2016-07-28 22 views
0

Ich habe einen Datenrahmen, die Skalierung mehr Spalten in einem Datenrahmen mit ddply in R

ID   Lot SubLot test1 test2 test3 
dffk  A  A1  6  10  10 
wdwd  A  A1  8  6  5 
ewew  A  A2  2  9  3 
llde  A  A2  2  10  6 
e3rw  B  B1  8  2  2 
qweo  B  B2  2  9  8 
cmve  B  B2  6  5  9 
owdf  B  B2  10  3  2 

Mein Ziel zu ersetzen, ist die „Test“ Spalten mit ihren standardisierten Werten wie

aussieht. Die Standardisierung muss während der Gruppierung durch Lot und Sublot Säulen erfolgen.
Ich dachte über die Verwendung ddply von plyr pckage. Ich kann es für eine einzelne Spalte tun mit:

new_data <- ddply(old_data, c("Lot","SubLot"), transform, test1 = scale(test1)) 

Wie sollte die Syntax aussehen, wenn ich auf einmal diese für alle „Test“ Spalten durchführen möchten?

Vielen Dank, David

+0

mit 'ddply', können Sie einfach die Skalierung von anderen Spalten auf den Befehl als zusätzliche Argumente hinzufügen (dh' ddply (old_data, c ("Lot", "SubLot"), transformieren, test1 = skalieren (test1), test2 = skalieren (test2), test3 = skalieren (test3)). "Die Lösung von @Sumedh ist jedoch allgemeiner , und ich glaube nicht, dass Sie das mit 'plyr' machen können. – aichao

+0

Danke, aber es wird nicht funktionieren, da ich Tausende von Spalten im Datensatz habe. @Sumedh Lösung führt zu einem Fehler, den ich unten erwähnte – buras12

Antwort

0

Wenn Sie zur Verwendung dplyr offen sind, schauen Sie in mutate_at:

library(dplyr) 

scale1 <- function(x) scale(x)[,1] 

old_data %>% group_by(Lot, SubLot) %>% 
    mutate_at(vars(contains("test")), scale1) 

#Source: local data frame [8 x 6] 
#Groups: Lot, SubLot [4] 

#  ID Lot SubLot  test1  test2  test3 
# <fctr> <fctr> <fctr>  <dbl>  <dbl>  <dbl> 
#1 dffk  A  A1 -0.7071068 0.7071068 0.7071068 
#2 wdwd  A  A1 0.7071068 -0.7071068 -0.7071068 
#3 ewew  A  A2  NaN -0.7071068 -0.7071068 
#4 llde  A  A2  NaN 0.7071068 0.7071068 
#5 e3rw  B  B1  NaN  NaN  NaN 
#6 qweo  B  B2 -1.0000000 1.0910895 0.4402255 
#7 cmve  B  B2 0.0000000 -0.2182179 0.7043607 
#8 owdf  B  B2 1.0000000 -0.8728716 -1.1445862 

Spaltennamen übereinstimmen, die mit dem Wort Test

old_data %>% group_by(Lot, SubLot) %>% 
    mutate_at(vars(matches("^test")), scale1) 
starten

Da du es erwähnst

cols <- grep("test", names(old_data), value = T) 
old_data[,cols] <- lapply(old_data[,cols], as.double) 

library(data.table) 
setDT(old_data)[, (cols) := lapply(.SD, scale1) , by = .(Lot, SubLot), .SDcols = cols] 
+0

Danke für Ihre Antwort Ich bin offen für die Verwendung eines Pakets. Versucht, Ihren Vorschlag zu verwenden, aber wenn ich versuche, dann neue Datenrahmen anzuzeigen, bekomme ich diesen Fehler: Fehler in FUN (X [[i]], ...): Dims [Produkt 2288] stimmen nicht mit der Länge des Objekts überein [4719] Mein Los # 1 enthält 2288 Zeilen. In diesem Fall bin ich nur Gruppierung nach Los, nicht nach Sublot – buras12

+0

Ja, das ist, was passiert, wenn ich View-Befehl ausführen – buras12

+0

Es ist das gleiche entweder mit einem neuen Datenrahmen oder die Neuzuordnung der Werte zu den alten. Der Code läuft ohne Fehler, diese erscheinen nur, wenn ich versuche, die Ausgabe – buras12

0

@Sumedh, nochmals vielen Dank für Ihre Hilfe: wäre effizienter ed Sie Tausende von Spalten haben, vielleicht data.table verwenden. Leider hat Ihr letzter Code auch nicht funktioniert. Ich habe mit Skala satt und bekam, um das Problem durch eine benutzerdefinierte Funktion definieren, ihn zu definieren:

my.scale = function(x,na.rm=TRUE) (x-mean(x,na.rm=TRUE))/sd(x,na.rm=TRUE) 

old_data <- old_data %>% group_by(Lot) %>% 
    mutate_each(funs(my.scale), contains("test")) 
+0

Das ist seltsam, weil es für mich arbeitete. Ich habe einen Datensatz mit 5000 Zeilen für 1 Gruppe und 500 Zeilen für 5 andere Gruppen simuliert. Wie auch immer, froh, dass du es herausgefunden hast. Eine Anmerkung jedoch: 'muate_each' und' summarise_each' werden in Zukunft veraltet sein. – Sumedh

+0

Danke, dass Sie mich wissen lassen – buras12