aes中的局部variables

我试图在aes使用局部variables时,我与ggplot的情节。 这是我的问题归结为本质:

 xy <- data.frame(x=1:10,y=1:10) plotfunc <- function(Data,YMul=2){ ggplot(Data,aes(x=x,y=y*YMul))+geom_line() } plotfunc(xy) 

这会导致以下错误:

 Error in eval(expr, envir, enclos) : object 'YMul' not found 

看起来好像我不能在aes使用局部variables(或函数参数)。 难道是由于aes的内容在局部variables超出范围的时候被执行了吗? 我怎样才能避免这个问题(除了不使用aes内的局部variables)?

我会捕捉当地的环境,

 xy <- data.frame(x=1:10,y=1:10) plotfunc <- function(Data, YMul = 2){ .e <- environment() ggplot(Data, aes(x = x, y = y*YMul), environment = .e) + geom_line() } plotfunc(xy) 

下面是一个替代scheme,允许您通过YMulparameter passing任何值,而不必将其添加到Data data.frame或全局环境:

 plotfunc <- function(Data, YMul = 2){ eval(substitute( expr = { ggplot(Data,aes(x=x,y=y*YMul)) + geom_line() }, env = list(YMul=YMul))) } plotfunc(xy, YMul=100) 

要看看这是如何工作的,请单独尝试下面一行:

 substitute({ggplot(Data, aes(x=x, y=y*YMul))}, list(YMul=100)) 

ggplot()aes预计YMuldata数据框架内的一个variables。 尝试包括YMull

感谢@Justin: ggplot()aes似乎YMuldata数据框架中查找YMul ,如果找不到,那么在全局环境中。 我喜欢在数据框中添加这样的variables,如下所示,因为这对我来说在概念上是有意义的。 我也不必担心全局variables对函数有意想不到的后果。 但所有其他答案也是正确的。 所以,select适合你的。

 require("ggplot2") xy <- data.frame(x = 1:10, y = 1:10) xy <- cbind(xy, YMul = 2) ggplot(xy, aes(x = x, y = y * YMul)) + geom_line() 

或者,如果你想在你的例子中的function:

 plotfunc <- function(Data, YMul = 2) { ggplot(cbind(Data, YMul), aes(x = x, y = y * YMul)) + geom_line() } plotfunc(xy) 

我正在使用ggplot2,你的例子似乎与当前版本正常工作。

但是,很容易想出一些仍然会造成麻烦的变种。 我被我自己困惑的类似的行为,这就是我发现这个职位(顶部谷歌结果“ggplot如何评估variables时通过”)。 例如,如果我们将ggplot移出plotfunc:

 xy <- data.frame(x=1:10,y=1:10) plotfunc <- function(Data,YMul=2){ geom_line(aes(x=x,y=y*YMul)) } ggplot(xy)+plotfunc(xy) # Error in eval(expr, envir, enclos) : object 'YMul' not found 

在上面的变种中,“捕获本地环境”不是一个解决scheme,因为ggplot不是从函数内部调用的,只有ggplot有“environment =”参数。

但现在有一系列函数“aes_”,“aes_string”,“aes_q”,它们就像“aes”,但捕获局部variables。 如果我们在上面使用“aes_”,我们仍然得到一个错误,因为现在它不知道“x”。 但是直接引用数据很容易,解决了这个问题:

 plotfunc <- function(Data,YMul=2){ geom_line(aes_(x=Data$x,y=Data$y*YMul)) } ggplot(xy)+plotfunc(xy) # works 

你看过@wch(W. Chang)给出的解决scheme吗?

https://github.com/hadley/ggplot2/issues/743

我认为这是更好的

基本上和@baptiste是一样的,但直接在ggplot调用中包含对环境的引用

我在这里报告

 g <- function() { foo3 <- 4 ggplot(mtcars, aes(x = wt + foo3, y = mpg), environment = environment()) + geom_point() } g() # Works 

如果你在它的函数之外执行你的代码。 如果你在全局定义的YMul函数内执行代码,它就可以工作。 我不完全了解ggplot的内部工作,但这个工程…

 YMul <- 2 plotfunc <- function(Data){ ggplot(Data,aes(x=x,y=y*YMul))+geom_line() } plotfunc(xy)