如何在含glue函数的通用case_when语句中添加指定条件?
基于规则数据框判断目标数据框的布尔值
我有两个数据框rules_1(即问题中的df1)和df2,需要基于rules_1中的规则检查df2对应列的值,生成布尔结果。规则基于rules_1的dep、value列,针对var列指定的df2变量进行判断,以rules_1第一行(对应df2的A列)为例,判断逻辑如下:
- 若
E == 1,则A的判断结果为TRUE - 若
E != 1,则:- 若A为
NA,判断结果为TRUE - 若A为非
NA的任意值,判断结果为FALSE
- 若A为
- 若A和E均为
NA,判断结果为TRUE
现有代码已实现前两个条件,需添加第三个条件的支持。
原代码
library(tidyverse) library(rlang) library(glue) rules_1 <- tibble::tribble( ~var, ~value, ~dep, "A", "==1", "E", "B", "==1", "E", "C", "!=0", "A", "D", "==2", "G", "E", NA, NA, "F", NA, NA, "G", "%in% c('b','d')", "F", ) df2 <- data.frame( stringsAsFactors = FALSE, ID = c("1q", "2d", "4f", "3g", "8j", "5g", "9l"), B = c(1L, 1L, NA, 1L, 2L, NA, 1L), G = c(3L, 3L, NA, 2L, 2L, NA, NA), A = c(0L, 0L, 1L, 1L, 1L, NA, NA), C = c(NA, 1L, 1L, NA, NA, 1L, 1L), D = c(NA, 1L, 1L, 1L, 1L, 3L, 2L), E = c(2L, 2L, 1L, NA, NA, 3L, 1L), F = letters[1:7] ) # 过滤出需要处理的规则(dep不为NA的行) (rules_2 <- filter(rules_1, !is.na(dep))) # 生成规则表达式 (rules_3 <- mutate(rules_2, rule = glue("case_when({dep}{value}~TRUE,is.na({var})~TRUE,TRUE ~ FALSE)"))) (mutators <- rules_3$rule) names(mutators) <- rules_3$var (parsed_mutators <- rlang::parse_exprs(mutators)) # 执行判断 mutate(df2, !!!parsed_mutators)
修改方案
要添加var和dep同时为NA时返回TRUE的条件,只需在case_when的规则最前面新增一个判断分支,修改rules_3中的规则生成逻辑即可:
修改后完整代码
library(tidyverse) library(rlang) library(glue) rules_1 <- tibble::tribble( ~var, ~value, ~dep, "A", "==1", "E", "B", "==1", "E", "C", "!=0", "A", "D", "==2", "G", "E", NA, NA, "F", NA, NA, "G", "%in% c('b','d')", "F", ) df2 <- data.frame( stringsAsFactors = FALSE, ID = c("1q", "2d", "4f", "3g", "8j", "5g", "9l"), B = c(1L, 1L, NA, 1L, 2L, NA, 1L), G = c(3L, 3L, NA, 2L, 2L, NA, NA), A = c(0L, 0L, 1L, 1L, 1L, NA, NA), C = c(NA, 1L, 1L, NA, NA, 1L, 1L), D = c(NA, 1L, 1L, 1L, 1L, 3L, 2L), E = c(2L, 2L, 1L, NA, NA, 3L, 1L), F = letters[1:7] ) # 过滤出需要处理的规则 rules_2 <- filter(rules_1, !is.na(dep)) # 新增"var和dep同时为NA"的判断分支 rules_3 <- mutate(rules_2, rule = glue("case_when(is.na({var}) & is.na({dep}) ~ TRUE, {dep}{value}~TRUE, is.na({var})~TRUE, TRUE ~ FALSE)")) mutators <- rules_3$rule names(mutators) <- rules_3$var parsed_mutators <- rlang::parse_exprs(mutators) # 执行判断并输出结果 mutate(df2, !!!parsed_mutators)
逻辑说明
is.na({var}) & is.na({dep}) ~ TRUE:优先检查目标变量(如A)和依赖变量(如E)是否同时为NA,满足则直接返回TRUE- 后续分支保持原有逻辑,依次处理依赖变量满足规则、目标变量为NA的情况,最后默认返回
FALSE
内容的提问来源于stack exchange,提问作者Rara
相关产品推荐
相关产品推荐

