2013-04-18 59 views
6

我想使用ddply功能写入多个列相同的功能,但我试图继续写在一行,想看看有没有更好的方式做到这一点?plyr包写在多列相同的功能

这里的数据的简单版本:

data<-data.frame(TYPE=as.integer(runif(20,1,3)),A_MEAN_WEIGHT=runif(20,1,100),B_MEAN_WEIGHT=runif(20,1,10)) 

,我想这样做是为了找出列A_MEAN_WEIGHT和B_MEAN_WEIGHT的总和:

ddply(data,.(TYPE),summarise,MEAN_A=sum(A_MEAN_WEIGHT),MEAN_B=sum(B_MEAN_WEIGHT)) 

但在我目前的数据我有超过8个“* _MEAN_WEIGHT”,我厌倦了将它们写入8次像

ddply(data,.(TYPE),summarise,MEAN_A=sum(A_MEAN_WEIGHT),MEAN_B=sum(B_MEAN_WEIGHT),MEAN_C=sum(C_MEAN_WEIGHT),MEAN_D=sum(D_MEAN_WEIGHT),MEAN_E=sum(E_MEAN_WEIGHT),MEAN_F=sum(F_MEAN_WEIGHT),MEAN_G=sum(G_MEAN_WEIGHT),MEAN_H=sum(H_MEAN_WEIGHT)) 

是重新写一个更好的方法?感谢您的帮助!!

回答

6

plyr -centred方法是使用colwise

ddply(data, .(TYPE), colwise(sum)) 
    TYPE A_MEAN_WEIGHT B_MEAN_WEIGHT 
1 1  319.8977  60.80317 
2 2  621.6745  37.05863 

您可以通过列名作为参数.col,如果你只想要一个子集

您也可以使用numcolwisecatcolwise来对数字ric或分类专栏。

需要注意的是,你可以在地方使用sapply最基本的使用colwise

ddply(data, .(TYPE), sapply, FUN = 'mean') 

惯用data.table方法是使用lapply(.SD, fun)

dt <- data.table(data) 
dt[,lapply(.SD, sum) ,by = TYPE] 
    TYPE A_MEAN_WEIGHT B_MEAN_WEIGHT 
1: 2  621.6745  37.05863 
2: 1  319.8977  60.80317 
+0

Thanks @mnel! (数据,。(TYPE),colwise(sum,。(A_MEAN_WEIGHT)),colwise(sqrt,。(B_MEAN_WEIGHT))),所以如果我只写了一个问题,想要在多列上使用两种不同的功能,我需要将它们写两次? – linp

4

试试这个:

ddply(data, .(TYPE), colSums) 

这里是上面的(慢)等同,可以调整,以把任何函数,而不是总结的:

ddply(data, .(TYPE), function(x) {apply(x, 2, sum)}) 

如果你想保留.(TYPE)列,像这样会这样做:

ddply(data, .(TYPE), function(x) {apply(x[,names(x) != "TYPE"], 2, sum)}) 

更好的是,使用data.table,而不是plyr

library(data.table) 
dt = data.table(data) 

# just sums 
dt[, data.table(t(colSums(.SD))), by = TYPE] 

# sum for "A" and "B", and sqrt(sum) for "C" and "D" 
# note: you will have to call setnames() to fix the column names after 
dt[, data.table(t(colSums(.SD[, c("A_MEAN_WEIGHT", "B_MEAN_WEIGHT"), with = F])), 
       t(apply(.SD[, c("C_MEAN_WEIGHT", "D_MEAN_WEIGHT"), with = F], 
         2, function(x) sqrt(sum(x))))), 
    by = TYPE] 
+0

完美的作品!谢谢@eddi! – linp

+0

Emm ...后续问题,如果我有16列,我想为他们中的8个和其他8个人的sqrt(总和)做什么...... – linp

+0

你可以例如运行上述命令两次 - 每次函数执行一次,然后按需要的列进行过滤(例如,通过在'apply'或列中执行%c(“column_a”,“column_b”,...)中的'names(x)%'数字或任何适合您的数据),然后'cbind'结果 – eddi