如何用tidy方法计算排除中心区间的滚动窗口标准差?
问题
我正在尝试计算覆盖[-10,10]区间但排除中心[-1,1]三天的滚动标准差,想了解是否有tidy解决方案。我已尝试使用slide_period_vec()函数,它能识别日期格式与间隔,且适用于非平衡面板(可避免填充80%的NA来平衡数据)。请问是否可以调整.before和.after参数,一次性获取[-10,-2]与[2,10]区间的数据进行计算?
附相关R代码示例:
set.seed(4711) daily_data <- data.frame(date = seq(as.Date("2022-01-01"), as.Date("2023-12-31"), by = "day"), value = rnorm(730, mean = 50, sd = 10)) daily_data <- daily_data %>% mutate(SD = slide_period_vec(daily_data$value, .i = daily_data$date, .period = "day", .f = sd, .before =10, .after = 10, .complete = F))
解决方案
slide_period_vec()的.before和.after只能定义连续的时间窗口,没法直接跳过中间[-1,1]这三天。不过你可以通过自定义计算函数来绕开这个限制:在计算标准差前,先把窗口内属于中心三天的数据过滤掉。
这里得换用slide_period()(而非slide_period_vec()),因为需要同时获取窗口内的日期和数值来做过滤,代码调整如下:
library(tidyverse) library(slider) set.seed(4711) daily_data <- data.frame(date = seq(as.Date("2022-01-01"), as.Date("2023-12-31"), by = "day"), value = rnorm(730, mean = 50, sd = 10)) daily_data <- daily_data %>% mutate(SD = slide_period( .x = across(c(date, value)), # 同时传递日期和数值列 .i = date, .period = "day", .f = function(window) { # 计算窗口内每个日期与当前行日期的差值 date_diff <- window$date - window$date[nrow(window)] # 筛选掉差值在[-1,1]范围内的数值 filtered_vals <- window$value[!date_diff %in% -1:1] # 至少2个数据点才计算标准差,否则返回NA if (length(filtered_vals) >= 2) sd(filtered_vals) else NA_real_ }, .before = 10, .after = 10, .complete = FALSE ) %>% unlist()) # 将列表结果转为向量列
关键细节
- 用
across(c(date, value))把日期和数值一起传入窗口函数,这样才能判断哪些数据属于要排除的区间 window$date[nrow(window)]取窗口的最后一行日期(也就是当前计算行的日期),计算差值后筛选出[-10,-2]和[2,10]的数值- 加了数据量判断,避免因过滤后数据不足导致
sd()报错
内容的提问来源于stack exchange,提问作者Lukas Mueller
相关产品推荐
相关产品推荐

