6

Consider the following two functions:

library(ggplot2)

testdata <- as.data.frame(cbind(rep(c(1, 4), each = 50), rbinom(100, 50, .5)))
names(testdata) <- c("group", "value")

plotfun1 <- function(color) {
  ggplot(data = testdata, aes(x = factor(group, levels = c(0: 4)), y = value)) + 
    geom_boxplot(color = color) 
}

plotfun2 <- function(number) {
  ggplot(data = testdata, aes(x = factor(group, levels = c(0: number)), y = value)) + 
    geom_boxplot(color = 'red') 
}

Plotfun1 works perfectly, calling

plotfun1('red') 

yields two nice red boxplots. However calling

plotfun2(4)

yields the error message:

Error in factor(group, levels = c(0:number)) : object 'number' not found

apparently in some cases ggplot is not able to 'find' the arguments of the function, and in some cases it is. What is going on here?

PS I know there is an easy work around:

plotfun3 <- function(number) {
  plotdata <- testdata
  plotdata$group <- factor(plotdata$group, levels = c(0: number))
  ggplot(data = plotdata, aes(x = group, y = value)) + 
    geom_boxplot(color = 'red') 
}

I just want to understand what is going on.)

Vincent
  • 677
  • 2
  • 7
  • 19
  • 1
    Similar to http://stackoverflow.com/q/5106782/946850, but not a duplicate. – krlmlr Jul 19 '13 at 09:38
  • Ah yes I only found the other question when posting this. Apparently the difference between the functions is that in plotfun1 we call the argument within aes? – Vincent Jul 19 '13 at 09:41
  • Yes, that's probably the reason, but the cause lies in the internals of `ggplot`. – krlmlr Jul 19 '13 at 09:43

1 Answers1

9

Capture the local environment and use it when plotting:

plotfun2 <- function(number) {
localenv <- environment()
  ggplot(data = testdata, aes(x = factor(group, levels = c(0:number)), y = value), environment = localenv ) + 
    geom_boxplot(color = 'red') 
}

plotfun2(4)
Jonas Tundo
  • 6,137
  • 2
  • 35
  • 45