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

How to avoid same column names when multiple transformations in 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.

你可以试试

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

如果数据不是那么大并且重点是可读性,使用 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() 中的一个函数,这将不起作用。)