如何在R中按客户分组,用上一单元格结果计算EAD列?
修正R中按分组递推计算EAD的代码
你的核心问题是accumulate的调用没有结合每个分组的初始Vol值,仅计算了BRD的累积乘积,导致结果不符合预期。以下是两种可行的修正方案:
方案一:使用accumulate结合初始值
library(dplyr) library(purrr) df <- data.frame(Cust = c(1,1,1,2,2,2), Rec_count = c(1,2,3,1,2,3), BRD = c(1,0.9,0.9, 1, 0.8, 0.8), T_y = c(2,2,2,1,1,1), Vol = c(100,100,100,80,80,80)) df1 <- df %>% group_by(Cust) %>% # 以分组的第一个Vol为初始值,对BRD做累积乘积,去掉多余的初始值 mutate(EAD = accumulate(BRD, ~ .x * .y, .init = first(Vol)) %>% tail(-1)) %>% ungroup() print(df1)
方案二:用case_when+fill递推填充
library(dplyr) library(tidyr) df <- data.frame(Cust = c(1,1,1,2,2,2), Rec_count = c(1,2,3,1,2,3), BRD = c(1,0.9,0.9, 1, 0.8, 0.8), T_y = c(2,2,2,1,1,1), Vol = c(100,100,100,80,80,80)) df1 <- df %>% group_by(Cust) %>% # 先给Rec_count=1的行赋值Vol,其余行定义递推规则 mutate(EAD = case_when( Rec_count == 1 ~ Vol, TRUE ~ lag(EAD) * BRD )) %>% # 向下填充递推计算缺失值 fill(EAD, .direction = "down") %>% ungroup() print(df1)
结果验证
两种方案都会得到符合预期的EAD列:
| Cust | Rec_count | BRD | T_y | Vol | EAD |
|---|---|---|---|---|---|
| 1 | 1 | 1.0 | 2 | 100 | 100.0 |
| 1 | 2 | 0.9 | 2 | 100 | 90.0 |
| 1 | 3 | 0.9 | 2 | 100 | 81.0 |
| 2 | 1 | 1.0 | 1 | 80 | 80.0 |
| 2 | 2 | 0.8 | 1 | 80 | 64.0 |
| 2 | 3 | 0.8 | 1 | 80 | 51.2 |
原代码问题说明
原代码中accumulate(BRD[1:n()], function(x, y) x * y)仅对BRD列做了累积乘积,没有将每个分组的初始Vol值作为计算起点,因此得到的是BRD的累积结果(如1、0.9、0.81),而非基于Vol的递推值。
内容的提问来源于stack exchange,提问作者Manfred
相关产品推荐
相关产品推荐

