如何使用ddply获取dataframe中类的加权平均值?

问题描述:

我是plyr的新手,想要在一个类中取值的加权平均值来重新构造多个变量的数据框。使用下面的代码,我知道如何为一个变量做到这一点,如X2:如何使用ddply获取dataframe中类的加权平均值?

set.seed(123) 
frame <- data.frame(class=sample(LETTERS[1:5], replace = TRUE), 
        x=rnorm(20), x2 = rnorm(20), weights=rnorm(20)) 
ddply(frame, .(class),function(x) data.frame(weighted.mean(x$x2, x$weights)))  

不过,我想代码来创建为x和X2新的数据帧(和变量在任何金额框架)。有人知道怎么做这个吗?谢谢

+0

(?你知道你必须ddply'的'输出分配到的东西,吧) – smci

你可能会在?summarise函数中找到你想要的。我可以summarise复制你的代码如下:

library(plyr) 
set.seed(123) 
frame <- data.frame(class=sample(LETTERS[1:5], replace = TRUE), x=rnorm(20), 
        x2 = rnorm(20), weights=rnorm(20)) 
ddply(frame, .(class), summarise, 
     x2 = weighted.mean(x2, weights)) 

要为x也这么做,只需添加该行被传递到summarise功能:

ddply(frame, .(class), summarise, 
     x = weighted.mean(x, weights), 
     x2 = weighted.mean(x2, weights)) 

编辑:如果您想要对许多列执行操作,请使用colwisenumcolwise而不是summarise,或使用melt编辑的数据帧与reshape2 pac kage,然后cast回到原来的形式。 Here's an example.


这将使:

wmean.vars <- c("x", "x2") 

ddply(frame, .(class), function(x) 
     colwise(weighted.mean, w = x$weights)(x[wmean.vars])) 

最后,如果你不喜欢指定wmean.vars,你也可以这样做:

ddply(frame, .(class), function(x) 
     numcolwise(weighted.mean, w = x$weights)(x[!colnames(x) %in% "weights"])) 

将计算weighted-每个数字字段的平均值,不包括权重本身。

+0

谢谢,这个作品。有没有办法做到这一点,所以你不必为每个新变量指定函数?我正在处理一个包含100个变量的数据集,所以这需要一段时间! –

+1

谢谢@flodel填写我非常简洁的解释。在下面的@thelatemail之后,可以使用'wmean.vars Frank

+0

嗯,感谢提到'numcolwise',我从来没有见过它。 – flodel

A data.table回答为乐趣,这也不需要单独指定所有变量。

library(data.table) 
frame <- as.data.table(frame) 
keynames <- setdiff(names(frame),c("class","weights")) 
frame[, lapply(.SD,weighted.mean,w=weights), by=class, .SDcols=keynames] 

结果:

class   x   x2 
1:  B 0.1390808 -1.7605032 
2:  D 1.3585759 -0.1493795 
3:  C -0.6502627 0.2530720 
4:  E 2.6657227 -3.7607866 
+0

+1。请注意''权重'上不需要'.SD'(理论上,''keynames'也应该有一个解决方法):'frame [,lapply(.SD [,keynames,with = FALSE],weighted.mean ,w =权重),by = class]'具有相同的结果。 – Frank

+0

@Frank - 谢谢你 - 我已经编辑了你的建议。 – thelatemail