2015-07-07 3 views
7

Я попытался сделать несколько преобразований для тех же столбцов в data.table и нашел this answer. Однако, если я следую шагам, я получаю идентичные имена столбцов (вместо mean.Obs_1 и т. Д.).Как избежать одинаковых имен столбцов при нескольких преобразованиях в 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 

Есть ли способ избежать такого поведения и получить разные имена столбцов для разных преобразований? Я использую самую последнюю (1.9.4) стабильную версию data.table.

+1

Это будет лучше один раз [# 1063] (https: // GitHub .com/Rdatatable/data.table/issues/1063). – Arun

ответ

5

Вы можете попробовать

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

Это хороший. Никогда не видел этого раньше. –

+1

Спасибо, очень полезно! –

+0

@DavidArenburg Спасибо, просто попробовал некоторые комбинации и получил это правильно – akrun

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().)

+1

Обратите внимание, что при использовании одной функции. вы не можете получить «значение» в именах столбцов. то есть 'dt%>% group_by (ID)%>% summaryise_each (funs (mean))' и 'dt [, unlist (lapply (.SD, function (x) list (Mean = mean (x))), recursive = FALSE), by = ID] ' – akrun

+0

@akrun Это правильно. Но если вы используете только одну функцию, одно и то же имя столбцов является меньшей проблемой. – janosdivenyi

+0

Да, я понимаю, просто чтобы показать разницу в поведении – akrun