在R语言中实现两个DataFrame的名称列模糊映射匹配
R语言实现DataFrame名称模糊匹配替换
现有两个DataFrame:
# Dataframe #1 df1 <- data.frame(name = c("Jake", "Paul", "Luis", "Leon"), salary_new = c(60, 80, 90, 50)) # Dataframe #2 df2 <- data.frame(name = c("Paul Henderson", "John F. Smith", "Leon K.", "Luis Sierra"), salary_old = c(60, 55, 60, 80))
需求:将df1的name列中能与df2名称模糊匹配的项替换为df2的对应全名,匹配不到的保留原名称,最终得到如下结果:
df3 <- data.frame(name = c("Jake", "Paul Henderson", "Luis Sierra", "Leon K."), salary_new = c(60, 80, 90, 50))
方法一:Base R 实现
通过遍历df1的名称,结合grepl进行子串匹配完成替换:
# 遍历每个名称,查找匹配的全名 df1$name <- sapply(df1$name, function(x) { # 定位df2中包含当前名称的行 match_idx <- which(grepl(x, df2$name, fixed = TRUE)) # 有匹配则返回对应全名,无匹配则保留原名称 if (length(match_idx) > 0) df2$name[match_idx] else x }) # 得到目标DataFrame df3 <- df1
说明:
fixed = TRUE用于精确匹配子串,避免正则表达式特殊字符干扰(如果名称包含.、*等字符时尤其有用)- 如果存在一个短名称匹配多个全名的情况,此方法会返回第一个匹配项,需提前处理df2的重复匹配情况
方法二:Tidyverse 工具链实现
使用dplyr配合stringr,代码更简洁易读:
library(dplyr) library(stringr) df3 <- df1 %>% rowwise() %>% mutate(name = if_else( # 检查是否存在匹配的全名 any(str_detect(df2$name, fixed(name))), # 返回第一个匹配的全名 df2$name[str_detect(df2$name, fixed(name))][1], # 无匹配则保留原名称 name )) %>% ungroup()
说明:
rowwise()确保每一行单独处理名称匹配str_detect功能与grepl类似,用于检测子串是否存在- 同样,若存在多匹配场景,需提前明确匹配规则(比如优先匹配特定格式的全名)
额外注意事项
- 如果需要不区分大小写的匹配,可去掉
fixed = TRUE,并添加ignore.case = TRUE参数,例如grepl(x, df2$name, ignore.case = TRUE) - 若df2中存在重复的匹配项,建议先通过
distinct()或其他规则清理数据,避免匹配结果混乱
内容的提问来源于stack exchange,提问作者Student
相关产品推荐
相关产品推荐

