简体   繁体   English

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

[英]ggplot2: stat_summary throws error when trying to pass function argument as parameter, rather than hard-coding

I'm getting an error when I try to pass a parameter into the round function within stat_summary (even though the analogous code works with, say, geom_text ). 当我尝试将参数传递给stat_summaryround函数时,我收到错误(即使类似的代码与geom_text )。 Here's an example: 这是一个例子:

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

We'll try to set the number of decimal places for value labels using a parameter, rather than hard-coding it: 我们将尝试使用参数设置值标签的小数位数,而不是硬编码:

places = 2

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

Error in eval(expr, envir, enclos) : object 'places' not found eval中的错误(expr,envir,enclos):找不到对象'places'

The following two examples work fine, however. 但是,以下两个示例工作正常。

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)))

I ran into this problem while trying to write a ggplot function. 我在尝试编写ggplot函数时遇到了这个问题。 At first I thought the problem involved ggplot not getting the parameter from the function environment, but the example above suggests that's not the issue. 起初我认为问题涉及ggplot没有从函数环境中获取参数,但上面的例子表明这不是问题。 For completeness, below is a simplified example of the function, along with the error message. 为了完整起见,下面是该函数的简化示例以及错误消息。 The function works fine if I hard-code the digits argument to round , rather than trying to pass the places parameter. 如果我将数字参数硬编码为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")

Error in eval(expr, envir, enclos) : object 'places' not found eval中的错误(expr,envir,enclos):找不到对象'places'

I'm hoping to find out whether I'm doing something wrong and how I can get the desired behavior. 我希望了解我是否做错了什么以及我如何能够获得理想的行为。

I'm running R 3.2.3 and ggplot2 2.1.0 on OS X 10.10.5. 我在OS X ggplot2上运行R 3.2.3和ggplot2 2.1.0。

aes uses non-standard evaluation , and will thus try to evaluate places within the data argument you give it. aes使用非标准的评价 ,因此将尝试评估places的范围内data ,你给它的参数。 Its NSE varies, though, depending on what you pass it. 但它的NSE会有所不同,具体取决于你传递的内容。

The typical way to bypass NSE is with substitute , which, well, substitutes a value inside of code. 绕过NSE的典型方法是使用substitute ,它可以替代代码中的值。 You can then use eval to run the code: 然后,您可以使用eval运行代码:

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

which works as expected: 它按预期工作:

情节与标签

Hadley also provides several SE versions of aes : aes_ , aes_q , and aes_string , which may let you avoid the use of substitute , but which I couldn't get to evaluate ..y.. . Hadley还提供了几个SE版本的aesaes_aes_qaes_string ,它们可以让你避免使用substitute ,但是我无法评估..y.. (If anyone knows how to structure it, comment and I'll update.) (如果有人知道如何构建它,请评论,我会更新。)

Hadley also created the lazyeval package , which is useful for managing NSE. Hadley还创建了lazyeval包 ,这对管理NSE非常有用。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM