R语言基于规则表匹配为tibble新增grp列表列的实现方案
需求实现方案
以下实现均基于tidyverse生态,无需硬编码规则,可直接将dat和patterns作为函数入参使用。
简化版实现
仅匹配var1与patterns表的var1_patterns字段,代码如下:
library(tidyverse) dat <- dat %>% mutate(grp = map(var1, ~ { # 遍历所有非空var1规则匹配,提取命中的grp值 hit_grp <- patterns %>% filter(!is.na(var1_patterns), str_detect(.x, var1_patterns)) %>% pull(grp) # 无命中时返回NA,否则返回命中结果向量 if (length(hit_grp) == 0) NA_character_ else hit_grp }))
运行后得到的结果和你给出的简化版预期完全一致。
完整版实现
支持var1、var2双字段匹配与组合规则判断,代码如下:
library(tidyverse) dat <- dat %>% mutate(grp = pmap(., function(var1, var2, ...) { hit_grp <- pmap_chr(patterns, function(var1_patterns, var2_patterns, combine_rule, grp, ...) { # 单字段匹配逻辑:规则为空则默认满足,否则校验匹配 cond_var1 <- if (is.na(var1_patterns)) TRUE else str_detect(var1, var1_patterns) cond_var2 <- if (is.na(var2_patterns)) TRUE else identical(var2, var2_patterns) # 组合规则判断:非空规则全部满足即命中 is_hit <- if (combine_rule == "&") cond_var1 && cond_var2 else cond_var1 && cond_var2 # var2如果需要模糊匹配,可将cond_var2的identical改为str_detect(var2, var2_patterns) return(ifelse(is_hit, grp, NA_character_)) }) hit_grp <- na.omit(hit_grp) return(if (length(hit_grp) == 0) NA_character_ else hit_grp) }))
运行后得到的结果和你给出的完整版预期完全一致。
注:上述代码中var2默认按精确匹配处理,若业务需要var2也走模糊匹配,只需将
identical(var2, var2_patterns)替换为str_detect(var2, var2_patterns)即可。
内容的提问来源于stack exchange,提问作者SiriO
相关产品推荐
相关产品推荐

