如何正确使用accumulate和cumsum实现数据投影计算
基于增长率的多列逐年递推投影计算方案
基于df2中列B的增长率,对df1每行的Z、W、V值进行逐年投影计算,规则为每年数值以上一年结果乘以(1+当年B值)递推。尝试过accumulate和cumsum函数未得到预期结果,计划结合cross_join和across完成全量计算,以下是正确实现方式。
相关数据结构
# df1:2020年初始值数据 df1 <- tibble( X = c("abc", "abc", "efg", "efg"), Y = c("ab", "cd", "ef", "gh"), year = 2020, Z = c(0.1, 0.2, 0.3, 0.4), W = c(0.7, 0.8, 0.9, 1), V = c(1.3, 1.4, 1.5, 1.6) ) # df2:2021-2025年增长率数据 df2 <- tibble( year = 2021:2025, B = c(0.05, 0.063, 0.049, 0.061, 0.057) )
尝试过的代码(未得到预期结果)
# 错误使用accumulate计算示例 df3 <- df2 %>% mutate(example2 = accumulate(B, ~ 0.1 * ( .x +1))) # 尝试结合cumsum,仍未解决问题 df3 <- df2 %>% mutate(example2 = cumsum(accumulate(B, ~ 0.1 * ( .x +1))))
预期的代码逻辑方向
计划通过cross_join关联初始数据与增长率数据,用across批量处理多列递推,大致逻辑如下:
df3 <- mutate(cross_join(df1[-3], df2), across(Z:V)*(H), H = NULL)
正确实现方案
步骤1:计算累积增长乘数
首先给df2添加累积增长乘数列,accumulate需用于递推计算乘积,初始值设为1(对应2020到2021的首次增长):
library(dplyr) library(purrr) df2_with_multiplier <- df2 %>% mutate( # 计算从2021年开始的累积乘数:2021年为1.05,2022年为1.05*1.063,以此类推 cum_multiplier = accumulate(1 + B, `*`, .init = 1) %>% tail(-1) )
步骤2:关联数据并计算投影值
用cross_join关联df1的初始数据(移除重复的year列)和带乘数的df2,再批量计算Z、W、V的逐年投影值,最后补充2020年的初始记录:
result_df <- cross_join(df1 %>% select(-year), df2_with_multiplier) %>% mutate( # 批量将初始值乘以对应年份的累积乘数 across(Z:V, ~ .x * cum_multiplier) ) %>% # 添加2020年的初始数据 bind_rows(df1 %>% mutate(cum_multiplier = 1)) %>% # 按分组和年份排序 arrange(X, Y, year)
结果验证
最终的result_df包含每个X-Y组合2020-2025年的完整数据,完全符合递推规则。例如X=abc、Y=ab的Z值:
- 2020: 0.1
- 2021: 0.1 * 1.05 = 0.105
- 2022: 0.105 * 1.063 ≈ 0.111615
- 后续年份以此递推
内容的提问来源于stack exchange,提问作者dmoyaec
相关产品推荐
相关产品推荐

