Dynamic variables in case_when()

Hi folks,

df <- tibble(
  col1 = c(T,F,T,T,F),
  col2 = c(F,F,T,F,F),
  col3 = c(F,F,T,F,F)
  )

the code bellow produces desired results

df |> mutate(
  col_eval = case_when(col1 | col2 | col3 ~ "its true")
)

However, I was wondering whther it is possible to specify condition in case_when() dynamically?! I tried something like this and it doesnt work:

vars <- str_c(colnames(df), collapse = "|")
df |> mutate(
  col_eval = case_when({{ vars }} ~ "its true")
)

I also tried following but without luck:

vars <- str_c(colnames(df), collapse = "|")
df |> mutate(
  col_eval = case_when(!!as.symbol(vars) ~ "its true")
)

I know that data masking here plays the role. But im not sure how to go around it, is it recommended or not to do it in such a way?

Thank you and regards

This is not so much about data masking as it is the difference between a string (sequence of characters within quotes) and an expression (something that R can evaluate).

I believe your first attempt would have said this in the error message :

# ..1 (left)` must be a logical vector, not the string "col1|col2|col3".

you can get true/false ( a logical) from evaluating an expression that would return true or false, but not really from a string per say.

Here is a version that would work using base functions and then a modification using rlang

(vars <- parse(text=str_c(colnames(df), collapse = "|")))

df |> mutate(
  col_eval = case_when(eval(vars) ~ "its true")
)
library(rlang)
vars <- parse_expr(str_c(colnames(df), collapse = "|"))

df |> mutate(
  col_eval = case_when(!!vars ~ "its true")
)
1 Like

it makes perfect sense. Thank you very much, @nirgrahamuk!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.