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

使用dplyr与lag函数按分组逐行递推计算金额

用dplyr实现分组递推计算amt字段

原始数据

首先定义并查看原始数据:

df = data.frame(name=c(rep("Group1",5),rep("Group2",5)),
                mon=c(1,2,3,4,5,1,2,3,4,5),
                amt=c(10,NA,NA,NA,NA,15,NA,NA,NA,NA),
                inc=c(.1,.1,.2,.2,.3,.1,.1,.2,.2,.3))

df

输出:

name mon amt inc
1  Group1   1  10 0.1
2  Group1   2  NA 0.1
3  Group1   3  NA 0.2
4  Group1   4  NA 0.2
5  Group1   5  NA 0.3
6  Group2   1  15 0.1
7  Group2   2  NA 0.1
8  Group2   3  NA 0.2
9  Group2   4  NA 0.2
10 Group2   5  NA 0.3

需求说明

按name字段分组,每组首行amt有有效值,其余行为NA;需要递推计算后续行的amt,公式为:
后一行amt = 前一行amt(1+当前行inc)*
分组切换时重新开始计算。

dplyr解决方案

结合dplyr的分组功能和purrr的accumulate函数,可以优雅实现递推计算,替代循环写法:

library(dplyr)
library(purrr)

df_result <- df %>%
  group_by(name) %>%
  mutate(amt = accumulate(1 + inc, ~ .x * .y, .init = first(amt))[-1]) %>%
  ungroup()

df_result

代码解释

  • group_by(name):按分组字段name划分数据集,确保每组独立计算
  • accumulate(1 + inc, ~ .x * .y, .init = first(amt)):
    • 1 + inc将增长率转换为增长系数(比如0.1的增长率对应1.1的系数)
    • .x代表上一步的计算结果,.y代表当前行的增长系数,~ .x * .y定义每一步的计算逻辑
    • .init = first(amt)指定每组的初始值为该组第一个非NA的amt值
    • [-1]移除accumulate返回结果中的初始值,保证结果长度与原数据一致
  • ungroup():取消分组,将结果转换为普通数据框

计算结果

# A tibble: 10 × 4
   name    mon   amt   inc
   <chr> <dbl> <dbl> <dbl>
 1 Group1     1  10    0.1
 2 Group1     2  11    0.1
 3 Group1     3  13.2  0.2
 4 Group1     4  15.8  0.2
 5 Group1     5  20.6  0.3
 6 Group2     1  15    0.1
 7 Group2     2  16.5  0.1
 8 Group2     3  19.8  0.2
 9 Group2     4  23.8  0.2
10 Group2     5  30.9  0.3

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 11:01:32