首页 文章

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

提问于
浏览
5

当我尝试将参数传递到 stat_summary 中的 round 函数时,我收到错误(即使类似的代码与 geom_text 一起使用) . 这是一个例子:

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

我在尝试编写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(expr,envir,enclos)中的错误:找不到对象'places'

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

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

1 回答

  • 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

    Hadley还提供了几个SE版本的 aesaes_aes_qaes_string ,它们可以让你避免使用 substitute ,但我无法评估 ..y.. . (如果有人知道如何构建它,请评论,我会更新 . )

    Hadley还创建了lazyeval package,这对管理NSE非常有用 .

相关问题