2016-06-29 35 views
0

Ich habe eine Tabelle mit Daten in Spalte 1 (Spalte mit dem Titel "Datum") und Werte in den Spalten 2 bis 5 (Spalten mit dem Titel "A" -> "D").R: Bedingtes Auffüllen einer Spalte in einer Tabelle basierend auf Eingabe aus anderen Spalten


Date A B C D 
1/1/16 12 75 38 88 
1/2/16 32 76 44 34 

usw.


I benötigen zusätzliche 6. Spalte E zu erzeugen, die enthält:

Für jede Reihe:

Wenn der Wert in Spalte A> B> C dann Wert in Spalte E = X

Wenn der Wert in Spalte A < B < C dann Wert in der Spalte E = Y

für etwas anderen Wert in der Spalte E = Z

Was ist der beste Weg, dies zu tun?

+0

Warum würden Sie Beispieldaten bereitstellen, die keine der Bedingungen erfüllen, die Sie besonders testen möchten? – thelatemail

+0

Sorry, ich wollte nur ein Beispiel für das Tabellenformat geben, die tatsächlichen Werte folgen nicht den Regeln, die ich erwähnt habe. Danke fürs Fangen! –

Antwort

1
# Here I'm simulating your original dataset  
df <- data.frame(Date=seq(Sys.Date(),Sys.Date()+9,by=1), A = seq(1,20,2), 
       B = rep(10,1,1), C=abs(rnorm(10)), D = rnorm(10)) 
# Create E 
df$E <- NA 
df$E[df$A > df$B & df$B > df$C] <- "X" 
df$E[df$A < df$B & df$B < df$C] <- "Y" 
df$E[is.na(df$E)]    <- "Z" 
df 



     Date A B   C    D E 
1 2016-06-29 1 10 0.5833273005 -0.25244803522 Z 
2 2016-06-30 3 10 0.4291374487 0.01669504752 Z 
3 2016-07-01 5 10 1.7079045597 1.28413741595 Z 
4 2016-07-02 7 10 0.2286708311 1.16421926818 Z 
5 2016-07-03 9 10 0.6216853471 1.08934300378 Z 
6 2016-07-04 11 10 1.4662821456 -0.58322427720 X 
7 2016-07-05 13 10 0.8255102263 0.65217873906 X 
8 2016-07-06 15 10 1.6185672627 0.04195996408 X 
9 2016-07-07 17 10 0.6752993011 -2.31746231694 X 
10 2016-07-08 19 10 0.2901133125 0.97969860678 X 

# Create E only for a subset of rows, like 6:10 
df$E <- NA 
df$E[1:5] <- "nothing applied to this row" 
df$E[df$A > df$B & df$B > df$C & 6:10] <- "X" 
df$E[df$A < df$B & df$B < df$C & 6:10] <- "Y" 
df$E[is.na(df$E) & 6:10]    <- "Z" 
df 

     Date A B   C    D       E 
1 2016-06-29 1 10 0.5833273005 -0.25244803522 nothing applied to this row 
2 2016-06-30 3 10 0.4291374487 0.01669504752 nothing applied to this row 
3 2016-07-01 5 10 1.7079045597 1.28413741595 nothing applied to this row 
4 2016-07-02 7 10 0.2286708311 1.16421926818 nothing applied to this row 
5 2016-07-03 9 10 0.6216853471 1.08934300378 nothing applied to this row 
6 2016-07-04 11 10 1.4662821456 -0.58322427720       X 
7 2016-07-05 13 10 0.8255102263 0.65217873906       X 
8 2016-07-06 15 10 1.6185672627 0.04195996408       X 
9 2016-07-07 17 10 0.6752993011 -2.31746231694       X 
10 2016-07-08 19 10 0.2901133125 0.97969860678       X 
+1

Danke! Ich habe das implementiert und es hat super funktioniert! Wie würde ich die Anzahl der Zeilen reduzieren, die ich sehen möchte, sagen wir, ich möchte das nur in den Zeilen 6 bis 10 tun. Nochmals vielen Dank! –

+0

@ user3481603 siehe meine aktualisierte Erklärung, aber mit dem Beispiel von Hack-R könnten Sie etwas tun wie 'df $ E [df $ A> df $ B & df $ B> df $ C & seq_along (df $ C)> = 6)] '' – dcc310

+0

@ user3481603 nach dem Einfügen ein wenig von der Hack-R's Antwort oben, hat die zweite Teilmenge B> C, wenn ich denke, Sie wollten C> B. Nur für den Fall, dass Sie zufällig kopieren Sie diese Paste in einigen medizinischen Gerätecode:) – dcc310

1

ich denke, das gut funktionieren sollte:

1 2 3 4
set.seed(1) 
myframe = data.frame(date=1:10, a=sample(1:10), b=sample(1:10),  c=sample(1:10), d=sample(1:10), e=NA) 
myframe[myframe$a > myframe$b & myframe$b > myframe$c, "e"] = "x" 
myframe[myframe$a < myframe$b & myframe$b < myframe$c, "e"] = "y" 
myframe[is.na(myframe$e), "e"] = "z" 
myframe 

Gibt

 
    date a b c d e 
1  1 3 3 10 5 z 
2  2 4 2 2 6 z 
3  3 5 6 6 4 z 
4  4 7 10 1 2 z 
5  5 2 5 9 10 y 
6  6 8 7 8 8 z 
7  7 9 8 7 9 x 
8  8 6 4 5 1 z 
9  9 10 1 3 7 z 
10 10 1 9 4 3 z 

wenn x <- 1:4 gibt dann ist x < - 1:4 < 3TRUE TRUE FALSE FALSE. So wählt someFrame[x, "someCol"] dieses col aus Zeilen aus, in denen x WAHR ist, d. H. Die erste und die zweite Zeile. Das gleiche gilt für Vektoren, also gibt c("a", "b", "c", "d")[x]a b zurück. Ich habe das "logische Indexierung" genannt, was es wert ist.

+0

Danke! Warum verwenden Sie den Befehl set.seed, wenn ich fragen darf? –

+0

Auch, was wäre der einfache Weg, um die Anzahl der Zeilen in der Tabelle zu reduzieren, lassen Sie uns sagen, ich wollte nur in Zeilen 6 bis 10 lopk. –

+0

@ user3481603, siehe meinen Kommentar zu Hack-Rs Antwort für die Begrenzung auf 6 und darüber. Die set.seed-Funktion soll Beispiele erstellen, die Zufälligkeit für andere nachvollziehbar machen, sonst würden Sie jedes Mal ein anderes "zufälliges" Ergebnis erhalten. – dcc310

Verwandte Themen