首页 > 解决方案 > 点语法访问 ggplot2 层中的数据

问题描述

有人可以帮我弄清楚ggplot2 层参数中的含义吗.data任何我可以阅读的文档或博客文章?

ggplot(mtcars) + 
  geom_text(
    aes(x=1, y=cyl, label=hp), 
    data=. %>% group_by(cyl) %>% summarise(hp=mean(hp)) 
  )

显然这不是 magrittr 管道引入的通常点,因为在点之前没有管道......</p>

非常感谢!

标签: rggplot2

解决方案


我不知道是否有官方文档,但我们可以追溯 ggplot2 所做的步骤来弄清楚发生了什么。首先,管道存储为函数(子)类对象。

library(tidyverse)

(x <- . %>% group_by(cyl) %>% summarise(hp = mean(hp)))
#> Functional sequence with the following components:
#> 
#>  1. group_by(., cyl)
#>  2. summarise(., hp = mean(hp))
#> 
#> Use 'functions' to extract the individual functions.
class(x)
#> [1] "fseq"     "function"

然后,当 ggplot2 摄取管道操作时,它会将其强化为一个函数。您可以检查layer函数体以查看此内容。在这种情况下,它只会返回您已经拥有的函数。geom_*()这将存储在您从调用的任何函数或函数中获取的图层对象中stat_*()

ggplot2:::fortify.function
#> function(model, data, ...) model
#> <bytecode: 0x0000000014a1d878>
#> <environment: namespace:ggplot2>

最后,当绘图被构建时,图层会检查数据是否为函数,如果是,则使用(全局)绘图数据作为第一个也是唯一的参数对其进行评估。此时,mtcars数据集被输入到您的管道序列中。请注意,下面的代码self$data是强化数据参数,因此在您的情况下是管道序列。

geom_text()$layer_data
#> <ggproto method>
#>   <Wrapper function>
#>     function(...) f(..., self = self)
#> 
#>   <Inner function (f)>
#>     function(self, plot_data) {
#>     if (is.waive(self$data)) {
#>       plot_data
#>     } else if (is.function(self$data)) {
#>       data <- self$data(plot_data)
#>       if (!is.data.frame(data)) {
#>         abort("Data function must return a data.frame")
#>       }
#>       data
#>     } else {
#>       self$data
#>     }
#>   }

reprex 包于 2021-03-21 创建(v1.0.0)


推荐阅读