由于惰性评估,无法在 ggplot 中重用变量名
Unable to reuse variable names in ggplot due to 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 个点的预期图)。但这将显着降低任何生成单个绘图元素的函数的有效性。
写完我的整个问题后才找到答案: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
是 evaluate'n'quote 而 !!
是 unquote。因此 !!enquo
强制在调用变量时对其求值。
我正在制作一个包含许多相似元素的 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 个点的预期图)。但这将显着降低任何生成单个绘图元素的函数的有效性。
写完我的整个问题后才找到答案: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
是 evaluate'n'quote 而 !!
是 unquote。因此 !!enquo
强制在调用变量时对其求值。