R aes中的局部变量
当我用ggplot绘图时,我试图在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中
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
xyYMul
不必是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.framexy
中删除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