I want to use tidy evaluation in my function while mutating the entered variable, but can't seem to get the function to work properly.
I have read both tidy eval with e.g. mtcars %>% mutate(target := log(target)) and Tidy Evaluation not working with mutate and stringr, and they seem to suggest that there needs to be a different solution based on whether a symbol or a string is passed as an argument. But I'd prefer a general solution to this problem that works with both of these inputs.
Is there a way to do this?
function
library(magrittr)
foo <- function(data, x) {
# I know this is one solution to solve my problem
# But I want to avoid it because it creates problem if the function is to be used within a loop
# x <- rlang::ensym(x)
df <- tibble::as_tibble(dplyr::select(data, {{ x }}))
df %>% dplyr::mutate(.data = ., {{ x }} := droplevels(as.factor({{ x }})))
}
works as expected
foo(mtcars, am)
#> # A tibble: 32 x 1
#> am
#> <fct>
#> 1 1
#> 2 1
#> 3 1
#> 4 0
#> 5 0
#> 6 0
#> 7 0
#> 8 0
#> 9 0
#> 10 0
#> # ... with 22 more rows
doesn't work as expected
foo(mtcars, "am")
#> # A tibble: 32 x 1
#> am
#> <fct>
#> 1 am
#> 2 am
#> 3 am
#> 4 am
#> 5 am
#> 6 am
#> 7 am
#> 8 am
#> 9 am
#> 10 am
#> # ... with 22 more rows
P.S. In case you are curious about the issue caused in loops by the possible solution, here is a reprex:
library(magrittr)
col.name <- colnames(mtcars)
foo <- function(data, x) {
x <- rlang::ensym(x)
df <- tibble::as_tibble(dplyr::select(data, {{ x }}))
df %>% dplyr::mutate(.data = ., {{ x }} := droplevels(as.factor({{ x }})))
}
for (i in 3:length(mtcars)) {
foo(mtcars, col.name[i])
}
#> Error: Only strings can be converted to symbols