【问题标题】:How to use ddply to get weighted-mean of class in dataframe?如何使用 ddply 获取数据框中类的加权平均值?
【发布时间】:2013-08-25 21:21:29
【问题描述】:

我是 plyr 的新手,想采用类中值的加权平均值来重塑多个变量的数据框。使用以下代码,我知道如何对一个变量执行此操作,例如 x2:

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(以及框架中的任意数量的变量)创建一个新的数据框。有人知道怎么做这个吗?谢谢

【问题讨论】:

  • (你知道你必须将ddply 的输出分配给某个东西,对吧?)

标签: r plyr reshape weighted-average summarization


【解决方案1】:

您可能会在?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,或者在melted 数据框上执行summarise使用reshape2 包,然后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"]))

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

【讨论】:

  • 谢谢,这行得通。有没有办法做到这一点,所以你不必为每个新变量指定函数?我正在处理一个包含 100 个变量的数据集,所以这需要一段时间!
  • 感谢@flodel 填写我非常简洁的解释。在下面的@thelatemail 之后,可以使用wmean.vars &lt;- setdiff(names(frame), c("class","weights")) 来避免指定xx2
  • 好吧,谢谢你提到numcolwise,我以前从未见过。
【解决方案2】:

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

【讨论】:

  • +1 表示data.table。注意.SDweights 上是不必要的(理论上keynames 也应该有一个解决方法):frame[,lapply(.SD[,keynames,with=FALSE],weighted.mean,w=weights),by=class] 具有相同的结果。
猜你喜欢
  • 1970-01-01
  • 2016-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-11-30
  • 2014-08-09
相关资源
最近更新 更多