基于另一列相似文本提取R数据框列内容的问题求助
解决方案
首先,你之前的str_extract用法有误:参数顺序搞反了,str_extract(string, pattern)里第一个参数是要搜索的字符串(对应你的col_2),第二个是匹配模式(对应你的col_1)。而且默认是精确匹配,所以需要引入模糊匹配逻辑才能实现需求。
下面提供两种可行的方案:
方案1:逐行模糊匹配(基于编辑距离)
用adist计算两个字符串的编辑距离,设定一个阈值(比如编辑距离≤3,可根据需求调整),当col_1是col_2的近似子串时提取col_1,否则返回NA。
library(stringr) # 先修正原始数据的语法错误 df <- data.frame( col_1 = c("Pamela Da Costa", "Gaelle Bourget", "Etienne Klein"), col_2 = c("Pamela Giannotti", "Francois Sommet", "Pamela Da Costa Giovanni"), stringsAsFactors = FALSE ) extract_name <- function(name1, name2) { # 遍历每一对name1和name2 mapply(function(n1, n2) { # 生成col_2中所有长度和col_1一致的子串,计算与col_1的编辑距离 substrings <- str_extract_all(n2, str_c(".{1,", nchar(n1), "}"))[[1]] min_dist <- min(adist(n1, substrings)) # 阈值判断:编辑距离≤3则认为近似匹配 if (min_dist <= 3) n1 else NA }, name1, name2) } df$extracted <- extract_name(df$col_1, df$col_2)
运行后得到的结果和你期望的df2一致:
col_1 col_2 extracted 1 Pamela Da Costa Pamela Giannotti <NA> 2 Gaelle Bourget Francois Sommet <NA> 3 Etienne Klein Pamela Da Costa Giovanni Pamela Da Costa
方案2:用fuzzyjoin包高效匹配(适合大数据)
如果你的数据集很大,逐行循环处理效率低,可以用fuzzyjoin包的模糊连接功能,结合编辑距离判断匹配:
library(fuzzyjoin) library(dplyr) df <- df %>% mutate(row_id = row_number()) # 模糊连接:匹配条件为编辑距离≤3,且col_1是col_2的近似子串 matched <- df %>% fuzzy_inner_join( df, by = c("col_1" = "col_2"), match_fun = function(x, y) { adist(x, y) <= 3 & str_detect(y, str_replace_all(x, "\\s+", "\\\\s+")) } ) %>% select(row_id = row_id.x, extracted = col_1.x) # 合并回原数据框 df_final <- df %>% left_join(matched, by = "row_id") %>% select(-row_id)
这个方法避免了循环操作,处理大数据集时效率更高,结果同样符合预期。
关键说明
- 编辑距离阈值:可以根据你的数据调整,比如长名字可适当调大阈值,短名字调小。
str_replace_all(x, "\\s+", "\\\\s+")是为了适配col_2中可能存在的多余空格,让空格作为可变匹配项。
内容的提问来源于stack exchange,提问作者Jpaete
相关产品推荐
相关产品推荐

