如何补充R语言data.table代码实现duration变量的Goal(b)要求?
嘿,我来帮你补上需求(b)的逻辑,让代码完全符合你的要求~
首先明确下要补的规则:只要上月的value是1,不管之前的连续计数是多少,当前行的duration都要设为0。现有代码已经搞定了需求(a),我们只需要在最后加几步就能实现需求(b)。
修改后的完整代码
library(data.table) # 你的示例数据 sample <- structure(list(group = c(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2), month = c(2, 4, 5, 6, 7, 10, 11, 12, 13, 14, 7, 10, 11, 12, 13, 14, 15), value= c(NA, 0, 1, 1, 0, 0, 0, 0, 0, 0, NA, 1, 1, 0, 0, 0, 1)), class = "data.frame", row.names = c(NA, -17L), codepage = 65001L) setDT(sample) sample[, month_consecutive := NA] sample[, value_stable_rows := unlist(lapply(sample[, rle(value), by = group]$length, seq))] sample[, month_consecutive := unlist(lapply(sample[, rle(diffinv(diff(month) != 1)), by = group]$lengths, seq))] sample[, value_stable_rows := shift(value_stable_rows, type = "lag"), by = group] sample[, month_consecutive := shift(month_consecutive, type = "lag"), by = group] sample[, duration := ifelse(value_stable_rows < month_consecutive , value_stable_rows, month_consecutive)] sample[, month_lag1 := shift(month, n = 1)] sample[, month_lag2 := shift(month, n = 2)] sample[, month_lag3 := shift(month, n = 3)] sample[!((month - month_lag1 == 1) & (month_lag1 - month_lag2 == 1) & (month_lag2 - month_lag3 == 1)), duration := NA] # 新增:实现需求(b)的核心逻辑 sample[, prev_value := shift(value, type = "lag"), by = group] # 按组取上月的value sample[prev_value == 1, duration := 0] # 上月value为1时,强制把duration设为0 # 输出最终结果(可以按需选择列) sample[, .(group, month, value, duration)]
逻辑说明
- 获取上月value:用
shift(value, type="lag")并按group分组,这样就能拿到每个组里当前行的上一行的value,存成prev_value列。 - 强制设置duration为0:直接筛选出
prev_value == 1的行,把这些行的duration改成0。这一步放在需求(a)的判断之后,确保即使之前已经算出了duration值,也会被这个规则覆盖,完全符合你的要求。
验证示例
拿你的测试数据来看:
- group=1中month=7的行(value=0),上月(month=6)的value是1,所以duration会被设为0;
- group=2中month=12的行(value=0),上月(month=11)的value是1,duration同样会被设为0;
- 那些满足需求(a)且上月value不是1的行,会保留原来计算的duration值,不会受影响。
这样就同时满足了需求(a)和(b)的所有要求啦~
内容的提问来源于stack exchange,提问作者user14250906
相关产品推荐
相关产品推荐

