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

R语言基于UserID匹配与日差≤30的两个DataFrame模糊合并实现问题

适配需求的合并实现方案

方案1:使用powerjoin包实现模糊全连接(推荐,语法简洁符合dplyr使用习惯)

powerjoin是专门扩展dplyr连接功能的包,原生支持自定义条件的模糊连接,直接适配你的需求:
首先安装加载依赖:

install.packages("powerjoin")
library(powerjoin)
library(lubridate)

然后执行全连接:

# 执行按规则的全连接
merge_res <- power_full_join(
  df11, 
  df22,
  # 第一匹配条件:UserID相等
  by = "UserID",
  # 第二匹配条件:日期差值≤30天
  condition = ~ abs(as.duration(.x$Date %--% .y$EncounterDate)) / ddays(1) <= 30,
  # 重名列自动加后缀区分
  suffix = c("_df1", "_df2")
)

这个方法会自动保留所有df11和df22的行,满足条件的行合并为单行,不满足匹配条件的行对应另一表的列填充NA。

方案2:使用sqldf包通过SQL语法实现

如果你更习惯SQL操作,可以用这个方案:
安装加载依赖:

install.packages("sqldf")
library(sqldf)

执行全连接(SQLite不直接支持全外连接,通过左连接+右连接去重实现):

merge_res <- sqldf("
  -- 左连接保留所有df11的行
  SELECT a.*, b.* FROM df11 a 
  LEFT JOIN df22 b ON a.UserID = b.UserID AND abs(julianday(a.Date) - julianday(b.EncounterDate)) <=30
  UNION
  -- 右连接保留所有df22的行
  SELECT a.*, b.* FROM df11 a 
  RIGHT JOIN df22 b ON a.UserID = b.UserID AND abs(julianday(a.Date) - julianday(b.EncounterDate)) <=30
")

两种方案输出结果一致,符合你要求的匹配规则:比如你的数据中UserID=1的2021-01-02行可以匹配到df22中UserID=1的2021-01-01行,UserID=1的2021-12-11行没有符合日期条件的匹配,对应df22的列会填充NA,仅在df11中存在的UserID=7行,对应df22列也填充NA。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 03:24:02