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

R中含缺失日期的时间序列滚动均值计算方案问询

解决分组滚动均值(基于天数,处理日期缺失)的最优方案

核心思路是先补全每个分组的连续日期序列,再计算滚动统计量,这样就能保证滚动窗口基于天数而非记录数,同时避免Group出现NA的问题。以下是具体步骤和代码示例:

步骤1:补全每个分组的完整日期序列

使用tidyr::complete(),按Group分组后生成该分组的连续日期区间,缺失的Value会自动填充为NA,这就解决了你之前全局join日历表导致Group为NA的问题。

步骤2:计算基于天数的滚动均值

可以用zoo::rollapply()或更贴合tidyverse的slider::slide_dbl(),两者都能处理窗口内的NA值。


完整代码示例

1. 模拟测试数据

library(tidyverse)
library(zoo)

# 生成带日期缺失的分组数据
set.seed(123)
df <- tibble(
  Date = seq.Date(as.Date("2024-01-01"), as.Date("2024-01-10"), by = "day") %>% 
    sample(15, replace = TRUE),
  Group = sample(c("A", "B", "C"), 15, replace = TRUE),
  Value = rnorm(15, 10, 2)
) %>% 
  distinct(Date, Group, .keep_all = TRUE) %>% # 确保每日每组仅一条记录
  arrange(Date, Group)

2. 补全分组的连续日期

df_complete <- df %>%
  group_by(Group) %>%
  # 补全当前分组的最小到最大日期的完整序列
  complete(Date = seq.Date(min(Date), max(Date), by = "day")) %>%
  ungroup()

3. 用zoo计算7天滚动均值

df_roll <- df_complete %>%
  group_by(Group) %>%
  mutate(
    # 窗口为7天(右对齐,包含当天及前6天),忽略NA值
    rolling_mean_7d = rollapply(
      Value,
      width = 7,
      FUN = mean,
      na.rm = TRUE,
      fill = NA, # 窗口不足7天时填充NA
      align = "right"
    )
  ) %>%
  ungroup()

4. (可选)用slider包更简洁实现

如果你偏好更tidyverse风格的语法,slider包的API更直观:

library(slider)

df_roll_slider <- df_complete %>%
  group_by(Group) %>%
  mutate(
    # .before = 6 表示包含当天及前6天,共7天
    rolling_mean_7d = slide_dbl(
      Value,
      ~mean(.x, na.rm = TRUE),
      .before = 6,
      .complete = FALSE # 窗口不完整时也计算均值,设为TRUE则仅返回完整窗口结果
    )
  ) %>%
  ungroup()

关键说明

  • 补全日期的正确姿势:必须按Group分组后补全日期,而非全局生成日历表再join,这样每个分组的日期序列是独立连续的,不会出现Group为NA的情况。
  • 基于天数的窗口:补全日期后,日期是连续的,所以滚动窗口的width参数直接对应天数(比如width=7就是7天窗口)。
  • NA值处理:通过na.rm=TRUE忽略窗口内的缺失值,确保滚动均值能正常计算;如果需要严格仅用完整窗口的数据,可设置.complete=TRUE(slider)或调整rollapply的参数。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 17:17:03