如何在data.table中进行多次转换时避免使用相同的列名?

时间:2015-07-07 09:09:49

标签: r data.table

我尝试对data.table中的相同列进行多次转换,找到this answer。但是,如果我按照那里的步骤操作,我会得到相同的列名(而不是mean.Obs_1等)。

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

有没有办法避免这种行为并为不同的转换获取不同的列名? 我使用最新的(1.9.4)稳定版data.table

2 个答案:

答案 0 :(得分:6)

你可以尝试

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

或@David Arenburg建议的变体

 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 :(得分:2)

如果数据不是那么大并且重点是可读性,那么使用dplyr可能也是一个好主意。

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

(正如@akrun所指出的,如果你只使用funs()中的一个函数,这将不起作用。)