如何调整R中zoo包rollapply()函数的width参数以适配不连续日期序列
解决思路
你遇到的核心矛盾是rollapply()默认按数据点数计算窗口,而你需要按实际日历日期跨度计算窗口,所以需要先把不规则的时间序列补成规则的逐日序列,再做滑动计算。
步骤1:补全逐日时间序列
因为你假设缺失日期的值均为1,所以首先需要用完整的日期范围生成所有日期,把缺失日期的value填充为1即可,这里可以用tidyr::complete()配合lubridate实现。
步骤2:用rollapply做按天滑动计算
补全后每个数据点对应1天,此时设置width=14就对应真实的14天时间跨度,计算窗口内的最小值如果为1,就说明整个窗口内所有值都是1。
完整可运行代码
# 加载需要的包 library(lubridate) library(dplyr) library(tidyr) library(zoo) # 测试数据 test_data <- data.frame( date = c("2000-01-01", "2000-01-02", "2000-01-03", "2000-01-17", "2000-01-18"), value = c(0, 1, 1, 1, 0) ) test_data$date <- ymd(test_data$date) # 第一步:补全为逐日序列,缺失值按规则填充为1 full_data <- test_data %>% # 生成从最小日期到最大日期的所有逐日日期 complete(date = seq(min(date), max(date), by = "day"), # 缺失的value填充为1,符合你的假设规则 fill = list(value = 1)) # 第二步:滑动窗口计算符合要求的时段 select_first_1_value <- full_data %>% mutate( # 左对齐窗口,计算14天窗口内的最小值,最小值为1说明全窗口值均为1 is_14days_1 = rollapply(value, width = 14, min, align = "left", fill = NA, na.rm = TRUE) ) %>% # 筛选符合连续14天为1的行 filter(is_14days_1 == 1) %>% # 取第一个符合条件的起始日期 slice(1) %>% select(date, value) print(select_first_1_value)
运行结果
输出的第一个符合条件的日期就是你期望的2000-01-02,完全匹配需求。
扩展说明
- 如果需要同时检测连续14天为0的情况,把窗口内计算函数
min改成max,筛选is_14days_0 == 0即可。 - 如果后续缺失值的填充规则不是默认1,可以调整
complete()里的fill参数,或者先做缺失值插值再计算。
内容的提问来源于stack exchange,提问作者Joshua Culpepper
相关产品推荐
相关产品推荐

