如何在R中为按动物分组、单日期多测量值的数据集计算3天中心滚动平均值
在R中高效计算多测量值的奶牛甲烷3天中心滚动平均值
需求说明
现有奶牛甲烷测量数据集,结构如下:
- ID:奶牛标识符(整数类型)
- measure_date:测量日期(Date类型)
- ch4:甲烷测量值(数值类型)
需实现:
- 按奶牛ID分组,补全每个ID的所有连续日期(含无测量值的日期)
- 计算3天中心滚动平均值:以目标日期为中心,包含前一天、当天、后一天的所有测量值的算术平均
- 支持单日期多测量值的场景,且需高效处理大规模数据集
示例数据集
# 单个ID的示例数据(修正拼写错误并规范格式) df <- data.frame( ID = rep(1, 8), measure_date = as.Date(c("2023-01-01", "2023-01-01", "2023-01-01", "2023-01-01", "2023-01-02", "2023-01-03", "2023-01-03", "2023-01-05")), ch4 = c(200, 250, 233, 256, 270, 256, 290, 299) )
高效解决方案
方案1:使用tidyverse生态(易读性优先)
依赖dplyr、tidyr处理数据补全,slider包实现高效时间窗口计算:
library(dplyr) library(tidyr) library(slider) result_tidy <- df %>% group_by(ID) %>% # 生成当前ID的完整日期序列(从最早到最晚测量日) complete(measure_date = seq(min(measure_date), max(measure_date), by = "day")) %>% # 计算3天中心滚动平均:窗口覆盖前1天、当天、后1天的所有ch4值 mutate( ch4_3d_avg = slide_index_dbl( .x = ch4, .i = measure_date, .f = ~mean(.x, na.rm = TRUE), .before = 1, .after = 1 ) ) %>% ungroup()
方案2:使用data.table(性能优先,适合超大规模数据)
利用data.table的非等连接特性,实现高速窗口计算:
library(data.table) # 转换为data.table格式 setDT(df) # 生成每个ID的完整日期序列 full_dates <- df[, .(measure_date = seq(min(measure_date), max(measure_date), by = "day")), by = ID] # 左连接原数据,保留所有日期 result_dt <- full_dates[df, on = .(ID, measure_date), allow.cartesian = TRUE] # 通过非等连接计算3天窗口内的平均值 result_dt[, ch4_3d_avg := { # 匹配当前ID下,日期在[当前日-1, 当前日+1]范围内的所有ch4值求平均 df[.SD, on = .(ID, measure_date >= measure_date - 1, measure_date <= measure_date + 1), mean(ch4, na.rm = TRUE), by = .EACHI]$V1 }, by = .(ID, measure_date)]
结果说明
- 补全后的数据集包含每个奶牛的所有连续日期,无测量值的日期
ch4列显示为NA ch4_3d_avg列对应日期的3天窗口平均值:- 如2023-01-01的平均值为
(200+250+233+256+270)/5 = 241.8 - 2023-01-05的平均值为
299(仅当天有测量值)
- 如2023-01-01的平均值为
内容的提问来源于stack exchange,提问作者Methane123
相关产品推荐
相关产品推荐

