Making plot functions with ggplot and aes_string

Go To StackoverFlow.com

19

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?

2012-04-04 04:16
by Ed Fine
As for how to approach solving this question, I'd probably check on StackOverflow first. : - joran 2012-04-04 04:28
Also asked here: http://stackoverflow.com/questions/11028353/passing-string-variable-facet-wrap-in-ggplot-using- - Paul Lemmens 2014-01-14 11:49


17

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).

2012-04-04 04:29
by mathematical.coffee
Thanks for the clear answer. How did you figure out that facet_wrap expects a formula - Ed Fine 2012-04-04 16:40
If you look at ?facet_wrap it says facet_wrap(facets,...) and facets: formula specifying variabls to facet by - mathematical.coffee 2012-04-04 23:34


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

2012-04-04 04:28
by Marius


0

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)
2018-11-06 09:42
by Moody_Mudskipper
Ads