I'm hoping someone comes along with a recommended way for a function to take both bare symbols and strings as inputs since I haven't found anything that seems particularly straightforward.
One way, which seems pretty roundabout, is to convert everything (symbols or strings) to strings with rlang::as_name(). Then sym() can be used to convert the strings to symbols (as I said, roundabout
).
grouped_mean = function(data, group_var, summary_var) {
group_var = sym( rlang::as_name( enquo(group_var) ) )
summary_var = sym( rlang::as_name( enquo(summary_var) ) )
data %>%
group_by(!!group_var) %>%
summarise(mean = mean(!!summary_var))
}
Then using either strings or symbols as inputs returns the same output.
grouped_mean(mtcars, "cyl", "mpg")
# A tibble: 3 x 2
# cyl mean
# <dbl> <dbl>
#1 4 26.7
#2 6 19.7
#3 8 15.1
> grouped_mean(mtcars, cyl, mpg)
# A tibble: 3 x 2
# cyl mean
# <dbl> <dbl>
#1 4 26.7
#2 6 19.7
#3 8 15.1
Edited to add another approach
I thought there should be some way to use a conditional statement within the function. This would be based on checking whether the input was a symbol or not and then use enquo() or sym() based on that. It looks like rlang::quo_is_symbol() is the predicate symbol that can do the checking.
grouped_mean = function(data, group_var, summary_var) {
if(rlang::quo_is_symbol( enquo(group_var) ) ) {
group_var = enquo(group_var)
} else {
group_var = sym(group_var)
}
if(rlang::quo_is_symbol( enquo(summary_var) ) ) {
summary_var = enquo(summary_var)
} else {
summary_var = sym(summary_var)
}
data %>%
group_by(!!group_var) %>%
summarise(mean = mean(!!summary_var))
}