I would like to use a switch statement within dplyr's mutate. I have a simple function that performs some operations and assigns alternative values via switch, for example:
convert_am <- function(x) {
x <- as.character(x)
switch(x,
"0" = FALSE,
"1" = TRUE,
NA)
}
This works as desired when applied to scalars:
>> convert_am(1)
[1] TRUE
>> convert_am(2)
[1] NA
>> convert_am(0)
[1] FALSE
I would like to arrive at equivalent results via mutate call:
mtcars %>% mutate(am = convert_am(am))
This fails:
Error in
mutate_impl(.data, dots): Evaluation error: EXPR must be a length 1 vector.
I understand that this is because values passed to switch ar not single, as in example:
convert_am(c(1,2,2))Error inswitch(x, 0 = FALSE, 1 = TRUE, NA): EXPR must be a length 1 vector
Vectorization
Attempt to vectorize also yield the desired results:
convert_am <- function(x) {
x <- as.character(x)
fun_switch <- function(x) {
switch(x,
"0" = FALSE,
"1" = TRUE,
NA)
}
vf <- Vectorize(fun_switch, "x")
}
>> mtcars %>% mutate(am = convert_am(am))
Error in mutate_impl(.data, dots) :
Column `am` is of unsupported type function
Notes
- I'm aware of
case_whenin dplyr and I'm not interested in using it, I'm only interested in makingswitchwork inside mutate - Ideal solution would allow for further expansion to use
mutate_atwith variables passed as.
convert_aminstead offun_switch? Try egmtcars %>% mutate(am = Vectorize(convert_am)(am)). What you've done there returns a functionvf(see?Vectorize) - konvasdoand not vectorize at all. I would try to usecase_whensince that's what it's there for but suppose you have your reasons for not wanting to use it :) - konvas