!!! ggplot2 geom_point() 函数的(拼接运算符)

!!! (splice operator) for ggplot2 geom_point() function

我在用!!! (拼接 operator/big bang 运算符)为 ggplot2::geom_point() 函数,它失败了。有人可以指出这段代码有什么问题吗?以下代码尝试从字符向量执行 ggplot2 函数。

library(rlang)
library(ggplot2)

data(mtcars)
data = mtcars

assoc = c( "cyl" , "hp" )
names(assoc) = c("x", "y")
assoc_lang = rlang::parse_exprs(assoc)
gg = ggplot2::ggplot(data, ggplot2::aes( ,, !!! assoc_lang )) # This works

params = c( "10", "\"black\"" )
names(params) = c("size", "colour" )
params_lang = rlang::parse_exprs(params)
gg = gg + ggplot2::geom_point( !!! params_lang ) # This fails

plot(gg)
Error in !params_lang : invalid argument type
Calls: <Anonymous> -> layer
Execution halted

(注) 下面的代码是一个交互方式的等效代码,它显示了我在上面的代码中想要做的事情。

library(ggplot2)

data(mtcars)
data = mtcars

gg = ggplot2::ggplot(data, ggplot2::aes( x = cyl , y = hp ))
gg = gg + ggplot2::geom_point( size = 10, colour = "black")
plot(gg)

这些元编程运算符,包括 {{…}}!!!!! 仅适用于准引用函数。也就是说,其参数明确支持整洁评估的函数。通常,此类功能会在其文档中明确提及准引用支持。

在这些函数中有 ggplot2::aes,因为它通常对其参数使用非标准评估。但是其他“ggplot2”函数(包括 ggplot2::geom_point)对其参数执行标准评估,因此不支持任何这些伪运算符。

如果你想动态构造一个调用这个函数,你需要走常规路线,例如通过 (base R) do.call, 或 ('rlang') exec (或者,手动,通过 call + eval/call2 + eval_tidy).

Konrad 出色地解释了函数失败的原因。我只想记下 rlang::inject(),它允许您向任何函数引入准引用/非标准评估:

gg = gg + rlang::inject(ggplot2::geom_point( !!! params_lang ))

plot(gg)   # Now works

附带说明一下,您的“这行得通”示例实际上是对 .

的非常优雅的回答