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

data.table v1.15.2按列子集行后调用shift()赋值报错问题

data.table版本间代码失效原因解析

在data.table v1.14.2里,你用data[to.keep == TRUE, (mycols) := shift(value, n = 1:3, type = 'lag'), by = Species]能顺利按筛选后的行分组生成滞后列,但到了v1.15.2就报「提供16个元素要分配给lag.1列的11个项」的错,核心原因是版本间分组计算的行匹配逻辑变了:

  • v1.14.2中,用i参数(也就是to.keep == TRUE)筛选行后,by分组是基于筛选后的子集来做的,shift只会计算每个组内筛选后的行,生成的结果长度和当前组的筛选后行数一致,赋值自然没问题。
  • v1.15.2里,by分组是基于整个原始数据集的分组,哪怕你用i筛了行,shift还是会对每个组的所有原始行计算滞后值,结果长度是该组的原始总行数,而你要赋值的只有筛选后的那部分行,两者长度不匹配就报错了。

举个实际场景:假设某个Species组原始有16行,其中11行符合to.keep == TRUE。旧版本里shift只处理这11行,出11个值;新版本处理全组16行,出16个值,要塞到11行的列里,自然就冲突了。

你说的在j里重复筛选的方法确实能解决,比如:

data[to.keep == TRUE, (mycols) := shift(value[to.keep == TRUE], n = 1:3, type = 'lag'), by = Species]

或者先把筛选后的数据集单独拎出来处理,再合并回去,逻辑更清晰:

filtered_dt <- data[to.keep == TRUE]
filtered_dt[, (mycols) := shift(value, n = 1:3, type = 'lag'), by = Species]
data[filtered_dt, on = .(Species, your_unique_id), (mycols) := mget(mycols)]

这个调整属于data.table内部逻辑的优化,没单独在shift的文档里提,而是包含在版本更新的整体行为变更里。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.28 09:52:45