在aes内的局部变量

fab*_*abb 46 r ggplot2

aes当我用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)
Run Code Online (Sandbox Code Playgroud)

这会导致以下错误:

Error in eval(expr, envir, enclos) : object 'YMul' not found
Run Code Online (Sandbox Code Playgroud)

好像我不能使用局部变量(或函数参数)aes.可能是由于aes当局部变量超出范围后执行的内容会发生吗?我怎样才能避免这个问题(除了不使用局部变量aes)?

bap*_*ste 39

我会捕捉当地的环境,

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)
Run Code Online (Sandbox Code Playgroud)

  • 说实话,我认为它应该是默认的,不知何故.与plyr相同,当**ply没有找到其他R函数与通常的范围规则会找到的变量时,我总是深感困惑. (8认同)
  • +1 - @kohske和@baptiste.我也最喜欢这个.值得注意的是,它做了与我的解决方案不同的事情,可以看出:(1)从data.frame`xy`中删除`y = 1:10`; (2)在全球环境中加入"y <-1:10"; (3)在调用ggplot之前将`y <-10:1`放在函数体中.从本质上讲,我的解决方案允许传入选定的参数,而不会改变范围规则.你的用户完全改变了`ggplot()`的范围行为(这就是我喜欢它的原因). (2认同)

Jos*_*ien 10

这是一个替代方案,允许您通过YMul参数传递任何值,而无需将其添加到Datadata.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)
Run Code Online (Sandbox Code Playgroud)

要了解其工作原理,请单独尝试以下行:

substitute({ggplot(Data, aes(x=x, y=y*YMul))}, list(YMul=100))
Run Code Online (Sandbox Code Playgroud)


jth*_*zel 5

ggplot()aes期望YMul成为内的可变data数据帧.尝试包括YMull那里:

由于@Justin:ggplot()aes似乎已认准了YMuldata数据帧的第一个,如果没有找到,然后在全球环境.我喜欢将这些变量添加到数据框中,如下所示,因为它在概念上对我有意义.我也不必担心全局变量的变化会对功能产生意想不到的后果.但所有其他答案也是正确的.所以,请使用适合您的方式.

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()
Run Code Online (Sandbox Code Playgroud)

或者,如果您想要示例中的函数:

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

plotfunc(xy)
Run Code Online (Sandbox Code Playgroud)

  • `YMul`不必是data.frame的一部分.它只需要在评估`ggplot`对象的范围内定义,它是全局的而不是函数. (2认同)