我有一个包含 200 万行和 15 列的数据框。我想用 ddply 对这些列中的 3 个进行分组(所有 3 个都是因子,并且这些因子有 780,000 个唯一组合),并获得 3 个列的加权平均值(权重由我的数据集定义)。以下是相当快的:
system.time(a2 <- aggregate(cbind(col1,col2,col3) ~ fac1 + fac2 + fac3, data=aggdf, FUN=mean))
user system elapsed
91.358 4.747 115.727
问题是我想使用 weighted.mean 而不是 mean 来计算我的聚合列。
如果我在同一个数据帧上尝试以下 ddply(注意,我强制转换为不可变),则以下内容在 20 分钟后不会完成:
x <- ddply(idata.frame(aggdf),
c("fac1","fac2","fac3"),
summarise,
w=sum(w),
col1=weighted.mean(col1, w),
col2=weighted.mean(col2, w),
col3=weighted.mean(col3, w))
此操作似乎很占用 CPU,但不是很占用 RAM。
编辑:所以我最终编写了这个小函数,它通过利用加权平均值的一些属性来“欺骗”,并对整个对象而不是切片进行乘法和除法。
weighted_mean_cols <- function(df, bycols, aggcols, weightcol) {
df[,aggcols] <- df[,aggcols]*df[,weightcol]
df <- aggregate(df[,c(weightcol, aggcols)], by=as.list(df[,bycols]), sum)
df[,aggcols] <- df[,aggcols]/df[,weightcol]
df
}
当我运行时:
a2 <- weighted_mean_cols(aggdf, c("fac1","fac2","fac3"), c("col1","col2","col3"),"w")
我获得了良好的性能,以及一些可重用的优雅代码。