本书为 R for data science 第二版英文原版的要点记录,并加入自己的理解,力求做到更浓缩,更易懂,更实用。
参考书目:https://r4ds.hadley.nz
本书一上来就给出了数据分析的整体流程的框架:
1 数据可视化
1.1 引子
主要介绍使用 ggplot2 包进行可视化。
1.3 准备工作
R 包:ggplot2,tidyverse,palmerpenguins,ggthemes
如果没有安装这些包,需要运行 install.packages("包名")
来安装指定包
# 如果没有安装,则需运行下面一行安装tidyverse,ggplot也会自动安装
install.packages("tidyverse")
library(tidyverse)
library(palmerpenguins)
library(ggthemes)
1.2 第一步
利用可视化探索一下企鹅数据集中展示的一些关系。
1.2.1 企鹅数据集
该数据框是 palmerpenguins 包中的 penguins 数据框,即:palmerpenguins::penguins
。共有344个观察数据。
为了让讲解更容易一些,我们先做以下定义:
- 一个变量即一个可测量的指标,可以理解为数据框中的一列。
- 一个数值即一个变量中测得的数据。
- 一个观测即为一个样本的一组变量的数值集合,可以理解为数据框中的一行。
- 一个表格即一组观测的数据,也相当于一个数据框。
在这里,变量指所有企鹅的属性,而每个观测为每只企鹅所有属性的一个观测值。企鹅的数据是由 tibble 格式存储的,我的理解是可以看作是一个简化形式的数据框格式(dataframe)。
在 R 中,可以通过数据名预览数据集。
penguins
#> # A tibble: 344 × 8
#> species island bill_length_mm bill_depth_mm flipper_length_mm
#> <fct> <fct> <dbl> <dbl> <int>
#> 1 Adelie Torgersen 39.1 18.7 181
#> 2 Adelie Torgersen 39.5 17.4 186
#> 3 Adelie Torgersen 40.3 18 195
#> 4 Adelie Torgersen NA NA NA
#> 5 Adelie Torgersen 36.7 19.3 193
#> 6 Adelie Torgersen 39.3 20.6 190
#> # 338 more rows
#> # 3 more variables: body_mass_g <int>, sex <fct>, year <int>
可以看到本数据集由344个观测(行),每个观测有8个属性(列)。可以通过 glimpse()
来看每个属性的前几个观测值,如果在 R studio 中,则可以通过 View(penguins)
打开整个数据集浏览。
glimpse(penguins)
#> Rows: 344
#> Columns: 8
#> $ species <fct> Adelie, Adelie, Adelie, Adelie, Adelie, Adelie, A…
#> $ island <fct> Torgersen, Torgersen, Torgersen, Torgersen, Torge…
#> $ bill_length_mm <dbl> 39.1, 39.5, 40.3, NA, 36.7, 39.3, 38.9, 39.2, 34.…
#> $ bill_depth_mm <dbl> 18.7, 17.4, 18.0, NA, 19.3, 20.6, 17.8, 19.6, 18.…
#> $ flipper_length_mm <int> 181, 186, 195, NA, 193, 190, 181, 195, 193, 190, …
#> $ body_mass_g <int> 3750, 3800, 3250, NA, 3450, 3650, 3625, 4675, 347…
#> $ sex <fct> male, female, female, NA, female, male, female, m…
#> $ year <int> 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2007, 2…
目前我们关心的是:
species: 企鹅种类 (Adelie, Chinstrap, or Gentoo).
flipper_length_mm: 企鹅鳍状肢长度, 用毫米表示.
body_mass_g: 体重,用克表示.
1.2.2 最终目标
我们希望展示出下图:
1.2.3 建立图表
我们开始一步一步建立上图
第一步,建立一个空画布:ggplot(data = penguins)
。这一步做了两件事:
- 建立了一个空的画布,后面将在这张画布上画图
- 告诉ggplot,这个图所用的数据来自 penguins
第二步,告诉 ggplot 数据应该怎样展示,这里有一个概念:aesthetics,简称 aes,可以理解成展示数据的一种布局和美学。代码为:
ggplot(
data = penguins,
mapping = aes(x = flipper_length_mm, y = body_mass_g)
)
完成以上步骤后,我们将得到下图,仅有背景。
接下来定义显示的几何形状:geometrical objects。简称 geom。
ggplot(
data = penguins,
mapping = aes(x = flipper_length_mm, y = body_mass_g)
) +
geom_point()
#> Warning: Removed 2 rows containing missing values or values outside the scale range
#> (`geom_point()`).
我们用点图显示数据(geom_point),得到下图。
1.2.4 增加美学和图层
可以通过将颜色 color 比对到不同种类的企鹅,只需要在 aes 对应的括号内不加入color 参数。
ggplot(
data = penguins,
mapping = aes(x = flipper_length_mm, y = body_mass_g, color = species)
) +
geom_point()
得到下图
可以看到 ggplot2 为我们自动赋予了颜色和图注。
接下来我们加入一个图层,显示体重和鳍状肢长度的关系:geom_smooth.
ggplot(
data = penguins,
mapping = aes(x = flipper_length_mm, y = body_mass_g, color = species)
) +
geom_point() +
geom_smooth(method = "lm")
得到下图
得到了三条趋势线,原因是我们在ggplot 的全局信息的mapping参数的区域里运用了color。如果我们想保留不同颜色的分类,但仅显示一条总的趋势线,则可以将 aes 的信息放在 geom_point 参数里面。
ggplot(
data = penguins,
mapping = aes(x = flipper_length_mm, y = body_mass_g)
) +
geom_point(mapping = aes(color = species)) +
geom_smooth(method = "lm")
接下来,我们在给不同品种企鹅赋予颜色的同时,也给它们赋予不同的形状。
ggplot(
data = penguins,
mapping = aes(x = flipper_length_mm, y = body_mass_g)
) +
geom_point(mapping = aes(color = species, shape = species)) +
geom_smooth(method = "lm")
最后,让我们完善一下,最终完成这幅图:
- 加入标题信息
- 利用ggtheme里面对色盲友好的配色,这样色盲患者也能分清楚信息。这一步至关重要,许多SCI杂志在最终校稿时,都要求作者将配色换成色盲患者也能认清楚的颜色,因此不如在一开始做图时就注意。
ggplot(
data = penguins,
mapping = aes(x = flipper_length_mm, y = body_mass_g)
) +
geom_point(aes(color = species, shape = species)) +
geom_smooth(method = "lm") +
labs(
title = "Body mass and flipper length",
subtitle = "Dimensions for Adelie, Chinstrap, and Gentoo Penguins",
x = "Flipper length (mm)", y = "Body mass (g)",
color = "Species", shape = "Species"
) +
scale_color_colorblind()
完成!!!
1.3 ggplot 的代码形式
ggplot 也可以提供其它代码形式使代码变得更加简洁。
以下三种代码布局都可以:
- 完全形式
ggplot(
data = penguins,
mapping = aes(x = flipper_length_mm, y = body_mass_g)
) +
geom_point()
- 简洁形式
penguins |>
ggplot(aes(x = flipper_length_mm, y = body_mass_g)) +
geom_point()
- 管道形式 (后面会介绍)
penguins |>
ggplot(aes(x = flipper_length_mm, y = body_mass_g)) +
geom_point()
1.4 可视化分布信息
1.4.1 分类种类信息
柱状图,可以自动统计每个类别的数量
ggplot(penguins, aes(x = species)) +
geom_bar()
也可以将类别当作 factor 变量展示,这样可以方便排序 (根据数量排序)
ggplot(penguins, aes(x = fct_infreq(species))) +
geom_bar()
1.4.2 数值分类数据
连续性数值数据,可以分段显示。分段用 binwidth
设置。
ggplot(penguins, aes(x = body_mass_g)) +
geom_histogram(binwidth = 200)
ggplot(penguins, aes(x = body_mass_g)) +
geom_histogram(binwidth = 20)
ggplot(penguins, aes(x = body_mass_g)) +
geom_histogram(binwidth = 2000)
这类图可以看出分布的大致情况,但是仍然显得不够好看,一种选择是使用密度图(
geom_density()
)
ggplot(penguins, aes(x = body_mass_g)) +
geom_density()
#> Warning: Removed 2 rows containing non-finite outside the scale range
#> (`stat_density()`).
1.5 可视化变量关系
1.5.1 分类和数值变量
下面是三种图展示的结果
左图是变量的实际分布,中图是柱状图展示的结果,右图是盒子图(boxplot)展示的结果。
很明显,比较好的形式是盒子图。
我们来看一下用盒子图展示体重分布
ggplot(penguins, aes(x = species, y = body_mass_g)) +
geom_boxplot()
我们也可以用密度分布图展示:
ggplot(penguins, aes(x = body_mass_g, color = species)) +
geom_density(linewidth = 0.75)
我们可以将密度图填色,显得更加清楚
ggplot(penguins, aes(x = body_mass_g, color = species, fill = species)) +
geom_density(alpha = 0.5)
有两点需要注意:
- 如果我们需要将某些变量信息通过图形的形式对应起来,我们需要将这个变量放在 aes 里面进行设置
- 如果我们仅仅单纯是设置自己想要的颜色,则直接设置。
1.5.2 对应两组都是分类变量的情况
我们可以利用堆积的柱状图展示
ggplot(penguins, aes(x = island, fill = species)) +
geom_bar()
在 geom_bar 中设置
position=fill
可以以百分比的形式展示
ggplot(penguins, aes(x = island, fill = species)) +
geom_bar(position = "fill")
1.5.3 双数值变量的展示
当两个变量都是数量性状时,可以通过点图展示
ggplot(penguins, aes(x = flipper_length_mm, y = body_mass_g)) +
geom_point()
1.5.4 三个以上变量展示
ggplot(penguins, aes(x = flipper_length_mm, y = body_mass_g)) +
geom_point(aes(color = species, shape = island))
一种更好的方式是使用分面展示:
facet_wrap
ggplot(penguins, aes(x = flipper_length_mm, y = body_mass_g)) +
geom_point(aes(color = species, shape = species)) +
facet_wrap(~island)
1.6 保存图片
使用ggsave
命令
ggplot(penguins, aes(x = flipper_length_mm, y = body_mass_g)) +
geom_point()
ggsave(filename = "penguin-plot.png")
总结
本章总结了从画图到存储的整个流程。后面将进一步针对每个阶段进行更深入的探讨。