Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Metaprogramming with ggplot2

I've been trying to cut down on the amount of copying and pasting required to make a large number of charts with slightly differing functions / slices of the data.

Here is a simplified example of what I am trying to do:

test <- data.table(a=c("x","y"), b=seq(1,3), c=rnorm(18))

fixedSlices <- function(input, rowfacet, colfacet, metric){
  calc <- substitute(metric)
  bygroup<-c(rowfacet,colfacet)
  aggregates <- input[,eval(calc),by=bygroup]

  ggplot(aggregates) + geom_point(stat="identity") + aes(x="", y=V1) + facet_grid(a ~ b)
}
fixedSlices(test, "a", "b", mean(c)) #works

dynamicSlices <- function(input, rowfacet, colfacet, metric){
  calc <- substitute(metric)
  bygroup<-c(rowfacet,colfacet)
  aggregates <- input[,eval(calc),by=bygroup]

  ggplot(aggregates) + geom_point(stat="identity") + aes(x="", y=V1) + facet_grid(eval(rowfacet) ~ eval(colfacet))
}
dynamicSlices(test, "a", "b", mean(c))
#Error in layout_base(data, rows, drop = drop) : At least one layer must contain all variables used for facetting

I'd like to be able to have my function accept the variables to facet by as parameters. I was able to get this to work with respect to grouping by the columns in the data.table, but can't facet by them in ggplot.

like image 732
Rob Donnelly Avatar asked Dec 20 '22 23:12

Rob Donnelly


2 Answers

You should use

... + facet_grid(as.formula(sprintf("%s ~ %s", rowfacet, colfacet))

in your code.

like image 67
Victor K. Avatar answered Jan 17 '23 03:01

Victor K.


facet_grid() takes a formula object, and you can create a formula object from a string with as.formula(). So you should be able to do something like:

 facet_grid(as.formula(paste(rowfacet, "~", colfacet)))
like image 29
wch Avatar answered Jan 17 '23 04:01

wch