我尝试对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
。
答案 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()
中的一个函数,这将不起作用。)