dplyr:子分组(group_by)数据帧上的colSums:优雅

时间:2014-05-20 19:29:18

标签: r dplyr

我有一个非常大的数据框(265,874 x 30),有三个明智的组:年龄类别(1-6),日期(5479这样)和地理位置(总共4个)。每条记录包括每个记录中的一个选项,以及27个计数变量。我想按每个分组变量进行分组,然后对得到的子分组27变量进行colSums。我一直在尝试使用 dplyr (v0.2)来执行此操作,因为手动执行此操作最终会设置大量冗余内容(或者通过循环来迭代分组选项,缺乏优雅的解决方案)。

示例代码

countData <- sample(0:10, 2000, replace = TRUE)
dates <- sample(seq(as.Date("2010/1/1"), as.Date("2010/01/30"), "days"), 200, replace = TRUE)
locality <- sample(1:2, 2000, replace = TRUE)
ageCat <- sample(1:2, 2000, replace = TRUE)
sampleDF <- data.frame(dates, locality, ageCat, matrix(countData, nrow = 200, ncol = 10))

然后我想做的是......

library("dplyr")
sampleDF %.% group_by(locality, ageCat, dates) %.% do(colSums(.[, -(1:3)]))

但这并不是很有效,因为colSums()的结果不是数据帧。如果我投了它,它就可以了:

sampleDF %.% group_by(locality, ageCat, dates) %.% do(data.frame(matrix(colSums(.[, -(1:3)]), nrow = 1, ncol = 10)))

但是最后的do(...)位看起来非常笨重。

有关如何更优雅或更有效地做到这一点的任何想法?我想这个问题归结为:如何最好地使用do()函数和。运算符通过colSums汇总数据框。

注意:do(。)运算符仅适用于 dplyr 0.2,因此您需要从GitHub(link)中获取它,而不是从CRAN中获取它。

编辑:建议的结果

三种解决方案

  1. 我的帖子建议:已过去,146.765秒。

  2. @joran的建议如下:6.902秒

  3. @ eddi在评论中的建议,使用data.table:6.715秒。

  4. 我没有费心去复制,只是使用system.time()来获得粗略的衡量标准。从它的外观来看, dplyr data.table 在我的数据集上执行大致相同,并且两者都比我提出的黑客解决方案正确使用时快得多昨天。

2 个答案:

答案 0 :(得分:9)

除非我遗漏了某些内容,否则这似乎是summarise_each(来自 plyr colwise类似物)的工作:

sampleDF %.% group_by(locality, ageCat, dates) %.% summarise_each(funs(sum))

默认情况下,分组列不包含在汇总功能中,您只能选择列的子集以使用与使用select时相同的技术来应用这些功能。

summarise_each dplyr 的0.2版本中,但据我所知,不在0.1.3中。)

答案 1 :(得分:2)

这是@joran在2014年提出的一个很好的答案。

现在不建议使用此方法。相反,请使用summarize_all()summarize_at()