R aes中的局部变量

R aes中的局部变量,r,ggplot2,R,Ggplot2,当我用ggplot绘图时,我试图在aes中使用局部变量。这就是我的问题的本质: 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) 似乎我不能在aes中使用局部变量(或函数参数)。当局部变量超出范围时,是否会因为执行aes的内容而发生这种情况?如何避免此问题(除了不在aes中

当我用ggplot绘图时,我试图在
aes
中使用局部变量。这就是我的问题的本质:

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)
似乎我不能在
aes
中使用局部变量(或函数参数)。当局部变量超出范围时,是否会因为执行
aes
的内容而发生这种情况?如何避免此问题(除了不在
aes
中使用局部变量之外)?

ggplot()
aes
期望
YMul
成为
数据帧中的变量。尝试在此处包含
YMull

感谢@Justin:
ggplot()
aes
似乎首先在
数据
数据框中查找
YMul
,如果未找到,则在全局环境中查找。我喜欢将这些变量添加到数据框架中,如下所示,因为这在概念上对我来说是有意义的。我也不必担心全局变量的更改会给函数带来意外的后果。但所有其他答案也都是正确的。所以,选择适合你的

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()
require(“ggplot2”)

xy如果在函数之外执行代码,则代码将正常工作。如果您在全局定义了
YMul
的函数中执行代码,则它可以工作。我不完全理解
ggplot
的内部工作原理,但这是可行的

YMul <- 2

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

plotfunc(xy)

YMul这里有一个替代方法,允许您通过
YMul
参数传入任何值,而无需将其添加到
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)

我会捕捉当地的环境

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)

xy你看过@wch(W.Chang)给出的解决方案了吗

我认为这是最好的

本质上类似于@baptiste,但在对ggplot的调用中直接包含对环境的引用

我在这里报告

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

g()
# Works

g我使用的是ggplot2,您的示例在当前版本中似乎运行良好

然而,很容易找到仍然带来麻烦的变体。我自己也被类似的行为弄糊涂了,这就是我找到这篇文章的原因(谷歌“ggplot传递时如何计算变量”的最佳结果)。例如,如果将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

xy
YMul
不必是data.frame的一部分。它只需要在计算
ggplot
对象的范围内定义,该范围是全局的,而不是在函数中。@Justin:谢谢。我没有意识到这一点。有趣的是,
ggplot()
似乎首先在数据帧中查找
YMul
,如果在全局环境中找不到,显然会跳过函数的参数。我没有找到任何关于
ggplot()
如何搜索名称空间的信息,但我也没有仔细查找。这是一个更容易记住和键入的选项。如果您的数据帧有10亿行,可能不太好,但在其他情况下很方便。+1谢谢!我知道有办法做到这一点,但从来没有花时间去解决这个问题。“很酷!”贾斯汀——很高兴这有帮助。我从来没有花时间去整理ggplot基于原型的范围界定是如何工作的。例如,我刚刚在
aes()
调用中放置了一个
browser()
语句,在键入
sys.frames()
后,我得到了23个环境的列表,其中没有一个(?)似乎允许直接访问
YMul
的值。嗯,是的。。。我无法理解。我对Kohske有些好感,他打破了新版本,这对我来说是完全不可理解的!总有一天我想了解proto…@Justin和Josh:这里有一个关于github的相关讨论:似乎已经讨论过但没有实现。+1对于bquote也一样:eval(bquote(ggplot(Data,aes(x=x,y=y*(YMul)))+geom_line()。我认为这可能是官方(但没有文档)的方式。老实说,我认为它确实应该是默认的,以某种方式与plyr一样,当**ply没有找到其他具有常规作用域规则的R函数会找到的变量时,我总是感到非常困惑。+1--@kohske和@baptiste。我也最喜欢这个。但是值得注意的是,它与我的解决方案有所不同,如下所示:(1)从data.frame
xy
中删除
y=1:10
;(2) 放置<代码>y@JoshO”“是的。我还坚持aes()的参数应始终来自data.frame的规则,在这种情况下,我可能只想从周围环境中挑选像YMu这样的参数。这实际上是直截了当的,但我同意它应该是默认值。我认为ggplot中的aes就像一个闭包,保留周围所有使用过的对象;显然不是。非常感谢。这是@baptiste答案的副本,IMO不必要地使用了另一个例子,因为OP提供了一个可复制的例子。我建议删除(或者用你链接的Github问题评论baptiste的)。我认为,因为它仍然希望你传递Ymul,但你只给plotfunc(xy)不正确,它应该使用默认值。我正在运行上面的代码,没有得到任何错误(2017年10月23日),
ggplot2
是否有更新来解释为什么现在可以这样做?
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)
g <- function() {
  foo3 <- 4
  ggplot(mtcars, aes(x = wt + foo3, y = mpg),
         environment = environment()) +
    geom_point()
}

g()
# Works
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
plotfunc <- function(Data,YMul=2){
  geom_line(aes_(x=Data$x,y=Data$y*YMul))
}
ggplot(xy)+plotfunc(xy)
# works