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

如何在R中基于子串边界匹配实现数据表的左连接?

按子串边界规则实现数据表左连接

需求说明

需要将两个数据表按以下规则做左连接:

  • 保留第一个表(df)的所有数据
  • 匹配规则:第二个表(df2)的key2列子串需完整出现在df的key1列字符串中,且子串前后不能直接跟随字母

示例数据

df <- data.frame(key1 = c("apple pie with custard", "chicken and mushroom pie", "key lime pie", "key limecake"))

df2 <- data.frame(key2 = c("key lime", "chicken", "custard"),
                  val = c("dessert", "savoury", "dessert"))

实现方案

这里用dplyr和stringr包实现,核心是通过正则负向前后断言确保子串前后无字母:

library(dplyr)
library(stringr)

# 定义匹配函数:对每个key1值,找到符合规则的val
get_matched_val <- function(target_str) {
  # 为每个key2构建正则:前后不能是字母,同时转义空格避免匹配问题
  regex_patterns <- str_c("(?<![a-zA-Z])", str_replace_all(df2$key2, "\\s", "\\\\s"), "(?![a-zA-Z])")
  # 找到匹配的key2对应的索引
  match_pos <- which(str_detect(target_str, regex_patterns))
  # 返回对应val,无匹配则返回NA
  if (length(match_pos) > 0) df2$val[match_pos] else NA
}

# 生成结果
final_result <- df %>%
  mutate(val = sapply(key1, get_matched_val))

# 输出结果
print(final_result)

结果验证

运行后输出与预期一致:

key1     val
1   apple pie with custard dessert
2 chicken and mushroom pie savoury
3             key lime pie dessert
4             key limecake    <NA>

其中key limecake不匹配key lime,因为子串后直接跟了字母c,符合规则要求。

补充:Base R 实现

如果不想加载额外包,可以用基础R循环实现:

# 初始化val列
df$val <- NA

# 遍历每个key1值,匹配符合规则的key2
for (i in 1:nrow(df)) {
  current_key1 <- df$key1[i]
  for (j in 1:nrow(df2)) {
    # 构建正则规则
    pattern <- paste0("(?<![a-zA-Z])", gsub("\\s", "\\\\s", df2$key2[j]), "(?![a-zA-Z])")
    if (grepl(pattern, current_key1)) {
      df$val[i] <- df2$val[j]
      break # 若允许多个匹配,可移除break并处理多值情况
    }
  }
}

print(df)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 23:41:22