You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于cross_join与增长率实现依赖历史值的DataFrame投影计算

递增长期投影计算解决方案

需求背景

此前使用不依赖历史计算值的投影代码:

mutate(cross_join(df1[-3], df2), across(D:F)*H, H = NULL)

现在需要实现基于前一次计算的D、E、F列值,乘以对应年份的增长率H,生成逐年递增长的投影,公式为:Xn*(1+Hm)(注:根据示例实际计算逻辑,实际应为Xn*Hm,其中m=n+1,Xn是D/E/F列的历史值,Hm是对应年份的H)。

示例输入数据

df1(初始值)

A   B   year    D   E   F
abc ab  2020    0   1   2
def cd  2020    3   4   0
ghi ef  2020    0   5   6
jkl gh  2020    7   8   0
mno ij  2020    0   9   10

df2(增长率)

year    H
2021    1.1
2022    1.2
2023    1.3
2024    1.4
2025    1.5

预期输出示例

abc ab的投影结果(df3)

A   B   year    D    E     F      H
abc ab  2020    0   1.00    2.00    1
abc ab  2021    0   1.10    2.20    1.1
abc ab  2022    0   1.32    2.64    1.2
abc ab  2023    0   1.72    3.43    1.3
abc ab  2024    0   2.40    4.80    1.4
abc ab  2025    0   3.60    7.21    1.5

def cd的投影结果(df4)

A    B  year    D      E      F   H
def cd  2020    3        4    0   1
def cd  2021    3.3    4.4  0   1.1
def cd  2022    4.0    5.3  0   1.2
def cd  2023    5.1    6.9  0   1.3
def cd  2024    7.2    9.6  0   1.4
def cd  2025    10.8    14.4    0   1.5

尝试过的失败方案

  1. 错误的cross_join+across写法:
mutate(cross_join(df1[-3], df2), across(D:F)[-1]*H, H = NULL)
  1. 结合lag/lead与across的写法(未成功)
  2. 用cumsum和accumulate实现单列递增的错误尝试:
    测试数据:
Time      H   example
2010  0.000 0.1000000
2011  0.063 0.1062585
2012  0.049 0.1114821
2013  0.061 0.1182550
2014  0.057 0.1250279
2015  0.028 0.1285086
2016  0.060 0.1361788
2017  0.058 0.1441024
2018 -0.049 0.1370985
2019  0.058 0.1449823
2020 -0.149 0.1233892
2021  0.159 0.1430246
2022  0.076 0.1538541
2023  0.168 0.1796427
2024  0.144 0.2054314
2025  0.126 0.2312200
2026  0.112 0.2570086
2027  0.100 0.2827973
2028  0.091 0.3085859
2029  0.084 0.3343745
2030  0.077 0.3601632

尝试代码1:

df2_1 <- df2 %>% mutate(example2 = cumsum(0.1 * (H+1)))

不符合预期的结果:

Time     H   example example2
2010 0.000 0.1000000   0.1000
2011 0.063 0.1062585   0.2063
2012 0.049 0.1114821   0.3112
2013 0.061 0.1182550   0.4173
2014 0.057 0.1250279   0.5230
2015 0.028 0.1285086   0.6258

尝试代码2:

df2_1 <- df2 %>% mutate(example2 = accumulate(H, ~ 0.1 * ( .x +1)))

不符合预期的结果:

Time     H   example example2
2010 0.000 0.1000000  0.00000
2011 0.063 0.1062585  0.10000
2012 0.049 0.1114821  0.11000
2013 0.061 0.1182550  0.11100
2014 0.057 0.1250279  0.11110
2015 0.028 0.1285086  0.11111

解决方案

结合分组、递推计算和结果展开,可实现需求,代码如下:

library(tidyverse)

# 补充初始年份的增长率(2020年无增长,H=1),并按年份排序
df2_full <- df2 %>%
  add_row(year = 2020, H = 1) %>%
  arrange(year)

# 按A、B分组,为每组生成逐年投影数据
result <- df1 %>%
  group_by(A, B) %>%
  mutate(
    projections = list(
      df2_full %>%
        mutate(
          # 用accumulate递推计算每列的增长值,初始值为当前组的初始D/E/F
          D = accumulate(H, ~ .x * .y, .init = first(D))[-1],
          E = accumulate(H, ~ .x * .y, .init = first(E))[-1],
          F = accumulate(H, ~ .x * .y, .init = first(F))[-1]
        )
    )
  ) %>%
  unnest(projections) %>%
  select(A, B, year, D, E, F, H) %>%
  # 可选:保留两位小数,匹配示例格式
  mutate(across(D:F, ~ round(.x, 2))) %>%
  ungroup()

代码说明

  1. 处理增长率数据:给df2添加2020年的H=1,确保从初始值开始递推计算。
  2. 分组递推:按A、B分组后,使用accumulate函数以每组初始的D/E/F为起点,逐年乘以对应年份的H值,生成递增长的结果。
  3. 展开结果:用unnest将每组的投影列表展开为多行,得到完整的逐年投影数据。

运行上述代码后,将得到与示例一致的结果,可直接整合到分组计算逻辑中。


内容的提问来源于stack exchange,提问作者dmoyaec

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 21:22:01