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

R语言匹配两个数据框 按站点日期筛选±1小时内数据

R语言实现双表按站点日期匹配、时间差±1小时过滤记录

需求说明

需要对data2做行过滤,仅保留同时满足以下条件的记录:

  • 与data1的Site(站点)、Date(日期)字段取值完全匹配
  • 同站点同日期分组下,记录时间与data1中任意一条对应记录的时间差绝对值在1小时范围内
    已知data1行数多于data2,最终输出结构和示例给出的data_final一致。

注:示例给出的期望结果data_final中,EFG站点最后一条记录的Date值2022-01-05为笔误,实际匹配到的是2012-01-05的22:00记录,该记录与data1同组23:00的时间差刚好为1小时,符合保留规则。


实现方案

方案1:data.table 实现(推荐,大数据量性能最优)

适合数据量较大的场景,非等值连接效率远高于常规join后过滤的写法:

# 加载依赖包
library(data.table)

# 转换为data.table对象,拼接生成标准日期时间字段
setDT(data1)
setDT(data2)
data1[, datetime := as.POSIXct(paste(Date, Time), format = "%Y-%m-%d %H:%M")]
data2[, datetime := as.POSIXct(paste(Date, Time), format = "%Y-%m-%d %H:%M")]

# 非等值连接匹配时间窗口,去重得到最终结果
data_final <- data2[
  data1,
  on = .(Site, Date, datetime >= datetime - 3600, datetime <= datetime + 3600),
  .(Site, Date, Time = x.Time),
  nomatch = NULL
][!duplicated(.SD, by = c("Site", "Date", "Time"))]

# 可选:按站点、日期、时间排序
setorder(data_final, Site, Date, Time)

方案2:dplyr + lubridate 实现(适配tidyverse语法习惯)

如果平时更习惯用tidyverse系列的语法,可以用以下写法:

# 加载依赖包
library(dplyr)
library(lubridate)

# 拼接生成标准日期时间字段
data1 <- data1 %>%
  mutate(datetime = ymd_hm(paste(Date, Time)))
data2 <- data2 %>%
  mutate(datetime = ymd_hm(paste(Date, Time)))

# 连接后按时间差过滤,去重得到最终结果
data_final <- data2 %>%
  inner_join(data1, by = c("Site", "Date"), suffix = c("", "_ref")) %>%
  mutate(time_diff = abs(difftime(datetime, datetime_ref, units = "hours"))) %>%
  filter(time_diff <= 1) %>%
  select(Site, Date, Time) %>%
  distinct() %>%
  arrange(Site, Date, Time)

结果逻辑验证

运行代码后过滤逻辑和预期完全一致:

  • ABC站点2022-02-02的14:30记录,与同组data1最近的13:00记录时间差为1.5小时,被过滤
  • EFG站点2011-01-01的23:00记录,与同组data1最近的20:30记录时间差为2.5小时,被过滤
  • 其余记录均满足时间差要求,全部保留

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 15:18:15