23

In Hadley Wickham's ggplot2 book in chapter 10.3, he alludes to making plot functions. I want to make many similar plots that use faceting, but I cannot refer to a column. If all my references are in aesthetics then I can use aes_string and everything works. Facet_wrap seems not to have an analogue.

library(ggplot2)
data(iris)

This is the plot I want to functionalize.

pl.flower1 <- ggplot(data=iris, 
                    aes_string(x='Sepal.Length', y='Sepal.Width', color='Petal.Length')) +
                                 geom_point() +facet_wrap(~Species)

This works if I do not facet.

flowerPlot <- function(dat, sl, sw, pl, sp){
  ggplot(data=dat, aes_string(x=sl, y=sw, color=pl)) + geom_point()
}
pl.flower2 <- flowerPlot(iris, sl='Sepal.Length', sw='Sepal.Width', pl='Petal.Length')

What should "sp" be two lines below? A formula, a string? Maybe the whole aproach is wrong.

flowerPlotWrap <- function(dat, sl, sw, pl, sp){
      ggplot(data=dat, aes_string(x=sl, y=sw, color=pl)) + geom_point() +facet_wrap(sp)
    }
    pl.flower3 <- flowerPlotWrap(iris, sl='Sepal.Length', sw='Sepal.Width', pl='Petal.Length', sp= ?????)

In addition to an answer I would love pointer on how anyone approaches this problem?

2

3 Answers 3

22

facet_wrap expects a formula as its first argument, so I'd just coerce it with as.formula, and feed in my sp as a string:

flowerPlotWrap <- function(dat, sl, sw, pl, sp){
      ggplot(data=dat, aes_string(x=sl, y=sw, color=pl)) + 
      geom_point() +facet_wrap(as.formula(sp)) # note the as.formula
}
pl.flower3 <- flowerPlotWrap(iris, sl='Sepal.Length', 
                             sw='Sepal.Width', pl='Petal.Length', 
                             sp= '~Species')

Alternatively if my formula was always going to look like ~[columnname], I could just build that in to flowerPlotWrap and pass in the column name:

flowerPlotWrap <- function(dat, sl, sw, pl, sp){
      ggplot(data=dat, aes_string(x=sl, y=sw, color=pl)) + 
      geom_point() +facet_wrap(as.formula(sprintf('~%s',sp)))
}
pl.flower3 <- flowerPlotWrap(iris, sl='Sepal.Length', 
                             sw='Sepal.Width', pl='Petal.Length', 
                             sp= 'Species')

(kudos to the reproducible example in your question! If everyone asked questions as well as that they'd get answers much quicker).

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for the clear answer. How did you figure out that facet_wrap expects a formula?
If you look at ?facet_wrap it says facet_wrap(facets,...) and facets: formula specifying variabls to facet by.
5

Here are some alternatives using new features from ggplot2 V3.0.0

Using strings :

flowerPlot <- function(dat, sl, sw, pl, sp){
  ggplot(data=dat, aes(x=!!ensym(sl), y=!!ensym(sw), color=!!ensym(pl))) + 
    geom_point() +
    facet_wrap(eval(expr(~!!ensym(sp))))
}

flowerPlot(iris, sl='Sepal.Length', sw='Sepal.Width', pl='Petal.Length', sp = 'Species')

Using names :

flowerPlot2 <- function(dat, sl, sw, pl, sp){
  ggplot(data=dat, aes(x=!!enquo(sl), y=!!enquo(sw), color=!!enquo(pl))) + 
    geom_point() +
    facet_wrap(eval(expr(~!!enquo(sp))))
}

flowerPlot2(iris, sl= Sepal.Length, sw=Sepal.Width, pl=Petal.Length, sp = Species)

Comments

1

Your function worked fine for me unmodified if I just used sp='Species', i.e. the name of the variable you want to facet by.

flowerPlotWrap(iris, sl='Sepal.Length', sw='Sepal.Width', pl='Petal.Length', sp='Species')

enter image description here

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.