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

在data.table的lapply中组合rollapplyr与weighted.mean遇类型错误

问题原因分析

你猜的完全没错,这个错误确实和id=67只有1条数据直接相关。当分组的行数小于滚动窗口宽度(这里是3)时,rollapplyr返回的NA是逻辑类型(logical),而其他有足够数据的组返回的是数值类型(double)。data.table对列的类型一致性要求非常严格,不同组返回的同列类型必须完全统一,所以就抛出了类型不匹配的错误。

而你单独运行rollapplyr(ratio, ...)时没问题,是因为整个向量长度足够,即使前两个位置是NA,那也是数值型的NA,类型始终统一。但分组后单条数据的组,rollapplyr无法生成任何有效计算结果,返回的fill=NA会默认是逻辑型,这就和其他组的数值型结果产生了冲突。

解决方案

有两种简单的方法可以解决这个问题,核心都是保证所有组返回的结果类型统一为数值型:

方法1:强制转换结果为数值型

在rollapplyr的结果外层包一层as.numeric(),把逻辑型NA转成数值型NA,这样所有组的结果类型就完全一致了:

DT[, lapply(.SD, function(x) as.numeric(rollapplyr(x, width = 3, weighted.mean, w = c(0.2, 0.3, 0.5), align = 'right', fill = NA))), by = id, .SDcols = 'ratio']

方法2:先判断分组长度,针对性处理

可以先检查每组的行数,如果小于窗口宽度,直接返回对应长度的数值型NA;否则执行滚动计算,这种方式逻辑更清晰:

DT[, lapply(.SD, function(x) {
  if (length(x) < 3) {
    rep(NA_real_, length(x))  # 明确生成数值型NA
  } else {
    rollapplyr(x, width = 3, weighted.mean, w = c(0.2, 0.3, 0.5), align = 'right', fill = NA)
  }
}), by = id, .SDcols = 'ratio']
验证结果

运行上面任意一段代码,都会得到符合预期的结果:

  • id=67的组会返回1个数值型NA
  • id=39和id=58的组会正常生成滚动加权平均值

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.08 07:17:57