0

I am producing a ggplot with many similar elements. To assist I have designed a function that produces a single element, which I plan to reuse. For example

reusable.element = function(gg, params){
    x = some.calculation(params)
    y = some.calculation(params)
    gg + geom_line(aes(x,y))
}
gg = ggplot()
gg = reusable.element(gg, params1)
gg = reusable.element(gg, params2)
print(gg)

However, R then complains that it can not find x.

As best as I can determine this appears to be due to lazy evaluation. R is trying to evaluate x only when printing the plot. For example:

x1 = c(1,1)
y1 = c(1,2)
p = ggplot() + geom_point(aes(x1,y1))
x1 = c(1)
y1 = c(3)
p = p + geom_point(aes(x1,y1))
p

Produces a plot of only one point, because x1 = c(1) overrides x1 = c(1,1).

I know I can get around this by assigning different variables names. For example:

x1 = c(1,1)
y1 = c(1,2)
p = ggplot() + geom_point(aes(eval(x1),eval(y1)))
x2 = c(1)
y2 = c(3)
p = p + geom_point(aes(x2,y2))
p

(Produces the intended plot of 3 dots). But this will significantly reduce the effectiveness of any function that produces a single plot element.

Simon.S.A.
  • 6,240
  • 7
  • 22
  • 41

1 Answers1

3

Found the answer only after writing out my entire question: Force evaluation

In short, using aes_ instead of aes forces evaluation of the aesthetic at the time it is written (preventing lazy evaluation at the time the figure is drawn, and enabling figure elements to be built within a function).

Following the comment from @camille here is an approach without using aes_. Note that you may have to update to the most recent version of tidyverse and rlang packages to get this working.

x1 = c(1,1)
y1 = c(1,2)
p = ggplot() + geom_point(aes(!!enquo(x1),!!enquo(y1)))
x1 = c(1)
y1 = c(1)
p

I think of this as enquo is evaluate'n'quote and !! as unquote. So !!enquo forces evaluation of the variable at the time it is called.

Simon.S.A.
  • 6,240
  • 7
  • 22
  • 41
  • 1
    FYI `aes_` and `aes_string` are being deprecated in favor of tidyeval in `ggplot`. There was a question [earlier today](https://stackoverflow.com/q/51658629/5325862) dealing with this – camille Aug 03 '18 at 04:39