Reputation: 1897
cars %>%
group_by(cyl) %>%
summarise_each(funs(mean(., na.rm = TRUE),
min(., na.rm = TRUE),
max(., na.rm = TRUE),
sd(., na.rm = TRUE)),
mpg, wt)
I want to turn the above code into a function, where the dataframe (cars) and the column (cyl) are arguments. How can I do this in R?
I tried the following below but this does not evaluate
plot_cars <- function (df, col) {
df %>%
group_by(col) %>%
summarise_each(funs(mean(., na.rm = TRUE),
min(., na.rm = TRUE),
max(., na.rm = TRUE),
sd(., na.rm = TRUE)),
mpg, wt)
}
plot_cars(cars,"cyl")
Upvotes: 0
Views: 171
Reputation: 887741
If we need to pass a string, convert to sym
and evaluate. But, to be more flexible, it is better to convert to ensym
so that it can be take both unquoted and quoted
library(dplyr)#1.0.0
plot_cars <- function (df, col) {
col <- ensym(col)
df %>%
group_by(!!col) %>%
summarise(across(c(mpg, wt),
list(mean = ~ mean(., na.rm = TRUE),
min = ~ min(., na.rm = TRUE),
max = ~ max(., na.rm = TRUE),
sd = ~ sd(., na.rm = TRUE))))
}
plot_cars(mtcars,"cyl")
# A tibble: 3 x 9
# cyl mpg_mean mpg_min mpg_max mpg_sd wt_mean wt_min wt_max wt_sd
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 4 26.7 21.4 33.9 4.51 2.29 1.51 3.19 0.570
#2 6 19.7 17.8 21.4 1.45 3.12 2.62 3.46 0.356
#3 8 15.1 10.4 19.2 2.56 4.00 3.17 5.42 0.759
plot_cars(mtcars, cyl)
# A tibble: 3 x 9
# cyl mpg_mean mpg_min mpg_max mpg_sd wt_mean wt_min wt_max wt_sd
# <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
#1 4 26.7 21.4 33.9 4.51 2.29 1.51 3.19 0.570
#2 6 19.7 17.8 21.4 1.45 3.12 2.62 3.46 0.356
#3 8 15.1 10.4 19.2 2.56 4.00 3.17 5.42 0.759
Upvotes: 1
Reputation: 32558
foo = function(d, grp, ...) {
d %>%
group_by_at(grp) %>%
summarise_at(c(...), funs(mean(., na.rm = TRUE),
min(., na.rm = TRUE),
max(., na.rm = TRUE),
sd(., na.rm = TRUE)))
}
foo(mtcars, "cyl", "mpg", "wt")
Upvotes: 0
Reputation: 798
This is a similar solution using lazy evaluation.
plot_cars <- function (df, ...) {
df %>%
group_by_(.dots = lazyeval::lazy_dots(...)) %>%
summarise_each(funs(mean(., na.rm = TRUE),
min(., na.rm = TRUE),
max(., na.rm = TRUE),
sd(., na.rm = TRUE)),
mpg, wt)
plot_cars(mtcars, cyl)
}
If you'd like to read more about this, follow this link: https://medium.com/optima-blog/writing-your-own-dplyr-functions-a1568720db0d
Upvotes: 0
Reputation: 39613
You can try this:
plot_cars <- function (df,...) {
dots <- enquos(...)
df %>%
group_by(vars(!!!dots)) %>%
summarise_each(funs(mean(., na.rm = TRUE),
min(., na.rm = TRUE),
max(., na.rm = TRUE),
sd(., na.rm = TRUE)),
mpg, wt)
}
plot_cars(mtcars,cyl)
# A tibble: 1 x 9
`vars(cyl)` mpg_mean wt_mean mpg_min wt_min mpg_max wt_max mpg_sd wt_sd
<quos> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 cyl 20.1 3.22 10.4 1.51 33.9 5.42 6.03 0.978
Upvotes: 0