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

如何在R中基于ID、EG与最邻近年份实现数据框左连接?

R中按ID、EG匹配并基于最邻近年份合并数据框的简便方案

需求说明

原本打算执行精确匹配的左连接:

merge(b, a, by=c("ID", "EG", "year"), all.x=TRUE)

但需要实现:当a中的年份在b中找不到时,将a的test值匹配到b中年份最接近的行(年份差相等时采用四舍五入规则),最终确保结果的所有行都能获取到对应最邻近年份的test值。

示例数据

set.seed(123) # 设置随机种子保证结果可复现
a <- data.frame(ID = 1:4,
                EG = c("CA", "EV", "EV", "TR"),
                year =c(2000, 2005, 2010, 2020), test = sample(4))

b <- data.frame(ID = 1:4,
                EG = c("CA", "EV", "EV", "TR"),
                test = sample(20),
                year = sample(2000:2019, 20, replace=TRUE))

方案一:使用dplyr + fuzzyjoin(直观易懂)

先安装并加载所需包:

install.packages(c("dplyr", "fuzzyjoin"))
library(dplyr)
library(fuzzyjoin)

执行匹配逻辑:

# 按ID、EG分组,计算b中每行与a中对应组各年份的差值,取最接近的
result <- fuzzy_left_join(b, a, 
                          by = c("ID", "EG", "year"),
                          match_fun = list(`==`, `==`, function(x, y) TRUE)) %>%
  group_by(ID.x, EG.x, year.x, test.x) %>%
  mutate(year_diff = abs(year.x - year.y)) %>%
  filter(year_diff == min(year_diff)) %>%
  # 处理年份差相等的情况(四舍五入:选年份更大的那个)
  filter(year.y == max(year.y)) %>%
  ungroup() %>%
  select(ID = ID.x, EG = EG.x, year = year.x, test_b = test.x, test_a = test.y)

方案二:使用data.table(高效适合大数据)

先安装并加载data.table:

install.packages("data.table")
library(data.table)

转换为data.table并执行滚动匹配:

setDT(a)
setDT(b)

# 按ID、EG分组,对year做滚动匹配,设置roll="nearest"实现最邻近匹配
result <- b[a, on = .(ID, EG, year), roll = "nearest", 
            .(ID, EG, year = x.year, test_b = x.test, test_a = i.test)]

注:roll="nearest"会自动处理年份差相等的情况,默认会选择较大的年份(符合四舍五入规则)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 16:15:41