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

如何用dplyr的group_by()按n天分组计算样本n日平均值?

基于dplyr实现自定义n天间隔的平均值计算

问题描述

我曾用dplyr的group_by()函数计算样本结果的周、月、年度平均值,但在计算4日或10日这类自定义天数的平均值时遇到了难题。此外我的数据存在日期间隔问题,需要筛选出间隔在±n天内的数据计算平均值后再合并。

样本数据

data_test <- tibble('WBID' = c("10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A",
                               "11A", "11A", "11A", "11A", "11A", "11A", "11A", "11A", "11A", "11A", "11A", "11A",
                               "12A", "12A", "12A", "12A", "12A", "12A", "12A", "12A", "12A", "12A", "12A", "12A",
                               "10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A"),
              'Station' = c("A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A",
                           "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B",
                           "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D",
                           "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C"),
              'SampleDate' = c('2010-03-01','2010-03-02', '2010-03-03','2010-03-04','2010-03-05','2010-03-06','2011-03-01','2011-03-02','2011-03-03','2011-03-04','2011-03-05','2011-03-06',
                               '2010-03-01','2010-03-02', '2010-03-03','2010-03-04','2010-03-05','2010-03-06','2011-03-01','2011-03-02','2011-03-03','2011-03-04','2011-03-05','2011-03-06',
                               '2010-03-01','2010-03-02', '2010-03-03','2010-03-04','2010-03-05','2010-03-06','2011-03-01','2011-03-02','2011-03-03','2011-03-04','2011-03-05','2011-03-06',
                               '2010-03-01','2010-03-02', '2010-03-03','2010-03-04','2010-03-05','2010-03-06','2011-03-01','2011-03-02','2011-03-03','2011-03-04','2011-03-05','2011-03-06'),
              'Result' = c(7, 7, 2, 1, 5, 7, 7, 1, 5, 2, 4, 7, 
                           1, 7, 9, 3, 9, 4, 1, 9, 3, 6, 4, 3, 
                           8, 2, 9, 7, 3, 6, 1, 1, 1, 2, 6, 8,
                           4, 1, 7, 8, 1, 5, 3, 4, 6, 3, 2, 3))

原有周均值计算代码

# 按站点计算7天平均值
data_test <- data_test %>% 
  group_by(WBID, Station, Week = format(SampleDate, "%Y-%U")) %>% 
  mutate(Result_7day = mean(Result))

期望结果(n=4时)

data_test <- tibble('WBID' = c("10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A",
                               "11A", "11A", "11A", "11A", "11A", "11A", "11A", "11A", "11A", "11A", "11A", "11A",
                               "12A", "12A", "12A", "12A", "12A", "12A", "12A", "12A", "12A", "12A", "12A", "12A",
                               "10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A", "10A"),
                    'Station' = c("A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A", "A",
                                  "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B", "B",
                                  "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D", "D",
                                  "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C", "C"),
                    'SampleDate' = c('2010-03-01','2010-03-02', '2010-03-03','2010-03-04','2010-03-05','2010-03-06','2011-03-01','2011-03-02','2011-03-03','2011-03-04','2011-03-05','2011-03-06',
                                     '2010-03-01','2010-03-02', '2010-03-03','2010-03-04','2010-03-05','2010-03-06','2011-03-01','2011-03-02','2011-03-03','2011-03-04','2011-03-05','2011-03-06',
                                     '2010-03-01','2010-03-02', '2010-03-03','2010-03-04','2010-03-05','2010-03-06','2011-03-01','2011-03-02','2011-03-03','2011-03-04','2011-03-05','2011-03-06',
                                     '2010-03-01','2010-03-02', '2010-03-03','2010-03-04','2010-03-05','2010-03-06','2011-03-01','2011-03-02','2011-03-03','2011-03-04','2011-03-05','2011-03-06'),
                    'Result' = c(7, 7, 2, 1, 5, 7, 7, 1, 5, 2, 4, 7, 
                                 1, 7, 9, 3, 9, 4, 1, 9, 3, 6, 4, 3, 
                                 8, 2, 9, 7, 3, 6, 1, 1, 1, 2, 6, 8,
                                 4, 1, 7, 8, 1, 5, 3, 4, 6, 3, 2, 3),
                    'Result_4day' = c(4.25, 4.25, 4.25, 4.25, 3.75, 3.75, 3.75, 3.75, 3.75, 3.75, 3, 4.5,
                                      5, 5, 5, 5, 7, 6.25, 4.75, 4.75, 4.75, 4.75, 5.5, 4,
                                      6.5, 6.5, 6.5, 6.5, 5.25, 6.25, 1.25, 1.25, 1.25, 1.25, 2.5, 4.25,
                                      5, 5, 5, 5, 4.25, 5.25, 4, 4, 4, 4, 3.75, 3.5))

解决方案

方案1:基于固定n天块的分组(适合连续日期)

先将SampleDate转换为日期类型,再计算每个日期所属的n天分组块,最后用group_by分组计算平均值,完全贴合你期望的固定块分组逻辑:

library(dplyr)
library(lubridate)

# 转换日期格式为Date类型
data_test <- data_test %>% 
  mutate(SampleDate = ymd(SampleDate))

# 定义需要计算的天数n
n <- 4

# 按WBID、Station和n天块分组计算平均值
data_test <- data_test %>%
  group_by(WBID, Station, 
           # 生成n天分组键:以每个分组内的最早日期为起点,每n天划分为一个块
           n_day_block = floor_date(SampleDate - min(SampleDate, na.rm = TRUE), paste(n, "days")) + min(SampleDate, na.rm = TRUE)) %>%
  mutate(Result_nday = mean(Result)) %>%
  ungroup()

方案2:处理日期间隔的滑动窗口平均值(±n天范围)

如果数据存在日期间断,需要计算每个日期前后±n天内所有有效数据的平均值,可以用rowwise结合范围筛选实现:

n <- 4

data_test <- data_test %>%
  group_by(WBID, Station) %>%
  rowwise() %>%
  # 筛选当前日期前后n天内的所有Result值并计算平均
  mutate(Result_nday_slide = mean(Result[between(SampleDate, !!SampleDate - days(n), !!SampleDate + days(n))])) %>%
  ungroup()

结果验证

对于n=4的场景,方案1可以直接得到你提供的期望结果;如果数据存在日期间隔,方案2会自动忽略超出±4天范围的数据,只计算有效区间内的平均值,更适配你的补充需求。


内容的提问来源于stack exchange,提问作者nps-randy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 02:56:58