如何访问已传递给 ggplot() 的数据框?

How do I access the data frame that has been passed to ggplot()?

我想将字符串 N=xxx 设置为我的图形的标题,其中 xxx 是我作为 data 参数传递给ggplot()。在我当前的代码中,我第二次将该数据帧作为参数传递给 sprintf(),我在 labs() 内部使用它:

ggplot(mtcars, aes(mpg, hp)) + 
    labs(title=sprintf("N=%i", nrow(mtcars))) + 
    geom_point()

这确实产生了所需的标题,但它不适用于更复杂的任务:我使用 dplyr 管道构建正在绘制的数据框,因为这是一个 time-consuming 过程中,我不想再次重复管道以获得示例中的行数。

那么,如何从用于修改绘图的函数的参数规范中访问作为参数传递给 ggplot() 的数据框?

mtcars %>% {
  ggplot(., aes(mpg, hp)) + 
  labs(title = paste("N =", nrow(.))) + 
  geom_point()
}

请注意,当用 {...} 花括号包裹整个 ggplot 调用时,您必须使用 . 点代词作为 ggplot(., ...) 中的数据参数。然后您可以在调用的任何位置使用 . 代词回调该对象。

另一个选项利用了 magrittr 的另一个流水线特性:tee 运算符 %T>%.

library(ggplot2)
library(magrittr)
# to solidify where the variable will be out-of-scope defined
nr <- "oops"
mtcars %T>%
  { nr <<- nrow(.) } %>%
  ggplot(aes(mpg, hp)) + 
    labs(title=sprintf("N=%i", nr)) + 
  geom_point()

(这也可以使用 dplyrdo({nr <<- nrow(.)}) %>% 来完成。)

这与 Brian 的回答有两点不同:

  1. 主观上 "cleaner looking",因为 ggplot 代码没有在代码块内缩进。 (不过,正如所评论的,不同管道的混合也可能是负面的。)

  2. 它有副作用,通过在管道和 ggplot 管道之外创建 nr。通过预分配 nr,我认为这减轻了到达本地环境之外的影响,但它仍然有点草率。