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

Sch*_*ddi 13 r ggplot2 magrittr

我想将字符串设置N=xxx为我的图的标题,其中xxx是我作为data参数传递的数据框中的观察数ggplot().在我当前的代码中,我第二次显式传递该数据帧作为sprintf()我在其中使用的参数labs():

ggplot(mtcars, aes(mpg, hp)) + 
    labs(title=sprintf("N=%i", nrow(mtcars))) + 
    geom_point()
Run Code Online (Sandbox Code Playgroud)

这确实产生了所需的标题,但它不适用于更复杂的任务:我使用dplyr管道来构建正在绘制的数据框,因为这是一个耗时的过程,我不想重复管道第二次获取行数,如示例中所示.

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

Bri*_*ian 25

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

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

在此输入图像描述


r2e*_*ans 5

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

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

这与Brian的回答在两个方面不同:

  1. 主观上“看起来更简洁”,因为ggplot代码未在代码块内缩进。(不过,正如所评论的那样,不同管道的混合也可能是负面的。)

  2. 通过nr在管道和ggplot管道外部创建,它具有副作用。通过预分配nr,我认为这可以减轻到达本地环境之外的麻烦,但是仍然有些草率。