2016-03-04 63 views
5

当我尝试将参数传递到stat_summary中的round函数时(即使类似的代码使用,说,geom_text)。这里有一个例子:ggplot2:stat_summary在尝试传递函数参数作为参数时抛出错误,而不是硬编码

# Fake data 
set.seed(5) 
dat = data.frame(group=rep(c("A","B"),each=10), val=rnorm(20)) 

我们将尝试使用参数,设定位小数值标签的数量,而不是硬编码:

places = 2 

ggplot(dat, aes(group, val)) + 
    stat_summary(fun.y=mean, geom="text", aes(label=round(..y.., places))) 

错误的eval(表达式,envir,enclos):找不到对象“地方”

但是,以下两个示例可以正常工作。

ggplot(dat, aes(group, val)) + 
    stat_summary(fun.y=mean, geom="text", aes(label=round(..y.., 2))) 

ggplot(dat, aes(group, val)) + 
    geom_text(aes(label=round(val, places))) 

我试图写一个ggplot函数时遇到了这个问题。起初我认为这个问题涉及ggplot没有从函数环境中获取参数,但上面的例子表明这不是问题。为了完整起见,下面是该函数的简单示例以及错误消息。如果我将数字参数硬编码为round,而不是尝试通过places参数,则该函数可以正常工作。

pp1 = function(data, group, var, places=2, e=1.5) { 

    ggplot(data, aes_string(group, var)) + 
    geom_boxplot() + 
    stat_summary(fun.y=mean, geom="text", aes(label=round(..y.., places))) + 
    scale_y_continuous(limits = e * range(data[,var])) 

} 

pp1(dat, "group","val") 

错误的eval(表达式,ENVIR,enclos):对象“地方”未找到

,我希望能找到我是否做错了什么以及我如何获得理想的行为。

我正在运行R 3.2.3和ggplot2 2.1.0在OS X 10.10.5上。

+1

它看起来像一个NSE问题。你可以通过调用'eval(代替(... ggplot code ...,list(places = places)))'来躲避它,尽管可能有更好的方法。 – alistaire

+1

工作。请添加它作为答案。你知道为什么它发生在'stat_summary'内部而不是在其他地方? – eipi10

+0

我不确定;这是关于'aes'中的NSE如何工作的。也许它会被'..y..'打开?有一个名为'aes_'的SE版本,但我不知道如何让'..y..'参数在其中工作。我会在上面发布一个答案,我会在第二个答案中找到其他答案。 – alistaire

回答

2

aes使用non-standard evaluation,因此会尝试在您提供的data参数内评估places。但是,它的NSE会有所不同,具体取决于您传递的内容。

绕过NSE的典型方法是substitute,它代替了代码中的值。然后,您可以使用eval运行代码:

eval(substitute(ggplot(dat, aes(group, val)) + 
        stat_summary(fun.y=mean, geom="text", aes(label=round(..y.., places))), 
       list(places = places))) 

预期其工作原理:

plot with labels

哈德利还提供了aes几个SE版本:aes_aes_qaes_string,这可能让你避免使用substitute,但我无法评估..y..。 (如果有人知道如何构建它,评论和我会更新。)

哈德利还创建了lazyeval package,这对管理NSE很有用。

相关问题