R语言 基于列值部分匹配从另一数据框插入新列的实现方法
实现方案
以下两种方案都无需在每次新增分类映射时修改匹配逻辑,仅需直接在df2中新增关键词和对应分类的行即可,完全符合你的需求:
方法1:使用fuzzyjoin包实现正则左连接(推荐)
逻辑清晰,适配性强,支持自定义匹配规则:
# 首次使用先安装包 # install.packages("fuzzyjoin") library(fuzzyjoin) library(dplyr) df3 <- df1 %>% # 以df1的description包含df2的description作为匹配条件 regex_left_join(df2, by = c("description" = "description"), ignore_case = TRUE) %>% # 整理字段得到目标结构 select(date, description = description.x, amount, category)
如果存在单个描述同时匹配多个关键词的场景,可给df2增加优先级列自定义匹配优先级,避免冲突:
# 新增优先级列的df2示例,数值越小优先级越高 df2 <- tibble::tribble( ~description, ~category, ~priority, "insurance", "INS", 2, "grocery", "GRY", 2, "insurance-abc", "INS_SPECIAL", 1 ) # 带优先级处理的匹配代码 df3 <- df1 %>% regex_left_join(df2, by = c("description" = "description"), ignore_case = TRUE) %>% arrange(priority) %>% distinct(date, description.x, amount, .keep_all = TRUE) %>% select(date, description = description.x, amount, category)
方法2:无额外依赖的原生实现
不想安装第三方包可以用这个方案,匹配优先级和df2的行顺序一致:
library(dplyr) df3 <- df1 %>% mutate( category = sapply(description, function(x){ match_idx <- sapply(df2$description, function(y) grepl(y, x, ignore.case = TRUE)) ifelse(any(match_idx), df2$category[which.max(match_idx)], NA_character_) }) )
内容的提问来源于stack exchange,提问作者Madwolf
相关产品推荐
相关产品推荐

