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.

1 Answer 1

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.

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

1 Comment

FYI aes_ and aes_string are being deprecated in favor of tidyeval in ggplot. There was a question earlier today dealing with this

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.