如何在R中基于动态列匹配规则自动为数据框赋值结果?
解决方案:用tidyverse实现动态规则匹配(带优先级)
示例数据
先定义问题中的示例数据框和规则表:
library(tidyverse) # 待匹配的数据框 df <- tibble( ID = c(1,2,3,4,5), Category = c("A", "B", "A", "C", "B"), SubCategory = c("X", "Y", "X", "X", "X") ) # 规则表:主键+可选副键匹配,先定义的规则优先级更高 ID_Matrix <- tibble( PrimaryKeyField = c("Category", "Category", "ID"), PrimaryMatchData = c("A", "B", "4"), SecondaryKeyField = c("SubCategory", NA, NA), SecondaryMatchData = c("Y", NA, NA), Result = c("High", "Medium", "Low") )
自动化匹配代码
利用purrr::reduce按规则优先级批量处理,仅对未匹配的行应用后续规则:
# 初始化Result列为NA(未匹配状态) df_result <- df %>% mutate(Result = NA_character_) # 为每条规则生成处理函数:仅更新未匹配的行 rule_processors <- ID_Matrix %>% rowwise() %>% mutate( processor = list(function(data) { # 捕获当前规则的目标结果 target_result <- Result # 构建主键匹配条件 match_cond <- sym(PrimaryKeyField) == PrimaryMatchData # 若有副键,添加副键匹配条件 if (!is.na(SecondaryKeyField)) { match_cond <- match_cond & (sym(SecondaryKeyField) == SecondaryMatchData) } # 仅对Result为NA且满足匹配条件的行赋值 data %>% mutate(Result = ifelse(is.na(Result) & !!match_cond, target_result, .data$Result)) }) ) %>% pull(processor) # 按规则定义顺序依次应用,保证优先级 df_final <- reduce(rule_processors, ~ .y(.x), .init = df_result)
代码逻辑说明
- 初始化状态:先给数据框添加
Result列,初始值为NA,标记未匹配任何规则。 - 规则函数生成:遍历规则表的每一行,生成对应的匹配函数。函数会根据主键+可选副键构建匹配条件,仅对还未匹配(
Result为NA)的行进行赋值。 - 优先级保障:通过
reduce按规则表的原始顺序应用函数,先定义的规则先完成匹配赋值,后续规则无法覆盖已匹配的结果,完美实现"先定义规则覆盖后定义规则"的要求。
预期输出
df_final #> # A tibble: 5 × 4 #> ID Category SubCategory Result #> <dbl> <chr> <chr> <chr> #> 1 1 A X NA #> 2 2 B Y Medium #> 3 3 A X NA #> 4 4 C X Low #> 5 5 B X Medium
内容的提问来源于stack exchange,提问作者J.C.
相关产品推荐
相关产品推荐

