2016-07-15 13 views
0

Ich fühle mich extrem dumm jetzt anwenden, aber ich kann nicht mit mehr als einem für Schleife kommen ...R: effiziente Art und Weise eine Funktion nach den Spalten einer Datenrahmen

ich einen Datenrahmen haben mit numerischen und faktoriellen Spalten. Ich möchte einfach, dass die numerischen Spalten skaliert werden und die faktoriellen Spalten so bleiben, wie sie sind. Zum Beispiel

> set.seed(160) 
> df1 <- data.frame(as.data.frame(matrix(rnorm(8), ncol=2)), 
        V3=factor(c("A", "A", "B", "B"))) 
> df1 
      V1   V2 V3 
1 0.6185496 -0.6410203 A 
2 -0.8722777 2.6520986 A 
3 0.8529240 -1.4156009 B 
4 0.3678875 -1.1615607 B 

Ich möchte

> df1 
      V1   V2 V3 
1 0.4901808 -0.2642698 A 
2 -1.4493527 1.4780179 A 
3 0.7950968 -0.6740765 B 
4 0.1640750 -0.5396717 B 

mit einem effizienteren Befehl bekommen, als

for(i in 1:ncol(df1)) { 
    if(is.factor(df1[,i])) {df1[,i] <- df1[,i]} 
    else{df1[,i] <- scale(df1[,i])} 
} 

ich verschiedene Kombinationen von lapply(), sapply(), if(), ifelse() versucht, aber nichts schien zu funktionieren (apply doesn‘ t arbeiten, weil das df in eine Matrix umgewandelt wird und ich die Faktor/numerische Struktur verliere). Irgendwelche Vorschläge?

NB: Ich versuche nicht, eine Funktion auf der Grundlage der Werte in die Spalten anzuwenden, sondern auf der Grundlage der Art von Spalte.

+2

'Index <- sapply (DF1, is.factor); df1 [index] <- scale (df1 [index]) ', aber es ist immer noch off-topic ;-) –

+0

Ops, ich dachte ich poste auf SE;) danke trotzdem! – jeiroje

Antwort

1

Sie können die folgenden versuchen, die auf einen Vorschlag in den Kommentaren ähnlich ist:

df1[sapply(df1, is.numeric)] <- scale(df1[sapply(df1, is.numeric)]) 
#> df1 
#   V1   V2 V3 
#1 0.4901808 -0.2642698 A 
#2 -1.4493527 1.4780179 A 
#3 0.7950968 -0.6740765 B 
#4 0.1640750 -0.5396717 B 
0

Dies sollte funktionieren.

df1[] <- sapply(df1, function(i) if(is.numeric(i)) scale(i) else i)