如何在R中使用dplyr::full_join实现数据框的部分匹配连接?
按字符串前缀匹配合并数据集的实现方案
需求说明
需要将两个数据集按以下规则合并:mykey中的Item值需匹配mydata中Item条目的前缀部分,并用mykey的Avg值替换mydata的对应字段。
示例数据
library(tibble) mydata <- tibble(Item = c("ab_kssv", "ab_kd", "cde_kh", "cde_ksa", "cde"), Answer = c(1,2,3,4,5), Avg = rep(-100, length(Item))) mykey <- tibble(Item = c("ab", "cde"), Avg = c(0 ,10))
期望结果
Item Answer Avg 1 ab_kssv 1 0 2 ab_kd 2 0 3 cde_kh 3 10 4 cde_ksa 4 10 5 cde 5 10
现有方案问题
你目前使用的for循环方案虽然能实现需求,但可读性差,且在数据集较大时效率较低:
for (currLine in 1:nrow(mydata)) { mydata$Avg[currLine] <- mykey$Avg[str_starts(mydata$Item[currLine], mykey$Item)] }
更优解决方案
dplyr的full_join(及其他join函数)的by参数仅支持精确列匹配,无法直接实现前缀模糊匹配,以下是两种更简洁可读的替代方案:
方案1:使用fuzzyjoin包实现模糊匹配合并
fuzzyjoin专门用于处理非精确匹配的合并场景,代码简洁且可读性强:
library(fuzzyjoin) library(dplyr) library(stringr) mydata_joined <- mydata %>% fuzzy_left_join(mykey, by = "Item", match_fun = str_starts) %>% # 用mykey的Avg替换原mydata的Avg mutate(Avg = coalesce(Avg.y, Avg.x)) %>% # 整理目标列 select(Item = Item.x, Answer, Avg)
方案2:dplyr结合stringr的行级操作实现
如果不想额外加载包,可通过dplyr的行分组操作实现:
library(dplyr) library(stringr) mydata_updated <- mydata %>% rowwise() %>% # 逐行匹配前缀并替换Avg mutate(Avg = mykey$Avg[str_starts(Item, mykey$Item)]) %>% ungroup()
内容的提问来源于stack exchange,提问作者lilla
相关产品推荐
相关产品推荐

