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

如何基于日期时间列计算24/48/72小时窗口的时间序列移动平均值

基于时间窗口的分组移动平均实现

你之前的判断完全正确:zoo::rollmean的k参数是固定观测行数窗口,不会识别实际时间跨度,遇到采样间隔不固定、时间序列有缺断的情况,计算结果就不符合时间窗口要求。

要实现按实际时间跨度计算滚动均值,最简便的方案是使用slider包,该包支持直接以时间列为索引指定窗口宽度,和dplyr工作流适配度很高,不需要转换为专门的时间序列对象。

完整实现代码

library(dplyr)
library(slider)
library(lubridate) # 用于提供days()时间函数,加载tidyverse会默认加载

result <- df %>%
  # 按分组对时间排序,避免顺序错乱导致计算错误
  group_by(name) %>%
  arrange(Date_Time_GMT_3, .by_group = TRUE) %>%
  mutate(
    # 24小时窗口:当前时间点向前追溯24小时(含当前点)
    mean_01da = slide_index_dbl(
      .x = value,
      .i = Date_Time_GMT_3,
      .f = ~ mean(.x, na.rm = TRUE),
      .before = days(1),
      .after = 0
    ),
    # 48小时窗口
    mean_02da = slide_index_dbl(
      .x = value,
      .i = Date_Time_GMT_3,
      .f = ~ mean(.x, na.rm = TRUE),
      .before = days(2),
      .after = 0
    ),
    # 72小时窗口
    mean_03da = slide_index_dbl(
      .x = value,
      .i = Date_Time_GMT_3,
      .f = ~ mean(.x, na.rm = TRUE),
      .before = days(3),
      .after = 0
    )
  ) %>%
  ungroup()

参数说明

  • 这里用的slide_index_dbl是slider包针对索引滑动计算的函数,返回数值型结果,直接匹配value列的数据类型
  • .before = days(n)指定窗口的左边界为当前观测时间向前推n个自然日长度(精确到秒,即24*n小时),.after = 0代表窗口右边界就是当前观测时间,不纳入未来数据;如果需要包含当前点之后的时间,调整.after的参数值即可
  • 代码里mean()加了na.rm = TRUE参数,会自动跳过窗口内的缺失值,如果你的数据没有缺失值可以删除该参数
  • 分组内按时间排序是必要前置步骤,即使原数据看起来已经按时间排列,也建议保留该步骤避免异常结果

效果说明

该计算逻辑不会受采样间隔不固定、时间序列缺断的影响:比如某条观测的时间是2021-07-09 10:45:00,它的24小时窗口就会自动纳入所有同name下、时间在2021-07-08 10:45:00到2021-07-09 10:45:00之间的记录计算均值,完全匹配你需要的时间跨度要求。

如果不想额外加载slider包,也可以用zoo的rollapply函数配合width参数指定基于时间的窗口宽度,但写法更繁琐,容易出错,优先推荐slider方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 14:24:23