使用dplyr实现数据集精确匹配与部分字符串匹配连接
解决方案
要实现精确匹配exact列,同时判断pf$id_part是否包含在cj$id_part中的连接逻辑,结合dplyr和stringr可以轻松完成,以下是两种可行方案:
方案一:逐行匹配(rowwise)
这种方式直观易懂,逐行处理cj的每条记录,在pf中筛选符合条件的匹配项:
# 加载所需包 library(dplyr) library(stringr) # 定义数据集 pf <- data.frame('exact'=c('s1','s2','s3','s2','s4'),'id_part'=c('a','a','a','b','c'), 'value'=c(1,2,3,4,5)) cj <- data.frame('exact'=c('s1','s1','s4','s2','s4'), 'id_part'=c('saf','r2a@ff','k5-a','6b4-d','ab1')) # 生成结果 output <- cj %>% rowwise() %>% # 逐行处理 mutate( # 在pf中筛选exact匹配且pf$id_part包含于当前cj$id_part的记录 value = pf %>% filter(exact == !!current_env()$exact, str_detect(!!current_env()$id_part, id_part)) %>% pull(value) %>% # 若有匹配值则取该值,否则赋值0 {ifelse(length(.) > 0, ., 0)} ) %>% ungroup() # 取消逐行模式 print(output)
方案二:左连接后筛选分组
先基于exact列做左连接,再通过字符串匹配筛选有效记录,最后分组聚合得到结果:
# 加载所需包 library(dplyr) library(stringr) # 定义数据集 pf <- data.frame('exact'=c('s1','s2','s3','s2','s4'),'id_part'=c('a','a','a','b','c'), 'value'=c(1,2,3,4,5)) cj <- data.frame('exact'=c('s1','s1','s4','s2','s4'), 'id_part'=c('saf','r2a@ff','k5-a','6b4-d','ab1')) # 生成结果 output <- cj %>% # 按exact列精确左连接,保留cj所有行 left_join(pf, by = "exact", suffix = c("_cj", "_pf")) %>% # 判断pf$id_part是否包含在cj$id_part中,匹配则保留value,否则设为0 mutate( value = ifelse(str_detect(id_part_cj, id_part_pf), value, 0) ) %>% # 按cj的原始行分组,提取有效value(因左连接可能产生重复行) group_by(exact, id_part_cj) %>% summarise( value = max(value), .groups = "drop" ) %>% # 还原列名 rename(id_part = id_part_cj) print(output)
说明
- 两种方案均会输出你预期的结果,核心逻辑是用
str_detect()判断字符串包含关系,而非使用stringdist(该函数用于计算字符串相似度,不适合判断包含场景)。 - 若同一
cj行存在多个符合条件的pf记录,可根据需求调整聚合逻辑(如sum()或first())。
内容的提问来源于stack exchange,提问作者efz
相关产品推荐
相关产品推荐

