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
相关产品推荐
相关产品推荐

