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

R语言如何基于正则表达式ID与年份字段合并两个数据框

R双键(正则ID+精确年份)合并数据框方案

问题复现

需要合并两个R数据框,匹配规则:

  • 双字段共同匹配:year字段做精确等值匹配,ID字段做正则模式匹配(a表ID中.为正则通配符,代表匹配任意单个字符,对应匹配b表的完整ID)
  • 匹配无歧义,不存在一个a表ID模式匹配多个b表ID的情况
    示例输入数据:
a<- data.frame(x=c(1,4,6,8,1,6,7,2),ID=c("132","14.","732","2..","132","14.","732","2.."),year=c(1,1,1,1,2,2,2,2))
b<- data.frame(y=c(2,7,5,5,1,1,2,3),ID=c("132","144","732","290","132","144","732","290"),year=c(1,1,1,1,2,2,2,2))

期望输出:

output<-data.frame(y=c(2,7,5,5,1,1,2,3),x=c(1,4,6,8,1,6,7,2),ID=c("132","144","732","290","132","144","732","290"), year=c(1,1,1,1,2,2,2,2))

此前方案的报错原因:

  • 用substr截取前缀匹配失败:因为通配符位置不固定(如14.是前2位固定、2..是仅第1位固定),固定长度截取会漏匹配
  • 直接调用regex_inner_join(b,a, by=c("ID","year"))报Coercing pattern to a plain character vector:一是传参逻辑错误,未指定不同字段的匹配规则,函数默认将数值型year也当做正则pattern做类型转换;二是未明确正则匹配的方向,把无通配符的b表ID当做了匹配模式。

可行方案

方案1:fuzzyjoin包实现(代码最简洁)

regex_inner_join的默认逻辑是第二个传入表的匹配列作为正则pattern,匹配第一个传入表的对应列值,需要通过match_fun为每个匹配字段单独指定匹配规则,代码如下:

# 首次使用先安装包
# install.packages("fuzzyjoin")
library(fuzzyjoin)

# 注意传参顺序:存完整ID的b表在前,存正则pattern的a表在后
merge_res <- regex_inner_join(
  x = b,
  y = a,
  by = c("ID" = "ID", "year" = "year"),
  # 匹配函数顺序和by字段一一对应:ID走正则检测,year走精确相等匹配
  match_fun = list(stringr::str_detect, `==`)
)

# 整理列名和列顺序,去掉a表冗余的ID、year列
merge_res <- merge_res[, c("y", "x", "ID.x", "year.x")]
colnames(merge_res) <- c("y", "x", "ID", "year")

运行结果和期望输出完全一致。

注意:正则匹配默认会做部分匹配,如果你需要严格匹配整串ID(避免短pattern匹配长ID),可以提前把a表的ID加上首尾锚定符:a$ID <- paste0("^", a$ID, "$"),再执行上面的合并逻辑即可。

方案2:基础R实现(无第三方包依赖)

如果不想安装额外包,可以按年份分组后逐组做ID匹配:

# 按年份拆分两个表
a_split <- split(a, a$year)
b_split <- split(b, b$year)

# 逐年份匹配
res_list <- lapply(names(b_split), function(yr){
  a_sub <- a_split[[yr]]
  b_sub <- b_split[[yr]]
  # 为b表每一行匹配对应的x值
  b_sub$x <- vapply(b_sub$ID, function(b_id){
    match_flag <- vapply(a_sub$ID, function(a_id) grepl(paste0("^", a_id, "$"), b_id), logical(1))
    a_sub$x[match_flag]
  }, numeric(1))
  b_sub
})

# 合并分块结果
merge_res <- do.call(rbind, res_list)
rownames(merge_res) <- NULL

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 10:45:50