Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get case_when in dplyr accept conditions from character

I am trying to use case_when in shiny application in order to build an app, showing the preview of some selection policy expressed as a set of rules.

In the app, user can input expressions in case_when syntax, e.g.:

cond = "Age > 40 ~ 1, TRUE ~ 0"

and they should be substituted in case_when.

I am looking at rlang and trying to figure out how to get an expression from a character vector, e.g.

tibble::tribble(~Age,23,26,32,50,51,52,25,49,34,54) %>% 
  mutate(result = case_when(!!!quos(syms(cond))))

but, apparently, fail to get it right

like image 212
zzr Avatar asked Oct 19 '25 18:10

zzr


2 Answers

How about with parse_exprs?

library(dplyr)
library(rlang)
cond <- "Age > 40 ~ 1, TRUE ~ 0"
cond <- gsub(",",";",cond)
repdata %>% mutate(result = case_when(!!!rlang::parse_exprs(cond)))
## A tibble: 10 x 2
#     Age result
#   <dbl>  <dbl>
# 1    23      0
# 2    26      0
# 3    32      0
# 4    50      1
# 5    51      1
# 6    52      1
# 7    25      0
# 8    49      1
# 9    34      0
#10    54      1

This is required because parse_expr returns one expression, whereas case_when requires 2 or more expressions (separated by commas in code) to have 2 cases. Meanwhile, parse_exprs returns 2 or more expressions, but it splits expressions on ;.

Data

repdata <- tibble::tribble(~Age,23,26,32,50,51,52,25,49,34,54)
like image 76
Ian Campbell Avatar answered Oct 22 '25 06:10

Ian Campbell


This works:

library(dplyr)
library(rlang)

repdata %>% 
  mutate(result = !!parse_expr(paste0("case_when(", cond, ")"))) %>% 
  head()
#    Age result
#  <dbl>  <dbl>
#1    23      0
#2    26      0
#3    32      0
#4    50      1
#5    51      1
#6    52      1

I will note that letting users execute arbitrary R code inside of a shiny app probably isn't the best idea, though. There is probably a better way to solve this using something like cut.

like image 39
dave-edison Avatar answered Oct 22 '25 08:10

dave-edison



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!