ggplot2:stat_summary在尝试将函数参数作为参数传递时抛出错误,而不是硬编码

eip*_*i10 5 r parameter-passing ggplot2

当我尝试将一个参数传递给round函数时,我收到一个错误stat_summary(即使类似的代码也适用于,比方说geom_text).这是一个例子:

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

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

places = 2

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

eval中的错误(expr,envir,enclos):找不到对象'places'

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

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

我在尝试编写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")
Run Code Online (Sandbox Code Playgroud)

eval中的错误(expr,envir,enclos):找不到对象'places'

我希望了解我是否做错了什么以及我如何能够获得理想的行为.

我在OS X 10.10.5上运行R3.2.3和ggplot22.1.0.

ali*_*ire 2

aes使用非标准评估,因此将尝试在您给出的参数places内进行评估。data不过,它的 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)))
Run Code Online (Sandbox Code Playgroud)

其按预期工作:

带标签的绘图

aesHadley 还提供了: aes_aes_q、 和 的几个 SE 版本aes_string,这可能会让您避免使用substitute, 但我无法对其进行评估..y..。(如果有人知道如何构建它,请发表评论,我会更新。)

Hadley还创建了lazyeval包,它对于管理NSE很有用。