如何用单条dplyr语句高效计算各职业平均捐款额?
解惑:dplyr分组后
n()的作用及简化代码的正确性 问题背景
你需要按捐赠者职业分组计算平均捐款额,最初用两次分组统计(总额+次数)再合并计算的方式,过程繁琐;后来发现用单条dplyr语句就能得到正确结果,但对语句中n()的作用存疑:sum(contribution_receipt_amount)/n()里的n()是不是按职业分组后的捐款次数,而非总数据行数?
核心结论
是的,n()在这里返回的就是每个职业分组下的捐款次数(即该分组的行数),这也是简化代码能得到正确结果的原因。
具体解释
在dplyr的工作流中:
- 当你用
group_by(contributor_occupation)对数据按职业分组后,后续的summarise()操作会逐组执行 - 分组状态下的
n()函数,会自动统计当前分组内的观测数量(也就是该职业的捐款次数),而非整个数据集的总行数
拿你提供的数据示例举例:
CIRCUS ARTIST分组有2条捐款记录,n()返回2,sum(contribution_receipt_amount)返回100+27=127,计算得平均127/2=63.5,和手动计算结果一致NOT EMPLOYED分组有2条记录,n()返回2,sum是2.7+50=52.7,平均26.35,同样符合预期
代码对比与优化
- 你最初的繁琐代码,本质是把「分组求和」「分组计数」拆成两个步骤,合并后再计算平均,和简化代码的逻辑完全一致,只是简化代码把这三步合并到了同一个
summarise()中,利用分组后n()的特性直接完成计算 - 其实还能进一步简化:
dplyr提供了现成的mean()函数,直接用它计算分组平均更直观,效果和sum/n()完全相同:
avg_donation_occupation <- b %>% select(contributor_occupation, contribution_receipt_amount) %>% group_by(contributor_occupation) %>% summarize(avg_donation_by_occupation = mean(contribution_receipt_amount)) %>% arrange(desc(avg_donation_by_occupation))
内容的提问来源于stack exchange,提问作者cigarettes_after_text
相关产品推荐
相关产品推荐

