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

如何用purrr按行处理df1,汇总df2并为df1添加汇总列?

问题

我有两个时间序列数据集,每个时间点都有测量值。df1每30分钟一个采样点,df2每5分钟一个采样点。我想关联这两个数据集,但需要先汇总df2,使其也变为每30分钟一个值。不过这些时间间隔并不总是固定的,我想到了当前的解决方案,但需要将该操作应用到df1的每一行。我认为可以用purrr函数按行映射自定义函数,但还没理清具体实现方式。


已完成的操作

0 - 加载包

library(lubridate)
library(tidyverse)
library(wakefield)
library(magrittr)

1 - 生成示例虚拟数据集

df1 <- data.frame(date_time = format(seq(as.POSIXct("2021-01-01 00:00:00", tz="GMT"), 
                                     as.POSIXct("2021-01-01 02:30:00", tz="GMT"), 
                                     by='30 min'), "%d-%m-%Y %H:%M:%S"), 
              other_vars = upper(6, k = 5, x = LETTERS, prob = NULL, name = "Upper"))


df2 <- data.frame(date_time = format(seq(as.POSIXct("2021-01-01 00:00:00", tz="GMT"), 
                                     as.POSIXct("2021-01-01 02:30:00", tz="GMT"), 
                                     by='5 min'), "%d-%m-%Y %H:%M:%S"),
              num_var1 = runif(31, 0, 255), 
              num_var2 = runif(31, 0, 255))

2 - 在df1中添加下一行的时间作为新列

df1 %<>% 
  mutate(date_time_lead = lead(date_time))

3 - 筛选df2中时间处于df1第1行时间区间内的行,并汇总数值(均值、标准差、求和)

df2_sub <- df2  %>% 
  filter(date_time >= df1$date_time[1] & date_time < df1$date_time_lead[1]) %>% 
  summarise(var1_mean = mean(num_var1, na.rm = T), 
            var1_sd = sd(num_var1, na.rm = T), 
            var1_sum = sum(num_var1, na.rm = T),
            var2_mean = mean(num_var2, na.rm = T), 
            var2_sd = sd(num_var2, na.rm = T), 
            var2_sum = sum(num_var2, na.rm = T))

4 - 在df1中生成新列

df1$var1_mean <- NA
df1$var1_sd <- NA
df1$var1_sum <- NA
df1$var2_mean <- NA
df1$var2_sd <- NA
df1$var2_sum <- NA

5 - 将新生成的汇总值添加到df1的第1行

df1[1, 4:9] <- df2_sub[1,]

解决方案

方法1:用purrr::pmap按行映射自定义函数

把筛选汇总逻辑封装成函数,再遍历df1每一行批量处理:

# 定义汇总函数,接收时间区间的起始和结束时间
summarize_df2 <- function(start_time, end_time) {
  df2 %>% 
    filter(date_time >= start_time & date_time < end_time) %>% 
    summarise(var1_mean = mean(num_var1, na.rm = TRUE), 
              var1_sd = sd(num_var1, na.rm = TRUE), 
              var1_sum = sum(num_var1, na.rm = TRUE),
              var2_mean = mean(num_var2, na.rm = TRUE), 
              var2_sd = sd(num_var2, na.rm = TRUE), 
              var2_sum = sum(num_var2, na.rm = TRUE))
}

# 处理df1最后一行的空值:用df2的最后一个时间作为区间终点
df1 <- df1 %>% 
  mutate(date_time_lead = ifelse(is.na(date_time_lead), max(df2$date_time), date_time_lead))

# 遍历df1每一行,生成所有区间的汇总结果
summary_results <- df1 %>% 
  select(date_time, date_time_lead) %>% 
  pmap_dfr(summarize_df2)

# 将汇总结果合并到df1中
df1 <- bind_cols(df1, summary_results)

方法2:高效模糊匹配(无需逐行循环)

如果只是偶尔存在时间间隔不固定的情况,用模糊匹配批量关联区间再汇总,效率更高:

library(fuzzyjoin)

# 先将字符格式的时间转回POSIXct类型,方便区间比较
df1 <- df1 %>% mutate(across(c(date_time, date_time_lead), as.POSIXct, tz="GMT"))
df2 <- df2 %>% mutate(date_time = as.POSIXct(date_time, tz="GMT"))

# 模糊匹配df2到df1的时间区间
joined_df <- fuzzy_left_join(
  df2, df1,
  by = c("date_time" = "date_time", "date_time" = "date_time_lead"),
  match_fun = list(`>=`, `<`)
)

# 按df1的分组汇总数据
summary_df <- joined_df %>% 
  group_by(date_time.y, other_vars, date_time_lead.y) %>% 
  summarise(var1_mean = mean(num_var1, na.rm = TRUE), 
            var1_sd = sd(num_var1, na.rm = TRUE), 
            var1_sum = sum(num_var1, na.rm = TRUE),
            var2_mean = mean(num_var2, na.rm = TRUE), 
            var2_sd = sd(num_var2, na.rm = TRUE), 
            var2_sum = sum(num_var2, na.rm = TRUE),
            .groups = "drop") %>% 
  rename(date_time = date_time.y, date_time_lead = date_time_lead.y)

内容的提问来源于stack exchange,提问作者Virginia Morera Pujol

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 08:45:46