在R中当分组重复时如何按组计算累积和?
面板数据按ID和年份计算跨年度累积和(处理重复分组)
我有一个面板数据的dataframe,包含id和时间字段,想要为每个id和年份计算跨年度的累积和,但id与年份的分组存在重复行的情况。
示例数据
df <- data.frame(id = rep(12345,15), year = c(rep(2021,5), rep(2022,5), rep(2023,5)), value = c(rep(5,5), rep(3,5), rep(4,5))) df
输出:
id year value 1 12345 2021 5 2 12345 2021 5 3 12345 2021 5 4 12345 2021 5 5 12345 2021 5 6 12345 2022 3 7 12345 2022 3 8 12345 2022 3 9 12345 2022 3 10 12345 2022 3 11 12345 2023 4 12 12345 2023 4 13 12345 2023 4 14 12345 2023 4 15 12345 2023 4
当前问题
我原本用以下代码计算,但结果是每个年份内的行内累积,不符合跨年度累积的需求:
df %>% group_by(id, year) %>% mutate(value_cumsum = cumsum(value))
输出结果:
# A tibble: 15 × 4 # Groups: id, year [3] id year value value_cumsum <dbl> <dbl> <dbl> <dbl> 1 12345 2021 5 5 2 12345 2021 5 10 3 12345 2021 5 15 4 12345 2021 5 20 5 12345 2021 5 25 6 12345 2022 3 3 7 12345 2022 3 6 8 12345 2022 3 9 9 12345 2022 3 12 10 12345 2022 3 15 11 12345 2023 4 4 12 12345 2023 4 8 13 12345 2023 4 12 14 12345 2023 4 16 15 12345 2023 4 20
我需要的value_cumsum列结果是:5, 5, 5, 5, 5, 8, 8, 8, 8, 8, 12, 12, 12, 12, 12,即每个年份内的所有行都显示该年份及之前年份的总累积值。
解决方案
方法1:分步处理(清晰易懂)
先计算每个id+year分组的总价值,再按年份顺序计算跨年度累积和,最后匹配回原数据:
library(dplyr) df_result <- df %>% # 计算每个id+year的总value group_by(id, year) %>% summarise(year_total = sum(value), .groups = "drop") %>% # 按id分组,按年份排序后计算累积和 group_by(id) %>% arrange(year) %>% mutate(cum_total = cumsum(year_total)) %>% # 将累积和匹配回原数据 right_join(df, by = c("id", "year")) %>% # 重命名为目标列名 rename(value_cumsum = cum_total) %>% # 保留原数据列顺序 select(id, year, value, value_cumsum) df_result
输出:
id year value value_cumsum 1 12345 2021 5 5 2 12345 2021 5 5 3 12345 2021 5 5 4 12345 2021 5 5 5 12345 2021 5 5 6 12345 2022 3 8 7 12345 2022 3 8 8 12345 2022 3 8 9 12345 2022 3 8 10 12345 2022 3 8 11 12345 2023 4 12 12 12345 2023 4 12 13 12345 2023 4 12 14 12345 2023 4 12 15 12345 2023 4 12
方法2:简洁链式写法
利用first()提取每个年份分组的总价值,再计算累积:
df_result <- df %>% group_by(id, year) %>% mutate(year_total = sum(value)) %>% group_by(id) %>% arrange(year) %>% mutate(value_cumsum = cumsum(first(year_total))) %>% ungroup() %>% select(-year_total) df_result
内容的提问来源于stack exchange,提问作者Marco
相关产品推荐
相关产品推荐

