我正在制作具有许多相似元素的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个点的预期图形)。但这会大大降低产生单个绘图元素的任何函数的有效性。
答案 0 :(得分:2)
仅在写下我的整个问题后才找到答案:Force evaluation
简而言之,使用aes_
代替aes
会在撰写时强制评估美学(防止在绘制图形时进行惰性评估,并允许在其中构建图形元素函数)。
以下@camille的注释是一种不使用aes_
的方法。请注意,您可能必须更新到tidyverse
和rlang
软件包的最新版本,才能正常工作。
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
会在变量被调用时强制对其进行求值。