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

在R中计算按小时分组、满足当日湿度范围的Reg变量5日滚动平均值

问题描述

这是我首次在Stackoverflow提问,若有疏漏或错误请见谅。

我拥有一份时间序列数据集,需按每日特定小时,计算二进制变量Reg的5日滚动平均值。可通过以下代码生成示例数据:

library(dplyr)
library(zoo)

set.seed(69)
df <- data.frame(Hour = rep(c(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24), times = 10),
                 Reg = rep(round(runif(24*10, 0, 1))),
                 HumidityLevel = rep(runif(24*10, 0, 100)))

df_ranges <- data.frame(LowerRange = rep(cbind(rollapply(df$HumidityLevel, 24, min, by = 24)), each = 24)
                        ,UpperRange = rep(cbind(rollapply(df$HumidityLevel, 24, max, by = 24)), each = 24))

df <- cbind(df, df_ranges)

我已通过以下代码计算出简单滚动平均值:

df <- df %>% 
  group_by(Hour) %>% 
  mutate(AvgReg = lag(rollapplyr(Reg, 5, mean, na.rm = T, partial = T), n = 1))

我需要实现的是:仅使用满足HumidityLevel处于当日对应范围(由LowerRange和UpperRange列确定,该范围为当日HumidityLevel的最值)的历史行,计算Reg的滚动平均值。

例如,某一天的湿度范围为20至54,则该天1小时的滚动平均值需使用之前所有1小时观测中HumidityLevel在20至54之间的Reg值计算。

期望输出如下:

desired_output <- data.frame(RowNum = c(1:10),
                  Hour = rep(1, times = 10),
                  Reg = c(1,0,0,1,0,1,0,0,0,0),
                  HumidityLevel = c(28.36, 65.02, 1.12, 49.61, 24.50, 98.16, 77.33, 97.03, 47.03, 85.71),
                  LowerBoundary = c(5.67, 7.50, 1.12, 19.32, 0.01, 6.94, 7.48, 0.71, 2.85, 1.59),
                  UpperBoundary = c(93.60, 89.37, 97.25, 99.63, 91.92, 98.16, 98.48, 99.98, 99.70, 98.86),
                  AvgReg = c("NA", 1, 0.5, 0.5, 0.5, 0.5, 0.6, 0.4, 0.4, 0.2))

解决方案

要实现按小时分组,仅筛选历史中湿度落在当日对应范围的记录来计算Reg的滚动平均值,可以结合dplyr的分组操作和自定义函数处理。核心逻辑是对每个小时组内的每一行,回溯所有历史行,筛选出符合湿度范围条件的Reg值后计算均值。

代码实现

library(dplyr)
library(zoo)

# 生成示例数据
set.seed(69)
df <- data.frame(Hour = rep(c(1:24), times = 10),
                 Reg = round(runif(24*10, 0, 1)),
                 HumidityLevel = runif(24*10, 0, 100))

df_ranges <- data.frame(LowerRange = rep(rollapply(df$HumidityLevel, 24, min, by = 24), each = 24),
                        UpperRange = rep(rollapply(df$HumidityLevel, 24, max, by = 24), each = 24))

df <- cbind(df, df_ranges)

# 自定义函数:计算当前行符合条件的滚动均值
calc_filtered_avg <- function(row_idx, group_data) {
  # 获取当前行的湿度范围
  current_lower <- group_data$LowerRange[row_idx]
  current_upper <- group_data$UpperRange[row_idx]
  # 提取同小时组内的历史行(当前行之前的记录)
  history_data <- group_data[1:(row_idx-1), ]
  # 筛选湿度在当前范围内的Reg值
  filtered_reg <- history_data$Reg[history_data$HumidityLevel >= current_lower & history_data$HumidityLevel <= current_upper]
  # 返回均值,无符合条件记录则返回NA
  if (length(filtered_reg) == 0) {
    return(NA)
  } else {
    return(mean(filtered_reg))
  }
}

# 按Hour分组计算符合要求的滚动平均值
df <- df %>%
  group_by(Hour) %>%
  mutate(AvgReg = sapply(1:n(), function(i) calc_filtered_avg(i, cur_data()))) %>%
  ungroup()

代码说明

  1. 自定义函数calc_filtered_avg:针对组内每一行,提取当前行的湿度范围,筛选同小时组内所有历史行中湿度符合该范围的Reg值,计算均值;若没有符合条件的历史记录,返回NA。
  2. 分组应用函数:通过sapply遍历每个小时组内的所有行,调用自定义函数计算对应的滚动平均值,最终生成符合要求的AvgReg列。

结果验证

可以筛选Hour == 1的记录,与你提供的desired_output对比,确认计算逻辑的正确性。


内容的提问来源于stack exchange,提问作者Hans Peter

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 14:40:33