R语言:按日期分组的每日温度范围滚动平均值实现问题
解决方案:计算每日温度范围的跨日期滚动平均
问题分析
你当前的代码在group_by(date)后执行rollapply,会在每日分组内逐行计算滚动平均,但每个日期的range值是固定的,所以结果要么是NA,要么等于range本身,无法实现跨日期的滚动平均。由于每日观测行数不固定,无法通过行数量设置窗口,正确做法是先聚合每日温度范围,再计算跨日期滚动平均,最后合并回原始数据。
实现步骤
- 聚合每日温度范围:从原始数据中提取每日唯一的
date和range值; - 计算跨日期滚动平均:在聚合后的每日数据上,用
rollapply计算窗口为3的滚动平均; - 合并回原始数据:将滚动平均结果匹配到原始数据的对应日期。
完整代码
library(tidyverse) library(zoo) set.seed(3) # 生成示例数据 dts <- sort(sample(seq(as_datetime("2024-08-15 09:00:00 EDT"), as_datetime("2024-08-22 09:00:00 EDT"), by="hour"), 24)) df <- tibble(dts = dts, temp = sample(10:20, 24, replace=TRUE)) # 第一步:计算每日温度范围,并生成跨日期滚动平均 daily_range <- df %>% mutate(date = as.Date(dts)) %>% group_by(date) %>% summarize(range = max(temp, na.rm=TRUE) - min(temp, na.rm=TRUE)) %>% mutate(rollRange = rollapply(range, 3, mean, fill=NA, align="center")) # align控制窗口对齐方式,匹配示例desired列的中心对齐 # 第二步:合并回原始数据 df_final <- df %>% mutate(date = as.Date(dts)) %>% left_join(daily_range, by="date") # 查看结果 print(df_final)
关键说明
align="center":对应示例中desired列的窗口对齐逻辑(如2024-08-16的滚动平均为(2+8+2)/3=4),可根据需求调整为"left"或"right";- 该方法天然适配每日行数不固定的场景,聚合后的每日数据仅一行,滚动窗口直接对应日期数量,无需考虑原始数据行数;
- 使用
left_join可保留原始数据所有行,并匹配正确的滚动平均结果。
结果验证
运行代码后,rollRange列的值与你提供的desired列完全一致:
- 2024-08-16的
rollRange为4,对应(15日2 + 16日8 +17日2)/3; - 2024-08-17的
rollRange为5.33,对应(16日8 +17日2 +18日6)/3。
内容的提问来源于stack exchange,提问作者uhClem
相关产品推荐
相关产品推荐

