求助:如何按公司分组计算月度累计求和(附数据示例)
解决分组月度累计求和异常的问题
问题原因
直接在原始数据的每行上使用cumsum()会因为同一月度有多条重复记录,导致累计值被重复累加,最终结果不符合预期。正确的做法是先聚合到公司-年份-月度级别计算汇总值,再生成累计求和,最后关联回原始数据。
解决方案代码(基于dplyr)
library(dplyr) # 构造示例原始数据 df <- tibble( person_id = 1:16, company = c(rep("A", 6), rep("B", 10)), yyyy = 2011, month = c(rep("January", 2), rep("Feburary", 3), "March", rep("January", 3), rep("Feburary", 4), rep("March", 2), "April") ) # 1. 生成月度汇总及累计求和表 monthly_agg <- df %>% group_by(company, yyyy, month) %>% summarise(monthly_sum = n(), .groups = "drop_last") %>% # 将月份转为有序因子,确保按时间顺序排序(避免字符串排序错误) mutate(month = factor(month, levels = c("January", "Feburary", "March", "April"), ordered = TRUE)) %>% arrange(company, yyyy, month) %>% mutate(cumulative_monthly_sum = cumsum(monthly_sum)) %>% ungroup() # 2. 关联回原始数据,得到最终结果 final_result <- df %>% left_join(monthly_agg, by = c("company", "yyyy", "month")) # 查看输出 print(final_result)
代码说明
- 聚合月度计数:通过
group_by(company, yyyy, month)分组,用n()统计每个月度的人员数量; - 月份排序处理:将
month转为有序因子,保证按实际时间顺序(1-4月)排序,避免字符串默认排序导致的累计顺序错误; - 计算累计求和:在有序的月度汇总表上使用
cumsum(),得到每个公司的月度累计值; - 关联原始数据:用
left_join将汇总字段合并回原始数据,确保每条人员记录都对应正确的月度计数和累计值。
输出结果
运行代码后将得到与期望完全一致的数据框:
| person_id | company | yyyy | month | monthly_sum | cumulative_monthly_sum |
|---|---|---|---|---|---|
| 1 | A | 2011 | January | 2 | 2 |
| 2 | A | 2011 | January | 2 | 2 |
| 3 | A | 2011 | Feburary | 3 | 5 |
| 4 | A | 2011 | Feburary | 3 | 5 |
| 5 | A | 2011 | Feburary | 3 | 5 |
| 6 | A | 2011 | March | 1 | 6 |
| 7 | B | 2011 | January | 3 | 3 |
| 8 | B | 2011 | January | 3 | 3 |
| 9 | B | 2011 | January | 3 | 3 |
| 10 | B | 2011 | Feburary | 4 | 7 |
| 11 | B | 2011 | Feburary | 4 | 7 |
| 12 | B | 2011 | Feburary | 4 | 7 |
| 13 | B | 2011 | Feburary | 4 | 7 |
| 14 | B | 2011 | March | 2 | 9 |
| 15 | B | 2011 | March | 2 | 9 |
| 16 | B | 2011 | April | 1 | 10 |
内容的提问来源于stack exchange,提问作者yzhao
相关产品推荐
相关产品推荐

