I've been studying the "Programming with dplyr" vignette because I want to create functions that use dplyr functions. I would like to use the functions I make in both shiny applications and interactive R work. For use in shiny, I would like these functions to take string arguments and convert them to symbols using the sym function. For use in interactive sessions, I would like these functions to have the option to not have to use strings. So the functions I make will need a way to tell if certain arguments are strings or not.
I figured out a way to this this. I'm just curious if there is a better and/or more elegant way to do it.
I made a simple function, "my_summarise", as an example. It is a different version of the function "my_summarise" from the vignette. It uses tryCatch to check if the group_var argument is a string.
library(dplyr)
df <- data.frame(g1 = c(1, 1, 2, 2, 2),
g2 = c(1, 2, 1, 2, 1),
a = c(1, 5, 4, 3, 2),
b = c(3, 1, 2, 5, 4))
# df:
# g1 g2 a b
# 1 1 1 3
# 1 2 5 1
# 2 1 4 2
# 2 2 3 5
# 2 1 2 4
my_summarise <- function(df, group_var) {
is_string <- tryCatch(sym(group_var), error = function(group_var) group_var)
if ("error" %in% class(is_string)) {
group_var <- enquo(group_var)
} else {
group_var <- sym(group_var)
}
df %>% group_by(!! group_var) %>%
summarise(a = mean(a))
}
my_summarise(df, g1)
# g1 a
# 1 3
# 2 3
my_summarise(df, "g1")
# g1 a
# 1 3
# 2 3
Edit: Onyambu's answer is perfect. I just tweaked it to use a few rlang functions instead of their base equivalents.
my_summarise <- function(df, group_var) {
group_var <- enexpr(group_var)
if(!is_symbol(group_var)) group_var <- sym(group_var) # instead of is.name and as.name you can use is.symbol and as.symbol or a mixture.
group_var <- enquo(group_var)
df %>% group_by(!! group_var) %>%
summarise(a = mean(a))
}
my_summarise <- function(df, group_var) {
group_var <- substitute(group_var)
if(!is.name(group_var)) group_var <- as.name(group_var) # instead of is.name and as.name you can use is.symbol and as.symbol or a mixture.
group_var <- enquo(group_var)
df %>% group_by(!! group_var) %>%
summarise(a = mean(a))
}
You can also ignore the if
condition altogether :
my_summarise <- function(df, group_var) {
group_var<- as.name(substitute(group_var))
group_var <- enquo(group_var)
df %>% group_by(!! group_var) %>%
summarise(a = mean(a))
}
We can do this with parse_expr
my_summarise <- function(df, group_var) {
group_var <- parse_expr(quo_name(enquo(group_var)))
df %>%
group_by(!! group_var) %>%
summarise(a = mean(a))
}
-checking
my_summarise(df, g1)
# A tibble: 2 x 2
# g1 a
# <dbl> <dbl>
#1 1 3
#2 2 3
my_summarise(df, 'g1')
# A tibble: 2 x 2
# g1 a
# <dbl> <dbl>
#1 1 3
#2 2 3
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With