在R中按NOC、NAICS、Region分组计算三年周期求和
按分组计算三年周期Value求和的解决方案
问题描述
现有仅含年度数据的数据框,需按NOC、Region、NAICS列分组,计算组内三年周期的Value总和,最终仅在每组最早年份的行显示该总和,其余行显示NA。
原始数据框
| NOC | Region | NAICS | Date | Year | Value |
|---|---|---|---|---|---|
| 0000 | East | AA | 2010 | 12/31/2010 | 3 |
| 0000 | East | AA | 2011 | 12/31/2011 | 4 |
| 0000 | East | AA | 2012 | 12/31/2012 | 0 |
| 0000 | West | BB | 2010 | 12/31/2010 | 100 |
| 0000 | West | BB | 2011 | 12/31/2011 | 200 |
| 0000 | West | BB | 2012 | 12/31/2012 | 200 |
| 0000 | North | CC | 2010 | 12/31/2010 | -23 |
| 0000 | North | CC | 2011 | 12/31/2011 | 3 |
| 0000 | North | CC | 2011 | 12/31/2011 | 20 |
期望生成的新数据框
| NOC | Region | NAICS | Date | Year | Value | Sum |
|---|---|---|---|---|---|---|
| 0000 | East | AA | 2010 | 12/31/2010 | 3 | 7 |
| 0000 | East | AA | 2011 | 12/31/2011 | 4 | NA |
| 0000 | East | AA | 2012 | 12/31/2012 | 0 | NA |
| 0000 | West | BB | 2010 | 12/31/2010 | 100 | 500 |
| 0000 | West | BB | 2011 | 12/31/2011 | 200 | NA |
| 0000 | West | BB | 2012 | 12/31/2012 | 200 | NA |
| 0000 | North | CC | 2010 | 12/31/2010 | -23 | 0 |
| 0000 | North | CC | 2011 | 12/31/2011 | 3 | NA |
| 0000 | North | CC | 2011 | 12/31/2011 | 20 | NA |
尝试的R代码(无法正常运行)
df %>% group_by(NOC, Region, NAICS, Date) %>% mutate(max = rollapplyr(Value, 1:n() - findInterval(date - 5, Date), sum)) %>% slice_max(max) %>% ungroup %>%
可行解决方案
思路
- 按
NOC、Region、NAICS分组,计算每组的Value总和 - 标记每组中最早的年份(
Date最小的记录) - 仅在每组最早年份的行显示总和,其余行填充
NA
代码实现
library(dplyr) # 确保Date列为数值型,保证年份比较准确性 df$Date <- as.numeric(df$Date) result_df <- df %>% group_by(NOC, Region, NAICS) %>% mutate( total_sum = sum(Value, na.rm = TRUE), # 计算组内所有Value的总和 is_first_year = Date == min(Date) # 判断当前行是否为组内最早年份 ) %>% mutate( Sum = ifelse(is_first_year, total_sum, NA) # 仅最早年份行显示总和 ) %>% select(-total_sum, -is_first_year) %>% # 移除中间辅助列 ungroup() print(result_df)
代码说明
- 先转换
Date为数值型,避免字符型年份比较出错 - 分组计算组内总和,同时标记最早年份的记录
- 通过条件判断控制总和的显示位置,其余行设为
NA - 最后清理辅助列,得到符合需求的结果
内容的提问来源于stack exchange,提问作者user15032839
相关产品推荐
相关产品推荐

