R语言中如何基于名字模糊匹配合并含职位的DataFrame?
解决两表基于名字的匹配合并问题
你的问题出在使用stringdist_left_join时,是通过整体字符串的相似度来匹配的,而不是检查名字是否是name字段的子串。比如"Doctor John Doe"和"John"的整体字符串差异很大,jaccard距离远超过0.2,所以匹配失败。下面提供两种可靠的解决方案:
方法一:用正则匹配子串(推荐)
使用fuzzyjoin包中的regex_left_join,直接检查df2的名字是否是df1中name字段的子串,无需处理字符串距离:
library(fuzzyjoin) library(dplyr) df1 <- data.frame(name = c("Doctor John Doe", "Jane Smith", "Assistant manager Alice Johnson")) df2 <- data.frame(preusuel = c("John", "Bob", "Alice")) # 正则左连接,匹配preusuel是否在name中 result <- regex_left_join(df1, df2, by = c("name" = "preusuel"), match_fun = function(x, y) grepl(y, x, ignore.case = TRUE)) # 查看结果 print(result)
运行后得到正确结果:
| name | preusuel |
|---|---|
| Doctor John Doe | John |
| Jane Smith | NA |
| Assistant manager Alice Johnson | Alice |
ignore.case = TRUE是为了兼容大小写不一致的情况(比如"alice"和"Alice"),如果你的数据大小写完全统一,可以去掉这个参数。
方法二:先从df1提取名字再匹配
如果你能确定名字在name字段中的位置(比如是第二个单词,或者姓氏前的单词),可以先提取名字再用普通的左连接:
library(dplyr) library(stringr) df1 <- data.frame(name = c("Doctor John Doe", "Jane Smith", "Assistant manager Alice Johnson")) df2 <- data.frame(preusuel = c("John", "Bob", "Alice")) # 提取名字:这里假设名字是最后一个姓氏前的单词(即倒数第二个单词) df1_extracted <- df1 %>% mutate(first_name = word(name, -2)) # 普通左连接 result <- df1_extracted %>% left_join(df2, by = c("first_name" = "preusuel")) %>% select(name, preusuel) print(result)
这个方法需要你明确名字在字符串中的位置,适用性不如方法一,但匹配效率更高。
内容的提问来源于stack exchange,提问作者Wilcar
相关产品推荐
相关产品推荐

