数据可视化

参考:https://r4ds.hadley.nz/data-visualize

本章介绍基于ggplot2包的数据可视化基本语法,主要介绍几个常用图形的语法。

1 加载包

library(tidyverse)
library(palmerpenguins) # 提供案例数据
library(ggthemes) # 提供调色板

案例数据为Palmer Archipelago三个岛屿上企鹅的身体测量数据,这是一个tibble类型的数据集:

penguins
# A tibble: 344 × 8
   species island    bill_length_mm bill_depth_mm flipper_length_mm body_mass_g
   <fct>   <fct>              <dbl>         <dbl>             <int>       <int>
 1 Adelie  Torgersen           39.1          18.7               181        3750
 2 Adelie  Torgersen           39.5          17.4               186        3800
 3 Adelie  Torgersen           40.3          18                 195        3250
 4 Adelie  Torgersen           NA            NA                  NA          NA
 5 Adelie  Torgersen           36.7          19.3               193        3450
 6 Adelie  Torgersen           39.3          20.6               190        3650
 7 Adelie  Torgersen           38.9          17.8               181        3625
 8 Adelie  Torgersen           39.2          19.6               195        4675
 9 Adelie  Torgersen           34.1          18.1               193        3475
10 Adelie  Torgersen           42            20.2               190        4250
# ℹ 334 more rows
# ℹ 2 more variables: sex <fct>, year <int>

2 ggplot基本语法

下面我们通过相关性散点图可视化企鹅的鳍长度和体重之间的关系,并通过不同的颜色和形状标注企鹅的种类。

ggplot(
  penguins,
  aes(x = flipper_length_mm, 
      y = body_mass_g, 
      color = species,
      shape = species)
) +
  geom_point() +
  geom_smooth(method = "lm")

Tip

aes() 函数定义了如何将数据集中的变量映射到绘图的可视化属性(即美学,aesthetics)上。

可以看到,它给每个不同的企鹅类型都拟合了一条相关性趋势线。如果我们需要在整个数据集中拟合一条趋势线,则需要将区分企鹅类型的color = speciesshape = species参数从全局的ggplot()中移动到geom_point()中:

ggplot(
  data = penguins,
  aes(x = flipper_length_mm, 
      y = body_mass_g)
) +
  geom_point(aes(color = species, shape = species)) +
  geom_smooth(method = "lm")

这是因为在ggplot()中定义了全局级别的美学映射后,这些映射会向下传递到绘图的每个后续geom层。不过,ggplot2 中的每个 geom 函数也可以接受一个映射参数,这样就可以在局部层级添加美学映射,并将其添加到从全局层级继承的映射中。由于我们希望根据企鹅种类定义每个点的颜色和形状,但不希望分别为每个企鹅种类绘制拟合线,因此我们应该只为 geom_point()指定 color = speciesshape = species

最后,为其添加文字并调用调色板:

ggplot(
  penguins,
  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)",
  ) +
  scale_color_colorblind()

3 可视化分布

3.1 可视化分类变量的分布

条形图可视化企鹅类型的分布:

ggplot(penguins, 
       aes(x = species)) +
  geom_bar(fill = "red")

按照每个类型企鹅数量的多少重新排序条形图。可以通过fct_infreq()对“species”按照其频数重新排序:

ggplot(penguins, 
       aes(x = fct_infreq(species))) +
  geom_bar(fill = "red")

3.2 可视化数值变量的分布

通过直方图可视化企鹅体重对分布情况:

ggplot(penguins, 
       aes(x = body_mass_g)) +
  geom_histogram(binwidth = 200, 
                 fill = "darkblue") 

密度图是数值变量分布的另一种可视化方式。密度图是直方图的平滑化版本,与直方图相比,它显示的细节较少,但能让人更容易快速了解分布的形状。

ggplot(penguins, 
       aes(x = body_mass_g)) +
  geom_density(color = "darkblue")

4 可视化关系

4.1 一个数值变量和一个分类变量

通过箱型图比较不同种类企鹅的体重:

ggplot(penguins, 
       aes(x = species, 
           y = body_mass_g)) +
  geom_boxplot()

箱型图的解释

密度图:

ggplot(penguins, 
       aes(x = body_mass_g, 
           color = species, 
           fill = species)) +
  geom_density(alpha = 0.5)

4.2 两个分类变量

通过堆叠条形图比价不同岛屿上的企鹅类型分布情况:

ggplot(penguins, 
       aes(x = island, 
           fill = species)) +
  geom_bar()

可以通过在 geom 中设置 position = "fill"(填充)绘制相对频率图它更适用于比较各岛屿的物种分布情况,因为它不会受到各岛屿企鹅数量不等的影响

ggplot(penguins, 
       aes(x = island, 
           fill = species)) +
  geom_bar(position = "fill")

4.3 两个数值变量

在上面的ggplot基本语法中我们已经介绍了通过散点图展示两个数值型变量关系的语法:

ggplot(
  penguins,
  aes(x = flipper_length_mm, 
      y = body_mass_g)
) +
  geom_point() +
  geom_smooth(method = "lm") 

4.4 两个以上变量

正如我们在ggplot基本语法中所看到的,我们可以通过将更多变量映射到其他美学元素中,从而将更多变量整合到散点图中。例如,在下面的散点图中,点的颜色代表企鹅种类,点的形状代表所在岛屿:

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)) +
  geom_smooth(method = "lm") +
  facet_wrap(~island)


R version 4.3.2 (2023-10-31)
Platform: aarch64-apple-darwin20 (64-bit)
Running under: macOS Sonoma 14.3.1

Matrix products: default
BLAS:   /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRblas.0.dylib 
LAPACK: /Library/Frameworks/R.framework/Versions/4.3-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.11.0

locale:
[1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8

time zone: Asia/Shanghai
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] ggthemes_5.1.0       palmerpenguins_0.1.1 lubridate_1.9.3     
 [4] forcats_1.0.0        stringr_1.5.1        dplyr_1.1.4         
 [7] purrr_1.0.2          readr_2.1.5          tidyr_1.3.0         
[10] tibble_3.2.1         ggplot2_3.4.4        tidyverse_2.0.0     

loaded via a namespace (and not attached):
 [1] utf8_1.2.4        generics_0.1.3    stringi_1.8.3     lattice_0.22-5   
 [5] hms_1.1.3         digest_0.6.34     magrittr_2.0.3    evaluate_0.23    
 [9] grid_4.3.2        timechange_0.2.0  fastmap_1.1.1     Matrix_1.6-5     
[13] jsonlite_1.8.8    mgcv_1.9-1        fansi_1.0.6       scales_1.3.0     
[17] codetools_0.2-19  cli_3.6.2         rlang_1.1.3       munsell_0.5.0    
[21] splines_4.3.2     withr_3.0.0       yaml_2.3.8        tools_4.3.2      
[25] tzdb_0.4.0        colorspace_2.1-0  vctrs_0.6.5       R6_2.5.1         
[29] lifecycle_1.0.4   htmlwidgets_1.6.4 pkgconfig_2.0.3   pillar_1.9.0     
[33] gtable_0.3.4      glue_1.7.0        xfun_0.41         tidyselect_1.2.0 
[37] rstudioapi_0.15.0 knitr_1.45        farver_2.1.1      htmltools_0.5.7  
[41] nlme_3.1-164      rmarkdown_2.25    labeling_0.4.3    compiler_4.3.2