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

在R中基于ID匹配最邻近日期并创建新数据框的实现

我来帮你搞定这个按ID匹配最邻近日期的需求!下面分别用dplyr和data.table两种常用工具实现,先看我们的示例数据:

示例数据

首先把你的示例数据转换成R可识别的格式:

# Dataframe A
df_a <- data.frame(
  ID = c(3,5,8,1,1,1),
  DATE_A = c("15/05/06", "14/11/05", "25/11/08", "16/12/10", "5/01/12", "24/07/14")
)

# Dataframe B
df_b <- data.frame(
  ID = c(3,3,5,5,5,8,8,8,8,1,1,1,1,1),
  DATE_B = c("12/12/05", "17/04/06", "25/07/05", "26/09/05", "1/12/05", 
             "12/09/08", "13/11/08", "23/12/08", "31/03/09", "26/11/10", 
             "12/08/11", "12/11/11", "14/03/14", "8/08/14")
)

第一步必须先把字符型的日期转换成R的Date类型,否则没法计算日期差:

# 转换日期格式(注意是dd/mm/yy格式)
df_a$DATE_A <- as.Date(df_a$DATE_A, format = "%d/%m/%y")
df_b$DATE_B <- as.Date(df_b$DATE_B, format = "%d/%m/%y")

方法一:使用dplyr包

我们可以通过按ID左连接,然后计算日期差的绝对值,最后分组筛选出差值最小的记录:

library(dplyr)

result_dplyr <- df_a %>%
  # 按ID左连接,把同ID的所有DATE_B都匹配过来
  left_join(df_b, by = "ID") %>%
  # 计算两个日期的绝对差值
  mutate(date_diff = abs(DATE_A - DATE_B)) %>%
  # 按ID和DATE_A分组,筛选出差值最小的行(如果有多个相同最小差值会保留所有)
  group_by(ID, DATE_A) %>%
  slice_min(order_by = date_diff, n = 1, with_ties = TRUE) %>%
  # 去掉不需要的差值列,整理结果
  ungroup() %>%
  select(ID, DATE_A, DATE_B)

# 查看结果
print(result_dplyr)

方法二:使用data.table包

data.table的写法更高效,适合处理大数据量,思路类似但语法更简洁:

library(data.table)

# 转换成data.table格式
setDT(df_a)
setDT(df_b)

# 实现匹配逻辑
result_dt <- df_a[df_b, on = "ID", allow.cartesian = TRUE][, 
  date_diff := abs(DATE_A - DATE_B)][, 
  .SD[date_diff == min(date_diff)], by = .(ID, DATE_A)][, 
  !"date_diff"]

# 查看结果
print(result_dt)

结果示例

两种方法都会得到类似这样的输出(日期显示为R的标准Date格式):

ID      DATE_A      DATE_B
1:  3 2006-05-15 2006-04-17
2:  5 2005-11-14 2005-12-01
3:  8 2008-11-25 2008-11-13
4:  1 2010-12-16 2010-11-26
5:  1 2012-01-05 2011-11-12
6:  1 2014-07-24 2014-08-08

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:25:56