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

如何在R中基于ID和数据框计算多组指定时间窗口的移动平均值?

批量计算多组特定时间窗口的温度移动平均值解决方案

需求说明

为每个ID计算对应阶段日期前4天的温度平均值,要求时间窗口内必须包含完整的4天有效数据(无缺失、日期范围在温度数据的覆盖区间内),否则返回NA。例如ID A的阶段1结束日期为12,需计算9-12日的温度平均值;若结束日期超过温度数据的最大日期(12),或窗口起始日期小于1,均返回NA。

数据准备

ID阶段日期数据

IDDate <- data.frame(ID = c("A","B","C"), 
                     Stage1 = c(12, 13, 10), 
                     Stage2 = c(14, 30, 12))
ID阶段1阶段2
A1214
B1330
C1012

每日温度数据

IDTemp <- data.frame(Day = c(1:12), 
                     A = c(-3,-2,1,4,2,3,10,15,5,4,6,4), 
                     B = c(-4,2,0,3,12,10,9,8,9,3,1,2), 
                     C = c(4,1,2,5,5,2,3,2,1,5,6,1))
日期ABC
1-3-44
2-221
3102
4435
52125
63102
71093
81582
9591
10435
11616
12421

解决方案

使用dplyr和tidyr包进行数据整理与批量计算,步骤如下:

  1. 加载依赖包
library(dplyr)
library(tidyr)
  1. 转换温度数据为长格式(便于按ID和日期分组处理)
temp_long <- IDTemp %>%
  pivot_longer(cols = -Day, names_to = "ID", values_to = "Temperature")
  1. 转换ID阶段数据为长格式(将Stage1、Stage2转为行记录,并计算窗口起始日期)
stage_long <- IDDate %>%
  pivot_longer(cols = starts_with("Stage"), names_to = "Stage", values_to = "EndDay") %>%
  mutate(StartDay = EndDay - 3)  # 前4天的起始日期为结束日期减3
  1. 合并数据并计算符合要求的平均值
result <- stage_long %>%
  left_join(temp_long, by = "ID") %>%
  # 筛选当前阶段窗口内的日期
  filter(Day >= StartDay, Day <= EndDay) %>%
  # 按ID和阶段分组
  group_by(ID, Stage) %>%
  # 检查窗口内是否有完整4天数据且无缺失,是则计算平均值,否则返回NA
  summarise(Average_Temp = ifelse(n() == 4 & all(!is.na(Temperature)), mean(Temperature), NA), .groups = "drop") %>%
  # 转换回宽格式,匹配预期结果结构
  pivot_wider(names_from = Stage, values_from = Average_Temp, names_prefix = "阶段") %>%
  rename(
    "阶段1温度平均值" = "阶段Stage1",
    "阶段2温度平均值" = "阶段Stage2"
  )

结果验证

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

ID阶段1温度平均值阶段2温度平均值
A4.75NA
BNANA
C2.753.25

完全符合预期:

  • ID A的阶段2结束日期14超出温度数据的最大日期12,返回NA;
  • ID B的两个阶段结束日期均超出温度数据范围,均返回NA;
  • ID C的两个阶段窗口均包含完整4天有效数据,计算得到对应平均值。

内容的提问来源于stack exchange,提问作者Wayne Schmitt

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 20:22:02