You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在含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和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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.17 11:37:36