2016-10-20 4 views
0

Ich versuche herauszufinden, wie man einige grundlegende Mathematik mit einem Datenrahmen zu tun.Berechnung der prozentualen Differenz von R Datenrahmen

Ich habe einen Datenrahmen, der wie folgt aussieht:

| Version | Total | Case | 
|---------|-------|--------| 
| 1.0.1 | 110 | Case 1 | 
| 1.0.2 | 111 | Case 1 | 
| 1.0.3 | 114 | Case 1 | 
| 1.0.4 | 114 | Case 1 | 
| 1.0.5 | 113 | Case 1 | 
| 1.0.1 | 53 | Case 2 | 
| 1.0.2 | 53 | Case 2 | 
| 1.0.3 | 56 | Case 2 | 
| 1.0.4 | 57 | Case 2 | 
| 1.0.5 | 55 | Case 2 | 
| 1.0.1 | 110 | Case 3 | 
| 1.0.2 | 111 | Case 3 | 
| 1.0.3 | 113 | Case 3 | 
| 1.0.4 | 114 | Case 3 | 
| 1.0.5 | 113 | Case 3 | 
| 1.0.1 | 52 | Case 4 | 
| 1.0.2 | 53 | Case 4 | 
| 1.0.3 | 56 | Case 4 | 
| 1.0.4 | 57 | Case 4 | 
| 1.0.5 | 55 | Case 4 | 

Ich mag die „Prozent anders“ zwischen ‚Fall 1 und 2‘ und dann auch ‚Fall 3 und 4‘ für jede Version berechnen. Also für 1.0.1 wäre es diese Mathematik tun: (110-53)/(.5*(110+53))

Letztlich wäre es mit einem Tisch am Ende, die wie folgt aussah:

| Version | Total | Case  | 
|---------|-------|------------| 
| 1.0.1 | 70% | Case 1 & 2 | 
| 1.0.2 | 71% | Case 1 & 2 | 
| 1.0.3 | 68% | Case 1 & 2 | 
| 1.0.4 | 67% | Case 1 & 2 | 
| 1.0.5 | 69% | Case 1 & 2 | 
| 1.0.1 | 72% | Case 3 & 4 | 
| 1.0.2 | 71% | Case 3 & 4 | 
| 1.0.3 | 67% | Case 3 & 4 | 
| 1.0.4 | 67% | Case 3 & 4 | 
| 1.0.5 | 69% | Case 3 & 4 | 

EDIT: Hier ist ein Arbeitsbeispiel der ersten Tabelle zu verwenden, .

Version <- c('1.0.1', '1.0.2', '1.0.3', '1.0.4', '1.0.5', '1.0.1', '1.0.2', '1.0.3', '1.0.4', '1.0.5', '1.0.1', '1.0.2', '1.0.3', '1.0.4', '1.0.5', '1.0.1', '1.0.2', '1.0.3', '1.0.4', '1.0.5') 
Total <- c(110, 111, 114, 114, 113, 53, 53, 56, 57, 55, 110, 111, 113, 114, 113, 52, 53, 56, 57, 55) 
Case <- c('Case 1', 'Case 1', 'Case 1', 'Case 1', 'Case 1', 'Case 2', 'Case 2', 'Case 2', 'Case 2', 'Case 2', 'Case 3', 'Case 3', 'Case 3', 'Case 3', 'Case 3', 'Case 4', 'Case 4', 'Case 4', 'Case 4', 'Case 4') 
df <- data.frame(Version, Total, Case) 
+0

Das könnte Sie ernsthaft helfen http://stackoverflow.com/questions/3505701/r-grouping-functions-sapply- vs-lapply-vs-apply-vs-tapply-vs-by-vs-aggrega. Die 'Apply'-Familie von Funktionen ist wesentlich, um R richtig zu verwenden. –

+0

Ich denke schmelzen und werfen wäre hilfreich. Ich fertige gerne eine Antwort an, aber bitte fügen Sie einige Beispieldaten in einer reproduzierbaren Weise hinzu, so dass Poster darauf zugreifen können (ohne die Textdaten manuell einzugeben). http://stackoverflow.com/questions/5963269/how-to-make-a-great-r-reproducible-example wird Ihnen helfen! – Joy

