三、描述变量相关的可视化图形

许多数据集包含多个变量,我们除了关心每一个变量的类型、取值集合、分布情况,可能还对这些变量的关系、分组情况等感兴趣。例如,存在一个不同动物的定量测量数据集,如动物的身高、体重、长度和每日能量需求。为表现两个变量之间的关系,最常用的是散点图。如果我们想同时显示两个以上的变量,可以选择气泡图、散点图矩阵或相关图,可以在散点图中用符号大小、符号颜色、符号形状表示更多维数。最后,对于高维的数据集,经常需要利用降维方法,如主成分分析(PCA)对数据降维,对降维数据作图。 (一)散点图 R 软件自带的 Iris 数据集中包含了三种鸢尾花的 150 个样品的测量数据,每种各 50 个样本,每个样本测量了花瓣和花萼的长、宽。下面画出 50 个花卉样本的花瓣长、宽的散点图(见图 6-2-29~图 6-2-32),可以看出,二者有明显的线性相关关系。 使用 ggplot2 绘制散点图的步骤如下: ● 提供样本数据框;  确定在 x 和 y 轴上显示哪个变量;  添加一个 geom_point()函数显示点。 #本节使用的绘图库 library(ggplot2) library(hrbrthemes) library(patchwork) library(tidyverse) library(cowplot) library(dplyr) # 本节使用的演示数据是软件自带的数据集 iris # 叶片大小与生长之间的关系描述 # ggplot2 默认散点图 ggplot(iris, aes(Sepal.Length, Sepal.Width, color = Species)) + geom_point()+ theme_bw() 图 6-2-29 默认散点图 # 经典的 cowplot 主题 ggplot ( iris , aes ( Sepal.Length , Sepal.Width , color = Species )) + geom_point () + theme_cowplot (15 ) 6-2-30 cowplot 主题散点图 # 最小网格主题 ggplot ( iris , aes ( Sepal.Length , Sepal.Width , color = Species )) + geom_point () + theme_minimal_grid ( 12 ) 图 6-2-31 网格线散点图 # 使用颜色区分不同物种与生长之间的关系 ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width, color=Species)) + geom_point(size=6) + theme_ipsum(base_family = "") 图 6-2-32 不同颜色设置类别的散点图
使用 geom_point()自定义参数设置散点图(见图 6-2-33~图 6-2-35): ● color:描边颜色,圆形轮廓; ● stroke:笔画宽度; ● fill:圆圈内部的颜色; ● shape:标记的形状; ● alpha:圆形透明度,[0-1],0 为全透明; ● size:圆圈大小。 注意:如果将 geom_point()放入调用中,这些选项设置要与标记之间保持一致。如果将 它们放在 aes()代码中,还可以将它们映射到变量。 ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width)) + geom_point( color="red", fill="#0000CD", shape=20, alpha=0.5, size=4, stroke = 2 )+ theme_bw() 图 6-2-33 透明度散点图 将变量映射到任何标记特性。例如,下面透明度、形状和大小的设置都取决于 Species的值。 # 设置透明度 ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width, alpha=Species))+ geom_point(size=4, color="#008B8B") + theme_ipsum(base_family = "") 图 6-2-34 散点图 # 设置形状或大小 ggplot(iris, aes(x=Sepal.Length, y=Sepal.Width, shape=Species)) + geom_point(size=4,color="#008B8B") + theme_ipsum(base_family = "") 图 6-2-35 不同形状散点图
(二)散点图矩阵 多个变量之间的关系经常用散点图矩阵表示。ggplot2 包没有提供专门的散点图矩阵,基础 R 图形中提供了 pairs 函数做散点图矩阵,GGally 包提供了一个 ggscatmat()函数做散点图矩阵。例如,对 Iris 数据的四个测量值变量做散点图矩阵,如图 6-2-36 所示。 # 多变量散点矩阵图 ggscatmat(data = iris, columns = 1:4, color = "Species" )+ theme_bw() 图 6-2-36 多变量散点矩阵图 排列成矩阵的各个切片的下三角位置是两个变量的散点图,对角线位置是单个变量的核密度估计,上三角位置是两个变量的相关系数。 ggpairs(data = iris, color = "Species", columns = c("Petal.Length", "Sepal.Length", "Species"))+ theme_bw() 变量两两相关的散点矩阵图如图 6-2-37 所示。 图 6-2-37 变量两两相关的散点矩阵图
(三)数据降维 当数据中有过多变量时,即使是散点图矩阵也会因信息量过大难以认读。因此,要将数据降低维度,通常将数据降维到若干个新变量,最常用的方法是主成分分析(PCA)。PCA通过数据中原始变量的线性组合引入了一组新变量(称为主成分,PC),且使方差和均标准化值为零。主成分分析利用变量的协方差阵或者相关阵的特征值分解对原始变量进行线性组合,产生若干个新变量。当原始变量为相同单位且可比时,可以基于协方差阵,否则应该基于相关阵。例如,对 Iris 数据集的 4 个测量值作主成分分析,示例如下: pca1 <- princomp(iris[,1:4], cor=FALSE) summary(pca1) ## Importance of components: ## Comp.1 Comp.2 Comp.3 Comp.4 ## Standard deviation 2.0494032 0.49097143 0.27872586 0.153870700 ## Proportion of Variance 0.9246187 0.05306648 0.01710261 0.005212184 ## Cumulative Proportion 0.9246187 0.97768521 0.99478782 1.000000000 load1 <- loadings(pca1) print(load1) ## ## Loadings: ## Comp.1 Comp.2 Comp.3 Comp.4 ## Sepal.Length 0.361 0.657 0.582 0.315 ## Sepal.Width 0.730 -0.598 -0.320 ## Petal.Length 0.857 -0.173 -0.480 ## Petal.Width 0.358 -0.546 0.754 ## ## Comp.1 Comp.2 Comp.3 Comp.4 ## SS loadings 1.00 1.00 1.00 1.00 ## Proportion Var 0.25 0.25 0.25 0.25 ## Cumulative Var 0.25 0.50 0.75 1.00 ps1 <- predict(pca1) ps1 <- as.data.frame(ps1) ps1 <- cbind(iris, ps1) 前两个主成分解释了原始变量中 98%的方差。 作第一和第二主成分的散点图,如图 6-2-38 所示。 library(ggplot2) library(corrgram) library(ggrepel) ggplot(data = as.data.frame(ps1), mapping = aes( x = Comp.1, y = Comp.2, color = Species))+ geom_point(size = 2.0, alpha = 0.4)+ theme_bw() 图 6-2-38 主成分散点图
主成分分析取前两个主成分在各原始变量上的载荷做矢量图(见图 6-2-39),用来表示各个原始变量与主成分的关系: d <- as.data.frame(load1[,1:2]) d$vlabel <- rownames(d) p <- ggplot(data = d, mapping = aes( x = Comp.1, y = Comp.2, label = vlabel)) p + geom_segment(mapping = aes( xend = Comp.1, yend = Comp.2), x = 0, y = 0, arrow = arrow(angle = 15)) + geom_text_repel()+ theme_bw() 图 6-2-39 主成分矢量图 可以将降维的散点图与变量的载荷图画在同一坐标系内,如图 6-2-40 所示。 d <- as.data.frame(load1[,1:2]) d$vlabel <- rownames(d) ggplot() + geom_point(data = ps1, mapping = aes( x = Comp.1, y = Comp.2, color = Species), size =6.0, alpha = 0.6) + geom_segment(data = d, mapping = aes( xend = Comp.1, yend = Comp.2), x = 0, y = 0, arrow = arrow(angle = 20)) + geom_text_repel(data = d, mapping = aes( x = Comp.1, y = Comp.2, label = vlabel), alpha = 0.6)+ theme_bw() 图 6-2-40 降维后的矢量散点图