如何向包括glue函数的通用case_when语句添加条件?

huangapple go评论85阅读模式
英文:

How to add a condition to a generic case_when statement including the glue function?

问题

我有两个数据框(df1和df2),如下表所示。根据df1中的条件,我需要检查df2中的值。预期输出也已呈现。

条件基于df1中的列depvalue,在df2中根据从df1中的列var中获取的变量进行检查。请参考以下示例:

例如,基于df1中的第1行,我们判断df2中列A的值是否为TRUE或FALSE。

  1. 如果E == 1,则A == TRUE

  2. 如果E != 1,则我们需要检查以下条件:

    • 如果A == NA,则A == TRUE

    • 如果A == 除NA之外的任何值,则A == FALSE

  3. 如果A和E都是NA,则A == 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]
)

# 对于df1中具有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)
英文:

I have two data frames (df1 and df2) as you can see in the tables below. Based on the conditions in df1, I need to check the values in df2. The expected output is also presented.
The condition is based on the columns dep and value in df1 checked in df2 against the the variables taken from the column var in df1. Please see the following examples:

For instance, based on row 1 in df1, we judge whether the values in column A in df2 are TRUE or FALSE.

  1. if E == 1, A == TRUE

  2. if E != 1, we need to check the following conditions:

    - if A == NA, A == TRUE

    - if A == any values other than NA, A == FALSE

  3. If A and E are both NAs, A == TRUE

Here is the code that works for the first two conditions, my question is how to add the third condition:

library(tidyverse)
library(rlang)
library(glue)
rules_1 &lt;- tibble::tribble(
  ~var, ~value,    ~dep,
  &quot;A&quot;,   &quot;==1&quot;,    &quot;E&quot;, 
  &quot;B&quot;,   &quot;==1&quot;,    &quot;E&quot;, 
  &quot;C&quot;,   &quot;!=0&quot;,    &quot;A&quot;, 
  &quot;D&quot;,   &quot;==2&quot;,    &quot;G&quot;, 
  &quot;E&quot;,      NA,     NA, 
  &quot;F&quot;,      NA,     NA, 
  &quot;G&quot;,    &quot;%in% c(&#39;b&#39;,&#39;d&#39;)&quot;,     &quot;F&quot;,
)

df2 &lt;- data.frame(
  stringsAsFactors = FALSE,
  ID = c(&quot;1q&quot;, &quot;2d&quot;, &quot;4f&quot;, &quot;3g&quot;, &quot;8j&quot;, &quot;5g&quot;, &quot;9l&quot;),
  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]
)

# And for variables that have NA values in df1, we do not need to do anything. 

(rules_2 &lt;- filter(rules_1,
                   !is.na(dep)))

# rules from data
(rules_3 &lt;- mutate(rules_2,
                   rule = glue(&quot;case_when({dep}{value}~TRUE,is.na({var})~TRUE,TRUE ~ FALSE)&quot;)))

(mutators &lt;- rules_3$rule)
names(mutators) &lt;- rules_3$var

(parsed_mutators &lt;- rlang::parse_exprs(mutators))

mutate(df2,
       !!!parsed_mutators) 

答案1

得分: 0

延伸 case_when 逻辑

case_when( {dep}{value}~TRUE,
           is.na({dep}) &amp; is.na({var}) ~ TRUE,
           is.na({var})~TRUE,
           TRUE ~ FALSE)
英文:

extend the case_when logic

case_when( {dep}{value}~TRUE,
           is.na({dep}) &amp; is.na({var}) ~ TRUE,
           is.na({var})~TRUE,
           TRUE ~ FALSE)

</details>



huangapple
  • 本文由 发表于 2023年6月29日 17:35:05
  • 转载请务必保留本文链接:https://go.coder-hub.com/76579830.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定