A couple of case_when() tricks

Combining case_when() and across()

If you want to use case_when() and across() different variables, then here is an example that can do this with the help of the get() and cur_column() functions.

library(tidyverse)

iris_df <- as_tibble(iris) %>% 
  mutate(flag_Petal.Length = as.integer(Petal.Length > 1.5),
         flag_Petal.Width = as.integer(Petal.Width > 0.2))

iris_df %>% 
  mutate(across(c(Petal.Length, Petal.Width),
                ~case_when(
                  get(glue::glue("flag_{cur_column()}")) == 1 ~ NA_real_,
                  TRUE ~ .x
                ))) %>% 
    select(contains("Petal"))
## # A tibble: 150 × 4
##    Petal.Length Petal.Width flag_Petal.Length flag_Petal.Width
##           <dbl>       <dbl>             <int>            <int>
##  1          1.4         0.2                 0                0
##  2          1.4         0.2                 0                0
##  3          1.3         0.2                 0                0
##  4          1.5         0.2                 0                0
##  5          1.4         0.2                 0                0
##  6         NA          NA                   1                1
##  7          1.4        NA                   0                1
##  8          1.5         0.2                 0                0
##  9          1.4         0.2                 0                0
## 10          1.5         0.1                 0                0
## # ℹ 140 more rows

Is there any way to use this with a function from the rlang packages instead of get()? It’s a little beyond my current understanding of tidy evaluation but let me know in the comments if you know please.

Combining case_when() with if_any() and if_all()

The if_any() and if_all() functions can be used to save typing lots of variables (as these allow the use of tidyselect helpers) within case_when().

df1 <- tibble(var1 = c(1, 0, 1, NA),
              var2 = c(1, 0, 0, NA))

df1 %>% 
  mutate(category = case_when(
    if_any(c(var1, var2), ~.x > 0) ~ 1, 
    if_all(c(var1, var2), is.na) ~ NA_real_,
    TRUE ~ 0
  ))
## # A tibble: 4 × 3
##    var1  var2 category
##   <dbl> <dbl>    <dbl>
## 1     1     1        1
## 2     0     0        0
## 3     1     0        1
## 4    NA    NA       NA
Avatar
Alan Yeung
Research Fellow and Healthcare Scientist

Applied statistician, currently working mainly on blood borne viruses and drugs. Supporter of all things R.

Related