2016-08-08 7 views
0

Ich möchte die Ebenen einer Spalte in einem DF aufnehmen und jede Ebene als neue Spalte in einem neuen DF hinzufügen. Hier ist ein Spielzeug-Datensatz, der die Quell- und Idealziel-DFs zeigt.Größe einer Spalte (lang) in neue Spalten umwandeln (breit)

Quelle DF

person hour ride 
Bill  1  A 
Sue  2  B 
Bob  1  C 
Jill  3  B 
Dan  3  A 
Tina  3  A 

DF Mapped

hour A B C Saturation 
1  1 0 1  .66 
2  0 1 0  .33 
3  1 1 0  .66 

hier ein Testdatensatz ist:

test_data <- cbind.data.frame(person = c('Bill', 'Sue', 'Bob', 'Jill', 'Dan', 'Tina'), 
           hour = factor(c(1, 2, 1, 3, 3, 3)), 
           ride = c('A', 'B', 'C', 'B', 'A', 'A')) 

test_data$person <- as.character(test_data$person) 

Sehen Sie, wie jede Fahrt in Source verwandelt sich in eine neue Spalte in Mapped. Ich kann Ebenen erhalten und nutzen sie über

new_data <- cbind.data.frame(hour = levels(test_data$hour)) 

ein zugeordnetes DF zu schaffen, aber es schlägt fehl, wenn ich versuche, durch die Levels zu durchlaufen neue Spalten hinzuzufügen. Ich sehe die Ebenen.

unlist(lapply(levels(test_data$ride), function(x) paste(x))) 

ergibt

[1] "A" "B" "C" 

Wie in $ride durch die Levels gehen und eine Spalte in dem abgebildeten DF hinzufügen?

Bonus: Ich werde durch jede der Zeilen in test_data und ifelse() ein 1 in der Spalte ausführen, die zu dieser Fahrt entspricht es einem Fahrer hatte zu zeigen, und ein 0 sonst, aber jemand muss sehen, wie dies zu tun eleganter? So wie es aussieht, würde ich eine ifelse für jede Spalte benötigen, die aus den Ebenen in $ride extrahiert wird, von dem ich weiß, dass es ausführlicher als erforderlich sein muss.

+0

verwenden, das heißt g reat. Ich hatte keine Neufassung gesehen. Nichtsdestoweniger fand ich es auch nie auf der Suche nach Fragen, die Spalten hinzufügen, so dass die Frage vielleicht als ein Zeiger nützlich ist. –

+0

'pmin (mit (test_data, Tabelle (Stunde, Fahrt)), 1)' vielleicht? – thelatemail

+0

Warum benutzen Sie 'cbind.data.frame'? Verwenden Sie 'dat.frame', um Datenrahmen zu erstellen. –

Antwort

1
require(reshape2) 

mydat <- recast(test_data,hour~ride) 
mydat 
hour A B C 
1 1 1 0 1 
2 2 0 1 0 
3 3 2 1 0 
# 2nd part 
for(i in 2:ncol(mydat)){ 
    for(ii in 1:nrow(mydat)){ 
    if(mydat[ii,i] > 0) {mydat[ii,i] <- 1} 
    } 
} 
hour A B C 
1 1 1 0 1 
2 2 0 1 0 
3 3 1 1 0 
+0

Also die einzige Notwendigkeit jetzt ist, die vales auf A, B usw. von einem Bereich von 0..n zu 0,1 zu drehen, wo es 1 ist, wenn der Wert> 0 ist –

+0

@ShawnMehan OK Ich aktualisierte die Antwort mit dem –

+1

Danke für den Zeiger auf Neufassung, @ Hack-R. Ich könnte die for-Schleifen auch selbst schreiben, aber ich wollte eine Vektor-Lösung, da ich immer versuche, den (für mich) naheliegenden Ansatz zu vermeiden. 'ifelse' fällt zumindest in das, aber ich muss immer noch einen für jede Spalte schreiben, die aus' ride' kommt. –

0

Wir dcast von data.table

library(data.table) 
dcast(setDT(test_data), hour~ride, value.var="person", 
       function(x) as.integer(length(x) > 0))[, 
     Saturation := round(rowSums(.SD)/3,2), .SDcols = A:C][] 
# hour A B C Saturation 
#1: 1 1 0 1  0.67 
#2: 2 0 1 0  0.33 
#3: 3 2 1 0  1.00 
Verwandte Themen