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

R语言:如何按对应日期对循环聚合小时级数据集?

问题描述

我有一份全年小时级数据集(共37个变量、8760行),已经用独立R脚本run_seq.R实现了单个日期范围的小时数据聚合,代码如下:

Date_From <- '2022-04-01'
Date_To <- '2022-04-02'
DF_hour <- (DfDHW %>% filter(as.Date(Hour) >= as.Date(Date_From) & as.Date(Hour) <= as.Date(Date_To)))
dummy <- as.numeric(DF_hour$Var*0+1)
dfdate <- aggregate(.~dummy, DFhour, sum)

这段代码可以正常运行,但我需要循环处理多组连续日期对。已经生成了日期起始序列dates_from、结束序列dates_to及序列号seq_num并组合成数据框:

dates_from <- seq(as.Date("2022-04-01"), as.Date("2022-04-10"), by=1)
dates_to <- seq(as.Date("2022-04-02"), as.Date("2022-04-11"), by=1)
seq_num <- as.numeric(format(dates_from, format = "%d"))
df <- cbind.data.frame(dates_from, dates_to, seq_num)

但当前的for循环会聚合所有10天的数据,无法匹配对应序列号的日期对(比如第1次循环用seq_num=1对应的日期对,第2次用seq_num=2对应的日期对)。请问怎么实现这个需求?有没有更优雅的实现方式?

数据集DfDHW的结构示例:

HourVar1Var2
2022-01-01 01:00:001.4801.480
2022-01-01 02:00:000.9570.957

dput(head(DfDHW))输出:

structure(list(Hour = structure(c(1640995200, 1640998800, 1641002400, 
1641006000, 1641009600, 1641013200), class = c("POSIXct", "POSIXt"
), tzone = "Europe/Stockholm"), Var1 = c(1.48022736417965, 
0.957129616195086, 0.67616277119973, 0.516807667014335, 0.500124643187317, 
0.596748739907164), Var2 = c(1.48022736417965, 0.957129616195086, 
0.67616277119973, 0.516807667014335, 0.500124643187317, 0.596748739907164
), Var3 = c(1.48022736417965, 0.957129616195086, ...

解决方案

方法1:修正for循环逻辑

你的问题核心是循环时没有正确提取每组对应的日期范围,直接遍历df的每一行即可解决:

# 初始化空列表存储结果
result_list <- list()

for (i in 1:nrow(df)) {
  # 取出当前行的日期对和序列号
  current_from <- df$dates_from[i]
  current_to <- df$dates_to[i]
  current_seq <- df$seq_num[i]
  
  # 过滤目标日期范围的数据
  DF_hour <- DfDHW %>% 
    filter(as.Date(Hour) >= current_from & as.Date(Hour) <= current_to)
  
  # 聚合数据(注意修正原代码的笔误:DFhour → DF_hour)
  dummy <- as.numeric(DF_hour$Var1 * 0 + 1) # 替换成你实际要用来生成dummy的变量
  dfdate <- aggregate(. ~ dummy, DF_hour, sum)
  
  # 添加上序列号,方便后续识别分组
  dfdate$seq_num <- current_seq
  
  # 将结果存入列表
  result_list[[i]] <- dfdate
}

# 合并所有结果为单个数据框
final_result <- do.call(rbind, result_list)

方法2:更优雅的函数式编程(dplyr + purrr)

用purrr的pmap可以直接对df的每一行应用聚合逻辑,代码更简洁,无需手动管理循环索引:

library(dplyr)
library(purrr)

# 定义日期范围聚合函数
aggregate_date_range <- function(from_date, to_date, seq_num) {
  DfDHW %>%
    filter(as.Date(Hour) >= from_date & as.Date(Hour) <= to_date) %>%
    mutate(dummy = 1) %>% # 直接生成dummy列,比Var*0+1更直观
    group_by(dummy) %>%
    summarise(across(everything(), sum, .names = "sum_{.col}"), .groups = "drop") %>%
    mutate(seq_num = seq_num) %>%
    select(-dummy) # 移除无用的dummy列
}

# 应用函数并直接合并结果
final_result <- df %>% pmap_dfr(aggregate_date_range)

方法3:data.table高效处理(适合大数据场景)

如果数据集规模较大,data.table的处理速度会显著快于常规方法:

library(data.table)

# 转换为data.table格式
setDT(DfDHW)

# 定义聚合函数
aggregate_dt <- function(from_date, to_date, seq_num) {
  DfDHW[as.Date(Hour) >= from_date & as.Date(Hour) <= to_date, 
        lapply(.SD, sum), .SDcols = patterns("Var")][, seq_num := seq_num]
}

# 应用函数并合并结果
final_result <- rbindlist(Map(aggregate_dt, df$dates_from, df$dates_to, df$seq_num))

关键注意点

  1. 原代码中的DFhour是拼写错误,需修正为DF_hour
  2. 生成dummy列时,直接用mutate(dummy = 1)比Var*0+1更直观高效
  3. 若要聚合所有数值变量,用across(everything(), sum)(dplyr)或lapply(.SD, sum)(data.table)无需逐个指定变量

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 21:01:05