关于r:ggplot stat_ *函数在概念上如何工作?

How do ggplot stat_* functions work conceptually?

我目前正在努力弄清ggplot2stat_*geom_*之间的差异。 (请注意,这不是我要解决的特定问题,而是更多基于兴趣/理解的问题)。

介绍

我目前的理解是stat_*函数将转换应用于数据,然后将结果传递到geom_*进行显示。

最简单的例子是身份转换,它只是将未经转换的数据传递到geom上。

1
2
ggplot(data = iris) +
    stat_identity(aes(x = Sepal.Length, y = Sepal.Width) , geom="point")

当您想使用某种转换并将结果提供给非默认几何时,似乎更实际的用例是,例如,如果您要绘制第一四分位数和第三四分位数的误差线,则可以执行以下操作:

1
2
ggplot(data = iris) +
    stat_boxplot(aes(x=Species, y = Sepal.Length, ymax = ..upper.., ymin = ..lower..), geom ="errorbar")

问题1

那么这些转换如何/何时应用于数据集,数据如何准确地通过它们呢?

例如,假设我要进行stat_boxplot转换并绘制第三个四分位数的点,我将如何执行此操作?

我的直觉是这样的:

1
2
ggplot(data = iris) +
    stat_boxplot(aes(x=Species, y = ..upper..) , geom ="point")

要么

1
2
ggplot(data = iris) +
    stat_boxplot(aes(x=Species, y = Sepal.Length) , geom ="point")

但是两者都错误

1
Error: geom_point requires the following missing aesthetics: y

我的猜测是作为stat_boxplot转换的一部分,它消耗了y美学效果,并生成了一个不包含任何y变量的数据集,但这导致了...。

问题2

在哪里可以找到在stat_*转换中消耗了哪些变量,以及输出了哪些变量?也许我在错误的地方找东西,但是文档对我来说似乎一点都不清晰...


有趣的问题...

作为背景信息,您可以阅读R for Data Science的这一章,重点关注图形语法。我敢肯定,哈德利·威克姆(Hadley Wickham)关于ggplot2的书甚至是更好的资料,但我没有。

构建只有一层且没有任何构面的图的主要步骤是:

  • 在输入数据上应用美学映射(在简单情况下,这是对列的选择和重命名)
  • 在每个数据列上应用比例转换(如果有)
  • 计算每个数据组的统计信息(即本例中的每个物种)
  • 将美学映射应用于用....stat(name)检测到的统计数据
  • 应用位置调整
  • 建立图形对象
  • 应用坐标变换
  • 如您所料,步骤3的行为类似于dplyr::transmute():它消耗所有美学列,并输出一个数据框,该数据框具有所有新计算的统计信息和该组中所有恒定的列作为列。统计输出也可能与输入的行数不同。因此,确实在您的示例中,y列未传递给geom。

    为此,我们想在第1步(统计之前)和第4步(geom之前)指定不同的映射。我认为这样会起作用:

    1
    2
    3
    4
    5
    # This does not work:
    ggplot(data = iris) +
      geom_point(
        aes(x=Species, y=stat(upper)),
        stat=stat_boxplot(aes(x=Species, y=Sepal.Length)) )

    ...但是不是(stat必须是字符串或Stat对象,但是stat_boxplot实际上会返回一个Layer对象,就像geom_point一样)。

    注意:stat(upper)是与您的..upper..等效的,更新的符号

    我可能是错的,但我认为没有直接在ggplot中执行此操作的方法。您可以做的是提取上述过程的stat部分,并在输入ggplot()之前自行管理它:

    1
    2
    3
    4
    5
    6
    library(tidyverse)
    iris %>%
      group_by(Species) %>%
      select(y=Sepal.Length) %>%
      do(StatBoxplot$compute_group(.)) %>%
      ggplot(aes(Species, upper)) + geom_point()

    我承认有点不优雅

    对于您的问题2,它在文档中:请参见?stat_boxplot的美学和计算变量部分