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

使用data.table计算滚动均值未统计无值日期的问题与解决

问题:用data.table复现tidyverse的补全日期+滚动均值结果

背景

有两个按group分组的DataFrame,合并后需要完成两个操作:

  1. 补全所有group的缺失日期
  2. 按group计算90天滚动均值

tidyverse方法已得到预期结果,但原data.table实现存在偏差,需要修正并理解差异原因。

差异原因

  1. 日期补全范围不同
    • tidyverse用合并后数据的全局最小/最大日期生成序列,所有group都从全局最早日期开始补全
    • 原data.table代码按每组自身的最小/最大日期生成序列,导致每组起始日期不一致,且缺少全局更早的日期
  2. 滚动均值计算的数据源差异
    原data.table代码中,补全后的日期序列不包含全局最早到组内最早之间的日期(这些日期在tidyverse中被补为0),因此runner::mean_run计算时未将这些0值纳入,导致滚动均值结果偏高。

data.table解决方案

以下代码完全复现tidyverse的结果,包含全局日期补全和正确的滚动均值计算:

1. 加载依赖并生成示例数据

library(data.table)
library(runner)
library(lubridate)

set.seed(123) # 确保结果可复现
df1 <- data.frame(
  group = sample(c('g1', 'g2', 'g3', 'g4'), 365, replace = TRUE),
  date = sample(seq(as.Date('2023-01-01'), as.Date('2023-12-31'), by = "day"), 365),
  values = rnorm(365, 10, 1)
)

df2 <- data.frame(
  group = sample(c('g1', 'g2', 'g3', 'g4'), 365, replace = TRUE),
  date = sample(seq(as.Date('2023-01-01'), as.Date('2023-12-31'), by = "day"), 365),
  values = rnorm(365, 10, 1)
)

2. 合并数据并补全全局日期

# 合并两个DataFrame
dt <- rbindlist(list(df1, df2))

# 生成全局统一的日期序列(覆盖所有group的时间范围)
global_dates <- seq(min(dt$date), max(dt$date), by = "day")
# 生成所有group与全局日期的交叉表,确保每个group都有完整日期
full_idx <- dt[, .(date = global_dates), by = .(group = unique(dt$group))]

# 合并原数据与交叉表,补全缺失日期对应的values为NA
setkey(dt, group, date)
setkey(full_idx, group, date)
dt_full <- dt[full_idx]

3. 替换NA为0并计算滚动均值

# 按group处理:替换NA为0,计算90天滚动均值
dt_result <- dt_full[, 
  `:=`(
    values = fifelse(is.na(values), 0, as.numeric(values)),
    date = ymd(date),
    running_values = mean_run(x = values, k = 90, idx = date)
  ), 
  by = group
][order(group, date)]

结果验证

修正后的data.table结果与tidyverse完全一致:

  • 所有group从全局最早日期(2023-01-01)开始
  • 缺失日期的values被替换为0,且这些0值被纳入滚动均值计算(例如g1的2023-01-04的滚动均值为(0+0+0+9.412)/4=2.353)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 03:14:57