由于延迟评估,因此无法在ggplot中重用变量名

时间:2018-08-03 04:17:21

标签: r ggplot2 lazy-evaluation

我正在制作具有许多相似元素的ggplot。为了帮助我,我设计了一个产生单个元素的函数,我打算将其重用。例如

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)

但是,R然后抱怨找不到x

据我所知,这似乎是由于懒惰的评估。 R仅在打印绘图时才尝试评估x。例如:

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

仅产生一个点的图,因为x1 = c(1)会覆盖x1 = c(1,1)

我知道我可以通过分配不同的变量名称来解决此问题。例如:

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

(产生3个点的预期图形)。但这会大大降低产生单个绘图元素的任何函数的有效性。

1 个答案:

答案 0 :(得分:2)

仅在写下我的整个问题后才找到答案:Force evaluation

简而言之,使用aes_代替aes会在撰写时强制评估美学(防止在绘制图形时进行惰性评估,并允许在其中构建图形元素函数)。

以下@camille的注释是一种不使用aes_的方法。请注意,您可能必须更新到tidyverserlang软件包的最新版本,才能正常工作。

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

我认为这是因为enquo被评估为'n'quote,!!为未引用。因此!!enquo会在变量被调用时强制对其进行求值。