Search code examples
rggplot2dplyrmagrittr

pipe (%>%) ggplot2 like ggvis


When I integrate tables and figures in a document using knitr, adding the code makes it more reproducible and interesting.

Often a combination of dplyr and ggvis can make a plot that has relatively legible code (using the magrittr pipe operator %>).

mtcars %>%
  group_by(cyl, am) %>%
  summarise( weight = mean(wt) ) %>%
  ggvis(x=~am, y=~weight, fill=~cyl) %>%
  layer_bars()

The problem is that the ggvis plot:

ggvis

does not look quite as as pretty as the ggplot2 plot (I know, factoring of cyl):

enter image description here

However, for ggplot2 we need:

mtcars %>%
  group_by(am, cyl) %>%
  summarise( weight = mean(wt) ) %>%
  ggplot( aes(x=am, y=weight, fill=cyl) ) +
  geom_bar(stat='identity')

My problem is that this switches from %>% to + for piping. I know this is a very minor itch, but I would much prefer to use:

mtcars %>%
  group_by(am, cyl) %>%
  summarise( weight = mean(wt) ) %>%
  ggplot( aes(x=am, y=weight, fill=cyl) ) %>%
  geom_bar(stat='identity')

Is there a way to modify the behaviour of ggplot2 so that this would work?

ps. I don't like the idea of using magrittr's add() since this again make the code more complicated to read.


Solution

  • Since it would be too long to expand in the comments, and based on your answer I am not sure if you tried the bit of code I provided and it didn't work or you tried previously and didn't manage

    geom_barw<-function(DF,x,y,fill,stat){
       require(ggplot2)
       p<-ggplot(DF,aes_string(x=x,y=y,fill=fill)) + geom_bar(stat=stat)
       return(p)
    }
    library(magrittr)
    library(dplyr)
    library(ggplot2)
    
    mtcars %>%
    group_by(cyl, am) %>%
    summarise( weight = mean(wt) ) %>%
    geom_barw(x='am', y='weight', fill='cyl', stat='identity')
    

    This works for me with: dplyr_0.4.2 ggplot2_2.1.0 magrittr_1.5

    Of course geom_barw could be modified so you don't need to use the quotes anymore.

    EDIT: There should be more elegant and safer way with lazy (see the lazyeval package), but a very quick adaptation would be to use substitute (as pointed by Axeman - however without the deparse part):

     geom_barw<-function(DF,x,y,fill,stat){
        require(ggplot2)
    
        x<-substitute(x)
        y<-substitute(y)
        fill<-substitute(fill)
    
        p<- ggplot(DF,aes_string(x=x,y=y,fill=fill))
        p<- p + geom_bar(stat=stat)
        return(p)
    }