The way you are collecting the inputs is not very practical to work with. Your problem is that you are trying to parse code that looks like this:
var1, var2, var3
Try typing that in your R console, you'll get the same error:
#> Error: unexpected ',' in "var1,"
So first of all refactor your code so that you collect inputs as two vectors:
cnds <- c("condition1", "condition2", "condition3")
vals <- c("1", "2", "3")
Now you have two choices to turn these strings to R code: parsing or creating symbols. You use the former when you expect arbitrary R code and the latter when you expect variable or column names. Can you spot the differences?
rlang::parse_exprs(c("foo", "bar()", "100"))
#> [[1]]
#> foo
#>
#> [[2]]
#> bar()
#>
#> [[3]]
#> [1] 100
rlang::syms(c("foo", "bar()", "100"))
#> [[1]]
#> foo
#>
#> [[2]]
#> `bar()`
#>
#> [[3]]
#> `100`
In your case you probably need parsing because the conditions will be R code. So let's start by parsing both vectors:
cnds <- map(cnds, rlang::parse_expr)
vals <- map(vals, rlang::parse_expr)
I'm mapping parse_expr()
instead of using the plural version parse_exprs()
because the latter can return a list that is longer than its input. For instance parse_exprs(c("foo; bar", "baz; bam"))
turns 2 strings to a list of 4 expressions. parse_expr()
returns an error if a string contains more than one expression and so is more robust in our case.
Now we can map over these two lists of LHSs and RHSs and create the formulas. One simple way is to use quasiquotation to create the formulas by unquoting each LHS and its corresponding RHS:
fs <- map2(cnds, vals, function(c, v) rlang::expr(!!c ~ !!v))
The result is a list of formula expressions that is ready to be spliced into case_when()
:
data %>% mutate(result = case_when(!!!fs))
Use rlang::qq_show()
to see exactly what the splice-unquoting is doing:
rlang::qq_show(mutate(result = case_when(!!!fs)))
#> mutate(result = case_when(condition1 ~ 1, condition2 ~2, condition3 ~ 3))