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

Base R或dplyr如何实现ID匹配+日期区间匹配的merge合并?

R实现按id匹配+日期间隔条件的连接方法

前提说明

你有如下两个因子类型日期的数据表:

table_1 = data.frame(id = c("123", "123", "125", "125"), 
date_1 = c("2010-01-31","2010-01-31", "2015-01-31", "2018-01-31" ))
table_1$id = as.factor(table_1$id)
table_1$date_1 = as.factor(table_1$date_1)

table_2 = data.frame(id = c("123", "121", "125", "126"), 
date_2 = c("2009-01-31","2010-01-31", "2010-01-31", "2010-01-31" ),
date_3 = c("2011-01-31","2010-01-31", "2020-01-31", "2020-01-31" ))
table_2$id = as.factor(table_2$id)
table_2$date_2 = as.factor(table_2$date_2)
table_2$date_3 = as.factor(table_2$date_3)

需要满足的匹配条件:

  • table_1$id = table_2$id
  • table_1$date_1介于table_2$date_2和table_2$date_3之间

1. Base R实现

完全可以用Base R实现,逻辑是先按id做匹配生成同id的所有行组合,再筛选符合日期间隔的行即可。由于你的日期是YYYY-MM-DD格式的因子,字符串排序逻辑和日期排序逻辑一致,直接比较大小即可。

# 左连接:保留table_1的所有行,匹配table_2符合条件的行,要内连接去掉all.x参数即可
merge_temp <- merge(table_1, table_2, by = "id", all.x = TRUE)
# 筛选符合日期间隔条件的记录
final_base <- merge_temp[merge_temp$date_1 >= merge_temp$date_2 & merge_temp$date_1 <= merge_temp$date_3, ]
# 可选去重:按id+date_1去重,避免相同id不同日期的记录被误删
final_base_no_dup <- final_base[!duplicated(final_base[, c("id", "date_1")]), ]

说明:你之前用sqldf出现重复行是因为table_1中id=123本身就有2条完全相同的记录,每条记录都会匹配到table_2的对应行,属于正常现象,不是方法缺陷。


2. dplyr实现

如果习惯用tidyverse语法,可以用dplyr 1.1.0及以上版本支持的非等值连接语法,代码更简洁:

library(dplyr)

final_dplyr <- left_join(
  table_1,
  table_2,
  # 直接指定连接条件
  join_by(id == id, date_1 >= date_2, date_1 <= date_3)
)
# 可选去重
final_dplyr_no_dup <- final_dplyr %>% distinct(id, date_1, .keep_all = TRUE)

如果需要其他连接类型,把left_join替换为inner_join(内连接)、right_join(右连接)即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 07:45:04