I want to combine dplyr and ggplot within one function using piping and struggling with some issues now.
Here is the first easy one which is working. Function which takes a dataframe and filters by a specified column and value.
foo <- function(df, y, t = 4){
tmp <- df %>%
filter(!!enquo(y) > t)
ggplot(tmp, aes_(substitute(y))) +
geom_histogram()
}
foo(mtcars, cyl)
Now I'm trying to pipe directly to the ggplot function...gives an error
foo <- function(df, y, t=4){
df %>%
filter(!!enquo(y) > t) %>%
ggplot(aes_(substitute(y))) +
geom_histogram()
}
foo(mtcars, cyl)
Error in FUN(X[[i]], ...) : object 'cyl' not found In addition: Warning message: In FUN(X[[i]], ...) : restarting interrupted promise evaluation
and the last one. How to add a facet?
foo <- function(df, y, gr, t=4){
df %>%
filter(!!enquo(y) > t) %>%
ggplot(aes_(substitute(y))) +
geom_histogram() +
facet_grid(~gr)
}
foo(mtcars, y= cyl, gr= vs)
The second issue can be solved using aes_q instead of aes_ & substitute. Source
foo <- function(df, y, gr, t=4){
y <- enquo(y)
df %>%
filter(!!y > t) %>%
ggplot(aes_q(y)) +
geom_histogram()
}
foo(mtcars, cyl)
Using ggplot2_2.2.1
ggplot2 v3.0.0 released in July 2018 supports !! (bang bang), !!!, and :=.
facet_wrap() and facet_grid() support vars() inputs. The first two arguments of facet_grid() become rows and cols. facet_grid(vars(cyl), vars(am, vs)) is equivalent to facet_grid(cyl ~ am + vs) and facet_grid(cols = vars(am, vs)) is equivalent to facet_grid(. ~ am + vs).
So your example can be modified as follow:
library(rlang)
library(tidyverse)
foo <- function(df, y, gr, t=4) {
y <- enquo(y)
gr <- enquo(gr)
df %>%
filter(!!y > t) %>%
ggplot(aes(!!y)) +
geom_histogram() +
facet_grid(cols = vars(!!gr))
}
foo(mtcars, y= cyl, gr= vs)
#> `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.

Created on 2018-04-04 by the reprex package (v0.2.0).
@Tung's answer can be simplified using {{ syntax. https://rlang.r-lib.org/reference/quasiquotation.html
library(rlang)
library(dplyr)
library(ggplot2)
foo <- function(df, y, gr, t = 4) {
df %>%
filter({{ y }}> t) %>%
ggplot(aes({{ y }})) +
geom_histogram() +
facet_grid(cols = vars({{ gr }}))
}
foo(mtcars, y = cyl, gr = vs)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With