【问题标题】:ggplot2: stat_summary throws error when trying to pass function argument as parameter, rather than hard-codingggplot2:stat_summary 在尝试将函数参数作为参数而不是硬编码时抛出错误
【发布时间】:2016-06-18 18:40:02
【问题描述】:

当我尝试将参数传递到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。

【问题讨论】:

  • 看起来像是 NSE 问题。您可以通过拨打eval(substitute( ...ggplot code... , list(places = places))) 来躲避它,尽管可能有更好的方法。
  • 那行得通。请添加它作为答案。你知道为什么它发生在stat_summary 内部而不是其他地方吗?
  • 我不确定;这与aes 中的 NSE 的工作方式有关。也许它是由..y.. 开启的?有一个名为 aes_ 的 SE 版本,但我不确定如何让 ..y.. 参数在其中工作。我会在上面发布一个答案以及我在一秒钟内想出的任何其他内容。

标签: r ggplot2 parameter-passing


【解决方案1】:

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

按预期工作:

Hadley 还提供了几个 SE 版本的 aesaes_aes_qaes_string,这可能让您避免使用 substitute,但我无法评估 @987654335 @。 (如果有人知道如何构建它,请发表评论,我会更新。)

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-04-21
    • 2020-01-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多