如何用R的slider包实现从最新数据倒推的非重叠周期计数?
解决从最新日期倒推的非重叠60天周期统计问题
问题根源
你用slide_period_dfr遇到的问题,本质是该函数默认从早到晚正向划分周期,而非从最新日期倒推;同时.complete参数的判断逻辑并非针对“连续60天完整窗口”,导致结果不符合预期。
方案1:用slider包的slide_index_dfr实现倒推完整周期
slide_index_dfr支持自定义滑动方向和窗口范围,完美适配倒推60天的需求。
步骤1:编写正确的统计函数
这个函数负责处理单个周期内的数据,输出周期起止日期、时长,以及颜色-物体组合的最少出现次数:
period_count <- function(data) { if (nrow(data) == 0) return(tibble()) # 按颜色-物体分组统计出现次数 group_counts <- data %>% count(sample_colors, sample_objects, name = "counts") # 生成周期统计结果 tibble( earliest_day = min(data$dates), latest_day = max(data$dates), day_span = latest_day - earliest_day, min_object_n = min(group_counts$counts) ) }
步骤2:执行倒推周期统计
通过设置.direction="backward"从最新日期开始滑动,.every=days(60)和.before=days(59)确保每个窗口是连续60天,.complete=TRUE只保留完整的60天窗口:
library(lubridate) library(slider) library(dplyr) # 加载示例数据(已排序) set.seed(1) dates <- ymd(parse_date("2023-12-31") - days(0:199)) colors <- c('red', 'blue') sample_colors <- sample(colors, 200, replace = TRUE) objects <- c('pen', 'marker', 'brush') sample_objects <- sample(objects, 200, replace = TRUE) test_df <- data.frame(dates, sample_colors, sample_objects) %>% arrange(dates) # 生成统计结果 result <- slide_index_dfr( .x = test_df, .i = test_df$dates, .f = period_count, .every = days(60), .before = days(59), .direction = "backward", .complete = TRUE ) # 查看结果 print(result)
结果说明
- 每个周期的
earliest_day与latest_day间隔恰好60天 - 仅保留了数据范围内的完整60天周期(自动丢弃不足60天的区间)
min_object_n为对应周期内所有颜色-物体组合出现次数的最小值
方案2:手动生成周期区间(无需slider)
如果不想依赖第三方包,可以手动生成倒推的60天区间,再匹配数据统计:
# 获取数据的起止日期 max_date <- max(test_df$dates) min_date <- min(test_df$dates) # 生成倒推的完整60天区间 periods <- tibble( latest_day = seq(max_date, min_date + days(59), by = "-60 days"), earliest_day = latest_day - days(59) ) %>% filter(earliest_day >= min_date) # 过滤不完整的区间 # 匹配数据并统计 result_manual <- test_df %>% left_join(periods, by = join_by(dates >= earliest_day, dates <= latest_day)) %>% drop_na(latest_day) %>% group_by(earliest_day, latest_day) %>% summarise( day_span = latest_day - earliest_day, min_object_n = { # 先分组计数,再取最小值 count(cur_data(), sample_colors, sample_objects) %>% pull(n) %>% min() }, .groups = "drop" ) print(result_manual)
内容的提问来源于stack exchange,提问作者potpie
相关产品推荐
相关产品推荐

