如何在R语言中实现下限为0的库存余额滚动结转(roll forward)计算
R语言库存滚动结转实现方案
实现逻辑说明
你需要的滚动结转属于分组依赖型逐行计算,核心规则为:
- 每一期期初余额 = 上一期期末余额
- 期末余额不得低于0,计算公式为:
EndBal = max(当期期初余额 + 当期采购量 - ifelse(当期期初+采购 > 0, 1, 0), 0) - 计算按ID分组独立进行
代码实现
方案1:tidyverse实现(dplyr + purrr,主流数据处理方案)
# 加载依赖包 library(dplyr) library(purrr) # 构造示例数据 df <- tibble( ID = rep("A", 5), BegBal = c(0, 2, 1, 0, 0), Purchased = c(3, 0, 0, 0, 2), Used = c(1, 1, 1, 0, 1) ) # 分组滚动计算期末余额 df_result <- df %>% group_by(ID) %>% mutate( Calculated_EndBal = accumulate( .x = Purchased, .f = \(prev_end, curr_pur) max(prev_end + curr_pur - ifelse(prev_end + curr_pur > 0, 1, 0), 0), .init = first(BegBal) # 取每组第一行的原始期初余额作为初始值 ) %>% tail(-1) # 剔除.init生成的额外首元素,匹配原数据行数 ) %>% ungroup()
运行后Calculated_EndBal列输出结果为2,1,0,0,1,和示例给出的EndBal完全一致。
方案2:基础R实现(无需额外安装依赖包)
# 按ID拆分数据 df_list <- split(df, df$ID) # 逐组循环计算 df_result <- do.call(rbind, lapply(df_list, function(sub_df) { n_row <- nrow(sub_df) sub_df$Calculated_EndBal <- numeric(n_row) current_bal <- sub_df$BegBal[1] for (i in 1:n_row) { current_bal <- max(current_bal + sub_df$Purchased[i] - ifelse(current_bal + sub_df$Purchased[i] > 0, 1, 0), 0) sub_df$Calculated_EndBal[i] <- current_bal } return(sub_df) })) rownames(df_result) <- NULL
扩展说明
如果实际业务中扣减数量不是固定1,而是每行Used列存储不同的扣减值,只需要把公式中的固定1替换为对应Used列的取值即可,滚动计算逻辑无需调整。
内容的提问来源于stack exchange,提问作者user17362367
相关产品推荐
相关产品推荐

