2015-07-07 4 views
7

Ich habe versucht, mehrere Transformationen für die gleichen Spalten in einem data.table und gefunden this answer. Wenn ich jedoch die Schritte dort befolge, bekomme ich identische Spaltennamen (anstelle von mean.Obs_1 usw.).Wie vermeiden Sie die gleichen Spaltennamen, wenn mehrere Transformationen in data.table?

library(data.table) 
set.seed(1) 
dt = data.table(ID=c(1:3), Obs_1=rnorm(9), Obs_2=rnorm(9), Obs_3=rnorm(9)) 

dt[, c(mean = lapply(.SD, mean), sd = lapply(.SD, sd)), by = ID] 
# ID  Obs_1  Obs_2  Obs_3  Obs_1  Obs_2  Obs_3 
#1: 1 0.4854187 -0.3238542 0.7410611 1.1108687 0.2885969 0.1067961 
#2: 2 0.4171586 -0.2397030 0.2041125 0.2875411 1.8732682 0.3438338 
#3: 3 -0.3601052 0.8195368 -0.4087233 0.8105370 0.3829833 1.4705692 

Gibt es eine Möglichkeit, dieses Verhalten zu vermeiden und verschiedene Spaltennamen für verschiedene Transformationen zu erhalten? Ich benutze die neueste (1.9.4) stabile Version von data.table.

+1

Dieses Mal besser sein wird [# 1063] (https: // Github .com/Rdatatable/data.table/issues/1063) implementiert. – Arun

Antwort

5

könnten Sie versuchen,

library(data.table) 
dt[, unlist(lapply(.SD, function(x) list(Mean=mean(x), 
        SD=sd(x))),recursive=FALSE), by=ID] 
# ID Obs_1.Mean Obs_1.SD Obs_2.Mean Obs_2.SD Obs_3.Mean Obs_3.SD 
#1: 1 0.4854187 1.1108687 -0.3238542 0.2885969 0.7410611 0.1067961 
#2: 2 0.4171586 0.2875411 -0.2397030 1.8732682 0.2041125 0.3438338 
#3: 3 -0.3601052 0.8105370 0.8195368 0.3829833 -0.4087233 1.4705692 

Oder eine Variation wie von @ David Arenburg vorgeschlagen

dt[, as.list(unlist(lapply(.SD, function(x) list(Mean=mean(x), 
       SD=sd(x))))), by=ID] 
# ID Obs_1.Mean Obs_1.SD Obs_2.Mean Obs_2.SD Obs_3.Mean Obs_3.SD 
#1: 1 0.4854187 1.1108687 -0.3238542 0.2885969 0.7410611 0.1067961 
#2: 2 0.4171586 0.2875411 -0.2397030 1.8732682 0.2041125 0.3438338 
#3: 3 -0.3601052 0.8105370 0.8195368 0.3829833 -0.4087233 1.4705692 
+1

Das ist ein netter. Nie zuvor gesehen. –

+1

Danke sehr nützlich! –

+0

@DavidArenburg Danke, habe gerade einige Kombinationen ausprobiert und es richtig gemacht – akrun

2

Wenn die Daten nicht so groß ist und der Fokus auf die Lesbarkeit, dplyr Verwendung auch sein könnte gute Idee.

library(dplyr) 
dt %>% group_by(ID) %>% summarise_each(funs(mean, sd)) 
# ID Obs_1_mean Obs_2_mean Obs_3_mean Obs_1_sd Obs_2_sd Obs_3_sd 
#1 1 0.4854187 -0.3238542 0.7410611 1.1108687 0.2885969 0.1067961 
#2 2 0.4171586 -0.2397030 0.2041125 0.2875411 1.8732682 0.3438338 
#3 3 -0.3601052 0.8195368 -0.4087233 0.8105370 0.3829833 1.4705692 

(Wie @akrun wies darauf hin, das wird nicht funktionieren, wenn Sie nur eine Funktion in funs() verwenden.)

+1

Beachten Sie, dass wenn Sie eine einzige Funktion verwenden. Sie können nicht das "Mittel" in den Spaltennamen erhalten. dh 'dt%>% group_by (ID)%>% summarise_each (Spaß (Mittelwert))' und 'dt [, unlist (lapply (.SD, Funktion (x) liste (Mittelwert = Mittelwert (x))), rekursiv = FALSE), by = ID] ' – akrun

+0

@akrun Das stimmt. Aber wenn Sie nur eine einzige Funktion verwenden, ist der gleiche Name der Spalten ein kleineres Problem. – janosdivenyi

+0

Ja, ich verstehe, nur um den Unterschied im Verhalten zu zeigen – akrun

Verwandte Themen