R语言多匹配场景下DataFrame全匹配实现方案问询
搞定DataFrame一对多匹配的全结果保留问题
嘿,这个场景我太熟悉了!match()函数天生就是只返回第一个匹配项的位置,遇到像伦敦对应UK和英格兰这种一对多的关联时,确实没法满足你保留所有匹配的需求。不过没关系,用tidyverse工具链就能轻松解决,我给你两种实用的方案:
方案一:分关键词匹配后合并
这个思路很直接,分别处理每个关键词列的匹配,再把结果合并回原表:
library(tidyverse) # 处理keyword1对应的所有区域,转成宽格式 df_key1 <- df1 %>% select(document, keyword1) %>% left_join(df2, by = c("keyword1" = "City")) %>% group_by(document, keyword1) %>% mutate(area_col = paste0("area", row_number())) %>% pivot_wider(names_from = area_col, values_from = area) # 处理keyword2对应的所有区域,注意列名要接着keyword1的序号 df_key2 <- df1 %>% select(document, keyword2) %>% left_join(df2, by = c("keyword2" = "City")) %>% group_by(document, keyword2) %>% mutate(area_col = paste0("area", row_number() + ncol(df_key1) - 2)) %>% # 减去document和keyword1两列 pivot_wider(names_from = area_col, values_from = area) # 合并所有结果 final_result <- df1 %>% left_join(df_key1, by = c("document", "keyword1")) %>% left_join(df_key2, by = c("document", "keyword2")) print(final_result)
运行后就能得到你想要的输出:
document keyword1 keyword2 area1 area2 area3 1 1 Paris London France UK England 2 2 Valencia Glasgow Spain UK Scotland
方案二:长格式统一处理(更适配多关键词场景)
如果你以后可能会增加更多关键词列(比如keyword3、keyword4),这个方案会更灵活:
library(tidyverse) # 先把df1的所有关键词列转成长格式,方便统一匹配 df1_long <- df1 %>% pivot_longer(cols = starts_with("keyword"), names_to = "keyword_category", values_to = "City") # 匹配所有区域,再转回宽格式 final_result <- df1_long %>% left_join(df2, by = "City") %>% group_by(document, keyword_category) %>% mutate(area_order = row_number()) %>% ungroup() %>% # 给每个区域生成唯一的列名 mutate(area_col = paste0("area", row_number())) %>% pivot_wider(names_from = area_col, values_from = area) %>% # 回到原表的结构,合并同一行的结果 select(-keyword_category, -City) %>% group_by(document, keyword1, keyword2) %>% summarise(across(starts_with("area"), ~ first(na.omit(.))), .groups = "drop") print(final_result)
这个方法先把分散的关键词列整合到一列,一次性完成所有城市的区域匹配,再重新整理成你需要的宽格式,扩展性更强。
补充说明:为什么match不行?
match()的设计目标是高效找到第一个匹配项的索引,这在一对一的关联场景下非常好用,但面对一对多的情况,它没办法返回所有匹配的位置。而我们用的left_join()会保留所有匹配结果,再配合pivot_wider()就能把多行的匹配结果转换成多列,完美解决你的需求。
内容的提问来源于stack exchange,提问作者Jasper
相关产品推荐
相关产品推荐

