dplyr:子分组(group_by)数据帧上的colSums:优雅
Posted
技术标签:
【中文标题】dplyr:子分组(group_by)数据帧上的colSums:优雅【英文标题】:dplyr: colSums on sub-grouped (group_by) data frames: elegantly 【发布时间】:2014-07-09 05:16:12 【问题描述】:我有一个非常大的数据框 (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。
编辑:建议的结果
三种解决方案:
我在帖子中的建议:经过,146.765 秒。
@joran 的建议如下:6.902 秒
@eddi 在 cmets 中的建议,使用 data.table:6.715 秒。
我没有费心去复制,只是使用了 system.time() 来获得一个粗略的衡量标准。从外观上看,dplyr 和 data.table 在我的数据集上的性能大致相同,并且在正确使用时两者都比我想出的 hack 解决方案快得多昨天。
【问题讨论】:
您介意分享一个可以下载 dplyr 0.2 的链接吗?我会很感激,因为我没有在 GitHub 上找到下载(它可能会让其他社区成员更容易回答你的问题)。 @beginneR 如果您查看 github 页面上的自述文件,您将看到从 github 安装的命令。 (使用 devtools 包)。 @joran 太棒了,现在正在安装.. 感谢您的提示。 @beginneR 我对 OS X 的 magrittr 依赖有点麻烦,我必须从源代码安装它;由于某种原因,它正在寻找错误版本的二进制文件。 因为您的问题专门针对dplyr
,所以我将其作为评论 - 这里的语法不那么笨拙(并且可能更快):dt = as.data.table(sampleDF)
; dt[, lapply(.SD, sum), by = list(locality, ageCat, dates)]
【参考方案1】:
除非我遗漏了什么,否则这似乎是 summarise_each
的工作(类似于 plyr 的 colwise
类似物):
sampleDF %.% group_by(locality, ageCat, dates) %.% summarise_each(funs(sum))
默认情况下,汇总函数中不包含分组列,您可以只选择列的子集来应用函数,使用与使用select
时相同的技术。
(据我所知,summarise_each
在 dplyr 的 0.2 版中,但不在 0.1.3 版中。)
【讨论】:
我错过了 summarise_each:感谢您的建议!正如我对原始帖子的编辑所显示的那样,它比重复投射要快得多。【参考方案2】:2014 年的 joran's answer 中提到的方法 summarise_each
已被弃用。
请改用summarize_all()
或summarize_at()
。
【讨论】:
【参考方案3】:从 2018 年开始,Hack-R's answer 中提到的 summarize_all
和 summarize_at
方法已被取代。
请改用summarize()
/summarise()
和across()
。
【讨论】:
以上是关于dplyr:子分组(group_by)数据帧上的colSums:优雅的主要内容,如果未能解决你的问题,请参考以下文章
R语言使用dplyr包聚合(group_by)数据并过滤(fiter)之后再拆开聚合数据(ungroup取消组合)使用ggplot2可视化拆开分组后的线图(line plot)
R语言dplyr包使用arrange函数group_by函数mutate函数生成分组数据的排名(rank)实战(Rank Variable by Group):升序排名降序排名以及相同排名的处理
将 dplyr 函数 group_by() 与 cut() 一起使用
R语言dplyr包获取dataframe分组聚合汇总统计值实战(group_by() and summarize() ):均值中位数分位数IQRMADcountunique
R语言dplyr包使用group_by函数arrange函数和filter函数获取每个分组的第一个第N个最后一个记录实战