+0

@Joy Siehe meine Bearbeitung. – David

Antwort

3

können Sie library (data.table)

setDT(df) 
ans = df[, .(`case 1 & 2` = 200*(.SD[Case=="Case 1", Total] - .SD[Case=="Case 2", Total])/(.SD[Case=="Case 1", Total] + .SD[Case=="Case 2", Total]), 
      `case 3 & 4` = 200*(.SD[Case=="Case 3", Total] - .SD[Case=="Case 4", Total])/(.SD[Case=="Case 1", Total] + .SD[Case=="Case 2", Total]) 
     ), by=Version] 
# Version case 1 & 2 case 3 & 4 
# 1: 1.0.1 69.93865 71.16564 
# 2: 1.0.2 70.73171 70.73171 
# 3: 1.0.3 68.23529 67.05882 
# 4: 1.0.4 66.66667 66.66667 
# 5: 1.0.5 69.04762 69.04762 

verwenden Wenn Sie dies im langen Format benötigen Sie melt

melt(ans, id="Version") 
# Version variable value 
# 1: 1.0.1 case 1 & 2 69.93865 
# 2: 1.0.2 case 1 & 2 70.73171 
# 3: 1.0.3 case 1 & 2 68.23529 
# 4: 1.0.4 case 1 & 2 66.66667 
# 5: 1.0.5 case 1 & 2 69.04762 
# 6: 1.0.1 case 3 & 4 71.16564 
# 7: 1.0.2 case 3 & 4 70.73171 
# 8: 1.0.3 case 3 & 4 67.05882 
# 9: 1.0.4 case 3 & 4 66.66667 
#10: 1.0.5 case 3 & 4 69.04762 

Ein weiterer Ratschlag verwenden können: Ich würde empfehlen, keine Leerzeichen zu verwenden oder Sonderzeichen in Spaltennamen. Obwohl Sie hier durch Backticks um die Namen herumkommen können, kann es Probleme verursachen. Besser rufen Sie die Spalten so etwas wie case_a_b

+1

Die Logik, die für die Indexierung über mehrere Zeilen erforderlich ist, wird hier anschaulich dargestellt. –

+0

Mach dir keine Sorgen, diese Spalten sind nur Platzhalter, um es deutlicher zu machen, was dort vor sich geht. – David

2

Eine andere Lösung mit data.table mit dcast:

library(data.table) 
dt <- fread(" Version | Total | Case 
      1.0.1 | 110 | Case 1 
      1.0.2 | 111 | Case 1 
      1.0.3 | 114 | Case 1 
      1.0.4 | 114 | Case 1 
      1.0.5 | 113 | Case 1 
      1.0.1 | 53 | Case 2 
      1.0.2 | 53 | Case 2 
      1.0.3 | 56 | Case 2 
      1.0.4 | 57 | Case 2 
      1.0.5 | 55 | Case 2 
      1.0.1 | 110 | Case 3 
      1.0.2 | 111 | Case 3 
      1.0.3 | 113 | Case 3 
      1.0.4 | 114 | Case 3 
      1.0.5 | 113 | Case 3 
      1.0.1 | 52 | Case 4 
      1.0.2 | 53 | Case 4 
      1.0.3 | 56 | Case 4 
      1.0.4 | 57 | Case 4 
      1.0.5 | 55 | Case 4 ") 

dcast(dt, Version ~ Case, value.var = "Total")[, 
     .(Version, Case_1_2 = (`Case 1`-`Case 2`)/(.5*(`Case 1`+`Case 2`)), 
      Case_3_4 = (`Case 3`-`Case 4`)/(.5*(`Case 3`+`Case 4`)))] 

    Version Case_1_2 Case_3_4 
1: 1.0.1 0.6993865 0.7160494 
2: 1.0.2 0.7073171 0.7073171 
3: 1.0.3 0.6823529 0.6745562 
4: 1.0.4 0.6666667 0.6666667 
5: 1.0.5 0.6904762 0.6904762 
+0

Um die angeforderte Ausgabe zu bekommen, wäre es so etwas wie: 'paste0 (rund (100 * Case_1_2, 0),"% ")' oder vielleicht ein 'sprintf' Aufruf. –

Verwandte Themen