6

I want to arrange N ggplot (each one is facetted) on a grid with grid.arrange.

library(tidyverse)
library(ggplot2)
library(gridExtra)


plots <- lapply(unique(mtcars$cyl), function(cyl) {
    data <- mtcars %>% filter(cyl == cyl)
    ggplot(data, aes(x=mpg, y=hp))+
        geom_point(color = "blue")+
        facet_wrap(.~carb)}) %>% 
    do.call(grid.arrange, .)
do.call(grid.arrange, plots )

The problem is that all the plots are based on the entire dataset and they render the same plot, while they shuold be different as I filter them in line

data <- mtcars %>% filter(cyl == cyl).

Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
giannic
  • 91
  • 5
  • See also [How can I obtain an 'unbalanced' grid of ggplots?](https://stackoverflow.com/questions/8112208/how-can-i-obtain-an-unbalanced-grid-of-ggplots) – markus May 23 '19 at 07:36
  • 2
    Scoping issue. Just use `data <- mtcars[mtcars$cyl == cyl,]`. If you must use `dplyr` you need to tell `filter` from where it should take the second `cyl`. Or just use a different symbol for the parameter of your anonymous function. – Roland May 23 '19 at 07:38

3 Answers3

6

filter deals with cyl too letteral and treated as a string, therefore cyl==cyl is TRUE for the entire dataset. You can solve this by unquote cyl using !! or use another variable name in the function e.g. x.

#Option 1
data <- mtcars %>% filter(cyl == !!cyl)
#Option 2
... function(x) {
    data <- mtcars %>% filter(cyl == x)
...
A. Suliman
  • 12,923
  • 5
  • 24
  • 37
4

Here is a tidyverse approach

library(tidyverse)

group_plots <- mtcars %>%
                 group_split(cyl) %>%
                 map(~ggplot(., aes(x = mpg, y = hp))+
                 geom_point(color = "blue") +
                 facet_wrap(.~carb))

do.call(gridExtra::grid.arrange, group_plots)

enter image description here

Ronak Shah
  • 377,200
  • 20
  • 156
  • 213
3

Try use split() first:

library(tidyverse)
library(gridExtra)

l <- split(mtcars, mtcars$cyl) # divide based on cyl in a list

plots <- lapply(l, function(x) {
  ggplot(x, aes(x=mpg, y=hp)) +
    geom_point(color = "blue") +
    facet_wrap(.~carb)
}) # call lapply() on each element

do.call(grid.arrange, plots)  

enter image description here

RLave
  • 8,144
  • 3
  • 21
  • 37