r - ggplot stat_* 函数在概念上如何工作?
问题描述
我目前正试图弄清楚.stat_*
和geom_*
in之间的差异ggplot2
。(请注意,这更像是一个基于兴趣/理解的问题,而不是我正在尝试解决的特定问题)。
介绍
我目前的理解是,这些stat_*
函数对您的数据应用转换,然后将结果传递geom_*
给要显示的数据。
最简单的示例是身份转换,它只是将未转换的数据传递到 geom。
ggplot(data = iris) +
stat_identity(aes(x = Sepal.Length, y = Sepal.Width) , geom= "point")
更实际的用例似乎是当您想要使用一些转换并将结果提供给非默认几何图形时,例如,如果您想绘制第一和第三四分位数的误差条,您可以执行以下操作:
ggplot(data = iris) +
stat_boxplot(aes(x=Species, y = Sepal.Length, ymax = ..upper.., ymin = ..lower..), geom = "errorbar")
问题 1
那么这些转换如何/何时应用于数据集以及数据如何准确地通过它们?
例如,假设我想进行stat_boxplot
转换并绘制第三个四分位数的点,我该怎么做?
我的直觉是这样的:
ggplot(data = iris) +
stat_boxplot(aes(x=Species, y = ..upper..) , geom = "point")
或者
ggplot(data = iris) +
stat_boxplot(aes(x=Species, y = Sepal.Length) , geom = "point")
但是两者都错误
Error: geom_point requires the following missing aesthetics: y
我的猜测是作为stat_boxplot
转换的一部分,它消耗 y 美学并产生一个不包含任何y
变量的数据集,但这会导致......
问题2
我在哪里可以找到作为stat_*
转换的一部分使用的变量以及它们输出的变量?也许我在寻找错误的地方,但文档对我来说似乎并不清晰......
解决方案
有趣的问题...
作为背景信息,您可以阅读R for Data Science 的这一章,重点介绍图形的语法。我确信 Hadley Wickham 的关于 ggplot2 的书甚至是更好的来源,但我没有那个。
构建具有一层且无构面的图的主要步骤是:
- 对输入数据应用美学映射(在简单的情况下,这是对列的选择和重命名)
- 对每个数据列应用比例转换(如果有)
- 计算每个数据组的统计数据(即本例中的每个物种)
- 在统计数据上应用美学映射,用
..<name>..
or检测stat(name)
- 应用位置调整
- 构建图形对象
- 应用坐标变换
如您所料,第 3 步的行为类似于dplyr::transmute()
:它使用所有美学列并输出一个数据框,该数据框包含所有新计算的统计信息和组内所有常量列作为列。stat 输出的行数也可能与其输入不同。因此,在您的示例中,该y
列确实没有传递给 geom。
为此,我们希望在步骤 1(在 stat 之前)和在步骤 4(在 geom 之前)指定不同的映射。我认为这样的事情会起作用:
# 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() 之前自行管理它:
library(tidyverse)
iris %>%
group_by(Species) %>%
select(y=Sepal.Length) %>%
do(StatBoxplot$compute_group(.)) %>%
ggplot(aes(Species, upper)) + geom_point()
有点不优雅,我承认......
对于您的问题 2,它在文档中:请参阅 Aesthetics 和 Computed variables 部分?stat_boxplot
推荐阅读
- python - jsonschema 库将数字验证为没有上限的字符串
- flutter - 扫描条码时在 Flutter 应用中显示 progressIndicator
- spring - Spring Data JPA:使用可选参数调用存储库方法的有效方法
- android - 重新连接到网络后如何获取有效的 Firebase appcheck 令牌?
- google-gsuite - 发生错误:对 directory.users.signOut 的 API 调用失败并出现错误:请求的身份验证范围不足
- python - 硒超时异常
- node.js - 是否可以在 express 应用程序中运行节点工作程序
- python - 如何忽略特定索引?Python
- python - 如何解决此正则表达式问题以匹配可选列和空格?
- python - 带有 TypeError 的自动测试暂停:“str”对象不可调用