0
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")

4 Answers 4

1

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
Sign up to request clarification or add additional context in comments.

Comments

0

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

5 Comments

I'm getting an errror "cant splice an object of type 1closure1 because it is not a vector"
Actually my error is Must subbset columns with a valid subscript vector. x subscript has the wrong type 'quosures' it must be numeric or character
@Eisen are you using mtcars or cars? Maybe is your data. Let me know if it worked. It worked for me, maybe try a new session.
This was actually a toy example. I'm using a different dataset which I cannot post here. It's failling at a select statement, can I use vars(!!!dots) within a select?
@Eisen If you use in select then the rest of pipes will not work. Try to at least include dummy data so that we can help you.
0

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

Comments

0
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")

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.