如何在R的data.table中按规则迭代调整Plan生成NewPlan
问题描述
现有如下data.table数据:
dt <- data.table( Date = c("20240701", "20240801", "20240901", "20241001"), Plan = c(85,17,50, 34), OpenPlan = c(85, 0,33, 0), ValuetoReduce = c(97,97,97,97) )
需要按照以下逻辑对Plan字段累计削减总数值97(即ValuetoReduce的固定值),生成NewPlan字段:
- 第1行:用OpenPlan的85削减Plan,NewPlan为0,已消耗85,剩余12可用于后续削减
- 第2行:OpenPlan为0,无法削减,NewPlan等于原Plan值
- 第3行:OpenPlan为33,但仅剩余12可削减,原Plan50减12得到NewPlan
- 后续行:无剩余削减量,NewPlan等于原Plan值
期望得到的结果如下:
dt_new <- data.table( Date = c("20240701", "20240801", "20240901", "20241001"), Plan = c(85,17,50, 34), OpenPlan = c(85, 0,33, 0), ValuetoReduce = c(97,97,97,97), NewPlan = c(0,17,38,34) )
实现方案
利用data.table的逐行计算特性,维护剩余削减量变量,逐行处理生成NewPlan:
library(data.table) # 初始化总剩余削减量(取第一行的ValuetoReduce,因所有行值一致) remaining_reduce <- dt$ValuetoReduce[1] dt[, NewPlan := { if (OpenPlan > 0 && remaining_reduce > 0) { # 计算当前可削减的最大量:不超过OpenPlan和剩余削减量 cut_amount <- min(OpenPlan, remaining_reduce) # 更新剩余削减量 remaining_reduce <<- remaining_reduce - cut_amount # 生成当前行的NewPlan Plan - cut_amount } else { # 无削减空间,直接返回原Plan值 Plan } }, by = 1:nrow(dt)]
代码说明
- 先提取总削减目标值赋值给
remaining_reduce - 通过
by = 1:nrow(dt)实现逐行遍历处理每一行数据 - 每行判断是否满足削减条件:OpenPlan大于0且还有剩余削减量
- 满足条件时,计算实际可削减的量,更新剩余削减量,再算出NewPlan
- 不满足条件时,NewPlan直接等于原Plan值
运行后dt会自动新增NewPlan字段,结果与期望一致。
内容的提问来源于stack exchange,提问作者Sven
相关产品推荐
相关产品推荐

