You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在R中计算DataFrame的月度扩展窗口最小值?

在R中实现按月份分组的扩展窗口统计

原始数据生成代码

date = c(seq(as.Date("2021/12/1"), by = "day", length.out = 6),
         seq(as.Date("2022/1/1"), by = "day", length.out = 6),
         seq(as.Date("2022/2/1"), by = "day", length.out = 6),
         seq(as.Date("2022/3/1"), by = "day", length.out = 6))
y = c(seq(1:6),seq(10,60,by=10),seq(0.1,0.6,by=0.1),seq(0.01,0.06,by=0.01))
df = tibble(date,y)

需求说明

需要按年月对数据分组,采用扩展窗口(expanding window)计算统计值:

  • 每个月份的统计需包含当前月及之前所有历史数据
  • 输出结果需包含:年份、月份、累计观测数、累计最小值

解决方案

方法一:使用dplyr + purrr

利用分组汇总结合累计计算实现,无需额外依赖滑块工具包:

library(dplyr)
library(lubridate)
library(purrr)

result <- df %>%
  # 从日期中提取年、月信息
  mutate(year = year(date),
         month = month(date)) %>%
  # 按年月分组,将当月所有y值存入列表
  group_by(year, month) %>%
  summarise(month_ys = list(y), .groups = "drop") %>%
  # 确保数据按时间顺序排列
  arrange(year, month) %>%
  # 计算累计观测数和扩展窗口最小值
  mutate(obs = cumsum(sapply(month_ys, length)),
         minimum = accumulate(month_ys, ~min(.x, .y))) %>%
  # 移除临时辅助列
  select(-month_ys)

print(result)

方法二:使用slider工具包

通过专门的滑动窗口函数实现,逻辑更直观:

library(dplyr)
library(lubridate)
library(slider)

result <- df %>%
  # 将日期转换为当月起始日期,作为分组索引
  mutate(year_month = floor_date(date, "month")) %>%
  # 确保数据按日期升序排列
  arrange(date) %>%
  # 按年月索引创建扩展窗口,计算每个窗口的统计值
  slide_index_dfr(
    .x = .,
    .i = year_month,
    .f = function(window_data) {
      tibble(
        year = year(window_data$year_month[[1]]),
        month = month(window_data$year_month[[1]]),
        obs = nrow(window_data),
        minimum = min(window_data$y)
      )
    },
    .before = Inf  # 设置扩展窗口,包含所有历史数据
  ) %>%
  # 去重,保留每个年月的唯一结果
  distinct(year, month, .keep_all = TRUE)

print(result)

输出结果

运行上述代码后,将得到如下结果:

yearmonthobsminimum
20211261
20221121
20222180.1
20223240.01

内容的提问来源于stack exchange,提问作者Homer Jay Simpson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 07:15:44