R跨间接保留符号名称

时间:2018-07-23 17:37:53

标签: r ggplot2

我像这样画了一个图...

ggplot(my_data, aes(x = ttd, y = aval)) +
  theme_bw() +
  geom_point(alpha = 0.25)

这给了我一个不错的图,以ttdaval作为我的坐标轴标签。我喜欢它如何使用参数名称作为默认标签。

但是,我有很多这样的图,我想将其抽象到我自己的 function 中。但是我似乎无法从函数内部进行绘制。这是我尝试过的:

bw_plot <- function(data, x_, y_) {
  ggplot(data, aes(x = substitute(x_), y = substitute(y_))) +
    theme_bw() +
    geom_point(alpha = 0.25)
}

bw_plot(my_data, ttd, aval)

但是我得到这个错误:

Error in (function (..., row.names = NULL, check.rows = FALSE, check.names = TRUE, : object 'x_' not found

我只是想将符号从我的bw_plot函数向下传递到ggplot中。 如何获取我的实际列名?

((我也尝试将列名作为字符串传递,并在它们上调用as.name,但是得到的结果相同。

2 个答案:

答案 0 :(得分:1)

substitute将正确地“引用”您的参数x_y_。但是,aes将在内部应用第二轮“引用”,这是导致您出错的原因。将呼叫传递给substitute时,需要取消对aes调用结果的引用。可以使用!!中的rlang运算符来完成。

library( ggplot2 )
library( rlang )
bw_plot <- function( .data, x_, y_ )
{
  xsym <- ensym(x_)
  ysym <- ensym(y_)
  ggplot( .data, aes(x = !!xsym, y = !!ysym) ) +
    theme_bw() +
    geom_point(alpha=0.25)
}

请注意,要使用的正确函数是rlang::ensym,而不是substitute,因为您要捕获单个符号(列名)。另外,我建议不要命名您的参数data,以避免与内置函数发生名称冲突。

这里是示例用法:bw_plot( mtcars, mpg, wt ) enter image description here

答案 1 :(得分:0)

可接受的答案适用于ggplot2版本2.2.1.9000及更高版本。对于2.2.1及更低版本,aes使用的非标准评估似乎无法实现。取而代之的是,我必须使用aes_来提供“转义阴影”,使我能够按预期向函数提供符号。解决方法如下:

bw_plot <- function(data, x_, y_) {
  ggplot(data, aes_(x = substitute(x_), y = substitute(y_))) +
    theme_bw() +
    geom_point(alpha = 0.25)
}

bw_plot(my_data, ttd, aval)