Using a custom function to run dyplr and ggplot commands not rendering the way I want.

In my actual code, I made a plot for a df exactly the way I want with a lot of commands. I then need to make five more plots with the same df, but I need to use different columns from that df.

I'm trying to avoid the copy and paste method and manually changing things. So I tried to create a custom function, but I'm not getting it to work right.

Below demonstrates my issue with mtcars.
The first chunk creates the plot by first using dplyr to summarize the data and then throw it in a plot. As a new user, I'm only allowed one image in my post, so you'll have to run the code to see the plot I'm trying to reproduce in my function.

The next section is trying to turn that plot command into a function, but when I use the function, you can see the plot is not coming out right.

I can't seem to find the solution from all of my searches and trial and error, so any help will be greatly appreciated. My system info is a the bottom.

Thanks in advance for the help.

library(tidyverse)

mtcars %>%
  group_by(cyl,hp) %>%
  summarize(mpg = sum(mpg)) %>%
  ggplot(aes(x = cyl, y = hp, size = mpg)) +
  geom_point()

plot_func <- function(df,xcol,ycol){
  df %>%
    group_by_(xcol,ycol) %>%
    summarize(mpg = sum(mpg)) %>%
    ggplot(aes(x=xcol,y = ycol, size = mpg)) +
    geom_point()
}

plot_func(mtcars,"cyl","hp")

Created on 2019-01-24 by the reprex package (v0.2.0).

session info:
R version 3.5.1 (2018-07-02)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows >= 8 x64 (build 9200)
OS: Windows 10 Enterprise

Here is the plot I'm trying to use a function to create.

library(tidyverse)

mtcars %>%
  group_by(cyl,hp) %>%
  summarize(mpg = sum(mpg)) %>%
  ggplot(aes(x = cyl, y = hp, size = mpg)) +
  geom_point()

Created on 2019-01-24 by the reprex package (v0.2.0).

Take a look into tidy evaluation a.k.a NSE

1 Like

Thanks so much @andresrcs , that was the missing piece of the puzzle I wasn't figuring out. So here is what the function looks like that work.

library(tidyverse)

plot_func <- function(df,xcol,ycol){
  xcol <- enquo(xcol)
  ycol <- enquo(ycol)
  df %>%
    group_by_(xcol,ycol) %>%
    summarize(mpg = sum(mpg)) %>%
    ggplot(aes(!!xcol,!!ycol, size = mpg)) +
    geom_point()
}

plot_func(mtcars,cyl,hp)

Created on 2019-01-24 by the reprex package (v0.2.0).

For anyone stumbling upon this in the future trying to use dplyr in a customer function, make sure you notice that there needs to be an extra underscore after group_by in the function, in case you hadn't discovered that.

1 Like

I don't think you need the extra underscore in group_by() (and I think that syntax is being slowly removed from the package); you can use the same !! syntax inside group_by() (as you have done inside aes()).

2 Likes

If your question's been answered (even by you!), would you mind choosing a solution? It helps other people see which questions still need help, or find solutions if they have similar problems. Here’s how to do it:

1 Like

And in fact, you can omit the use of enquo() entirely using the "pass the dots" idea (although only for two variables):

plot_func2 <- function(df, ...){
  df %>%
    group_by(...) %>%
    summarize(mpg = sum(mpg)) %>%
    ggplot(aes(..., size = mpg)) +
    geom_point()
}

plot_func2(mtcars,cyl,hp)

This was discussed at rstudio::conf, and I'd really recommend watching the tidyeval material from the Friday sessions once they get posted online!

Thanks for the information @jim89. I'll take a look.

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.

If you have a query related to it or one of the replies, start a new topic and refer back with a link.