如何用slider包对分组数据的不规则滚动窗口计算均值与标准差
月度分组动态窗口滚动统计解决方案
需求场景
按REGION和TYPE分组,以月度为周期,对每个月份计算**当前月+指定前序月份(示例为前1个月,实际需覆盖前120个月)**的滚动均值、标准差,同时统计窗口内的条目总数。由于每月条目数量不固定,滚动窗口需要支持动态调整。
踩过的坑
- 最初使用
zoo包的rollmean,无法实现可变滚动窗口的需求 - 改用
slider包的slide_period_dfr或slide_index_dbl时,遇到两个问题:- 能算出均值和标准差,但没法按
REGION+TYPE分组生成每月一条的结果,也没统计到窗口内的条目数 - 在
slide_period_dfr中使用summarise时,之前的分组规则直接被忽略
- 能算出均值和标准差,但没法按
解决思路(感谢@Jon-Spring的帮助)
通过三步组合操作解决问题:
- 用
add_count统计每个滚动窗口内的条目数量 - 用
slide_index_dbl计算滚动均值和标准差,支持动态时间窗口 - 用
slice去重,保证每个REGION+TYPE+月份只保留一条汇总结果
最终代码
library(tidyverse) library(slider) # 假设原始数据框为df,包含日期列date、数值列value、分组列REGION和TYPE final_result <- df %>% # 按REGION和TYPE分组处理 group_by(REGION, TYPE) %>% # 先把每组内的日期按升序排列 arrange(date, .by_group = TRUE) %>% # 给每条数据标记对应的月份(用于后续窗口定位) mutate(month = floor_date(date, "month")) %>% # 统计当前月及前120个月窗口内的条目总数 add_count( wt = between(date, month %m-% months(120), month), name = "window_entry_count" ) %>% # 计算滚动均值:窗口范围是当前月往前推120个月内的所有value mutate( rolling_avg = slide_index_dbl( .x = value, .i = date, .f = ~mean(.x, na.rm = TRUE), .before = months(120), .complete = FALSE # 允许窗口不满120个月的情况(比如起始月份) ), # 计算滚动标准差 rolling_std = slide_index_dbl( .x = value, .i = date, .f = ~sd(.x, na.rm = TRUE), .before = months(120), .complete = FALSE ) ) %>% # 每组每个月只保留最后一条汇总结果(确保每月一条) slice(n()) %>% ungroup() %>% # 筛选出需要的结果列 select(REGION, TYPE, month, window_entry_count, rolling_avg, rolling_std)
内容的提问来源于stack exchange,提问作者JR2019
相关产品推荐
相关产品推荐

