ggplot2 | 统计变换的初步理解

之前零零散散写了几篇ggplot2绘图系统的推文,反响还不错。目前基础绘图系统已经基本介绍完毕,从本篇开始制表与可视化专辑就集中介绍ggplot2绘图系统。

ggplot2系统与基础绘图系统的语法结构很不一样,它更希望使用者能够专注于原始数据,而不必纠结从原始数据到绘图数据的转换。

例如,在基础绘图系统里,如果想对连续变量进行分段配色,需要先对原始数据进行分段,而在ggplot2绘图系统中可以使用颜色标度函数直接进行分箱映射,具体见前不久的推文:颜色标度函数

统计变换函数也有类似的功能,它执行的是原始数据到图形类别以及y轴变量的映射。

library(ggplot2)
library(patchwork)

从柱状图说起

柱状图是常见的统计图形。基础绘图系统中专门绘制柱状图的函数是barplot(),而在ggplot2系统中对应的几何图形函数是geom_bar()

示例1

生成随机离散值作为示例数据df01

set.seed(12)
df01 <- data.frame(x = rpois(20, 5))
df01$x
##  [1] 2 7 9 4 3 1 3 6 1 1 4 7 4 4 3 4 5 5 6 2

分别使用两个函数直接进行绘图:

barplot(df01$x)

ggplot(df01, aes(x)) +
  geom_bar()

可以看到,上面两个函数绘制出的图形完全不同,其中ggplot2系统绘制出的才是我们想要的柱状图。

这是因为使用原始数据绘制柱状图前需要先进行频数统计,这个过程就是统计变换。

geom_bar()函数的语法结构如下:

geom_bar(
  mapping = NULL,
  data = NULL,
  stat = "count",
  position = "stack",
  ...,
  width = NULL,
  na.rm = FALSE,
  orientation = NA,
  show.legend = NA,
  inherit.aes = TRUE
)

stat参数就是统计变换参数,stat = "count"表示geom_bar()函数默认执行的是频数统计转换,因此在默认情况下geom_bar()函数就能使用原始数据绘制出我们需要的柱状图,而基础绘图系统中的barplot()函数则不行。

示例2

使用dplyr工具包的count()函数对示例1中的df01数据框进行频数统计,作为示例数据df02

library(dplyr)
df02 <- count(df01, x)
df02
##   x n
## 1 1 3
## 2 2 2
## 3 3 3
## 4 4 5
## 5 5 2
## 6 6 2
## 7 7 2
## 8 9 1

再分别使用两个函数绘制柱状图:

barplot(df02$n)

ggplot(df02, aes(n)) +
  geom_bar()

可以看到,两个函数绘制出的结果仍然不一样,其中barplot()函数绘制出的图形与示例1中的geom_bar()函数绘制出的结果比较类似,是我们想要的柱状图。

这是由于geom_bar()函数依然默认执行了频数统计变换,而在本例中原始数据df02中已经包含了频数变量,因此不再需要进行统计变换。

解决办法是设置stat = "identity",该语句表示直接使用原始数据进行绘图。

ggplot(df02, aes(x = x, y = n)) +
  geom_bar(stat = "identity")
  • 需要注意的是count变换只需要一个绘图变量(示例1中的x),而identity变换需要两个绘图变量(示例2中的xn)。

到这里,就介绍了count和identity两种类型的变换了。

从柱状图到直方图、密度图

示例3

在基础绘图系统中,柱状图和直方图有着明显的界限:柱状图应用于离散变量的频数统计,直方图应用于连续变量的频数统计。

ggplot2绘图系统中,直方图对应的几何图形函数是geom_histogram(),但是通过设置统计变换参数statgeom_bar()函数也能绘制出直方图。

直方图的绘制原理是先将连续变量分段、统计频数,然后再绘制成“柱状图”,这就是分箱统计变换,即stat = bingeom_histogram()函数默认的就是分箱变换:

geom_histogram(
  mapping = NULL,
  data = NULL,
  stat = "bin",
  position = "stack",
  ...,
  binwidth = NULL,
  bins = NULL,
  na.rm = FALSE,
  orientation = NA,
  show.legend = NA,
  inherit.aes = TRUE
)

生成连续变量作为示例数据df03

set.seed(34)
df03 <- data.frame(x = rnorm(200, 5))

分别使用geom_histogram()geom_bar()函数绘制直方图:

ggplot(df03, aes(x)) +
  geom_histogram(binwidth = 0.25, color = "white") -> p1

ggplot(df03, aes(x)) +
  geom_bar(stat = "bin", binwidth = 0.25, color = "white") -> p2

p1 + p2

可以看出,两个函数绘制出的结果一致。

示例4

密度图相当于将柱状图的频数统计变换变为频率统计变换(离散变量),或者对直方图进行无限分割后再进行频率统计变换(连续变量)。

尽管有专门的密度函数geom_density(),但是通过设置统计变换参数,仍然可以使用geom_bar()绘制出密度图。

## 离散变量
ggplot(df01, aes(x)) +
  geom_bar(stat = "density") -> p3

## 连续变量
ggplot(df03, aes(x)) +
  geom_bar(stat = "density") -> p4

p3 + p4

至此,又介绍了bin和density两种统计变换。

统计变换函数

进行统计变换不仅可以通过设置几何图形函数的stat参数,还可以直接使用统计变换函数,这些函数以stat_开头进行命名。

示例5

频数统计变换函数的语法结构如下:

stat_count(
  mapping = NULL,
  data = NULL,
  geom = "bar",
  position = "stack",
  ...,
  width = NULL,
  na.rm = FALSE,
  orientation = NA,
  show.legend = NA,
  inherit.aes = TRUE
)

geom参数表示统计变换后绘制的图形类型,geom = "bar"表示stat_count()函数在进行频数统计后默认绘制柱状图。

ggplot(df01, aes(x)) +
  stat_count() -> p5

ggplot(df03, aes(x)) +
  stat_bin(binwidth = 0.25) -> p6

p5 + p6

示例6

stat_identity()函数的语法结构如下:

stat_identity(
  mapping = NULL,
  data = NULL,
  geom = "point",
  position = "identity",
  ...,
  show.legend = NA,
  inherit.aes = TRUE
)

该函数默认绘制的几何图形是散点图:

ggplot(df02, aes(x = x,  y = n)) +
  stat_identity() -> p7

ggplot(df02, aes(x = x,  y = n)) +
  stat_identity(geom = "bar") -> p8

p7 + p8

其他统计变换

ggplot2绘图系统中内置了许多类型的统计变换,还支持使用stat_function()函数进行自定义统计变换。下面简单列举几种,详细可查看官方帮助文档。

  • 概率累积变换

ggplot(df02, aes(x)) +
  stat_ecdf() -> p9

ggplot(df03, aes(x)) +
  stat_ecdf() -> p10

p9 + p10
  • 方向分布变换(标准差椭圆)

ggplot(df02, aes(x, n)) +
  geom_point() +
  stat_ellipse()
  • 正态QQ检验

ggplot(df03, aes(sample = x)) +
  stat_qq() +
  stat_qq_line()
  • 平滑变换

ggplot(mpg, aes(displ, hwy)) +
  geom_point() +
  stat_smooth(span = 0.3)
  • 汇总变换

ggplot(mtcars, aes(cyl, mpg)) +
  geom_point()+ 
  stat_summary(fun.data = "mean_cl_boot", colour = "red", size = 2)
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值