在决定如何处理缺失数据之前,了解哪些变量有缺失值、数目有多少、是什么组合形式等信息非常有用。这里我们将介绍探索缺失值模式的图标及相关方法。
列表显示缺失值
之前已经学习了一些识别缺失值的基本方法,如使用complete.cases()函数列出完整的实例,或者相反,列出含一个或多个缺失值的实例。但随着数据集的增大,这样的方法就逐渐丧失了吸引力。此时我们可以转向其他R函数。
mice包中的md.pattern()函数可以生成一个以矩阵或数据框形式展示缺失值模式的表格。将函数应用到sleep数据集,可得到:
表中1和0显示了缺失值模式,0表示变量的列中有缺失值,1则表示没有缺失值。第一行表述了“无缺失值”的模式(所有元素都为1)。第二行表述了“除Span之外无缺失值”的模式。第一列表示各缺失值模式的实例个数,最后一列白哦是各模式中有缺失值的变量的个数。此处可以看到,有42个实例没有缺失值,仅2个实例缺失了Span。9个实例同时缺失了NonD和Dream的值。数据集包含了总共(42*0)+(2*1)+...+(1*3)=38个缺失值。最后一行给出了每个变量中缺失值的数目。
图形探索缺失数据
虽然md.pattern()函数的表格输出非常简洁,但我们通常觉得用图形展示模式更为清晰。VIM包提供了大量能可视化数据集中缺失值模式的函数,例如:aggr()、matrixolot()和scattMiss()
aggr()函数不仅绘制每个变量的缺失值数,还绘制每个变量组合的缺失值数。例如:
> library("VIM")
> aggr(sleep, prop=FALSE, numbers=TRUE)
可以看到,变量NonD有最大的缺失值数(14),有2个哺乳动物缺失了NonD、Dream和Sleep的评分。42个动物没有缺失值。
代码aggr(sleep,prop=TRUE,numbers=TRUE)将生成相同的图形,但用比例代替了计算,选项numbers=FALSE(默认)删去了数值型标签。
matrixplot()函数可生成展示每个实例数据的图形:
> matrixplot(sleep)
此处,数值型数据被重新转换到[0,1]区间,并用灰度来表示大小:浅色表示值小,深色表示值大。默认缺失值为红色。注意,图中红色已经被手工阴影化处理,因此相对于灰色缺失值将非常显眼。我们可以自己创建图形,让它与众不同。
该图形可以进行交互,单击一列将会按其对应的变量重排矩阵。图中的行便按BodyWgt降序排列。通过矩阵图,我们可以看出某些变量的缺失值模式是否与其他变量的真实值有关联。此图中可以看到,无缺失值的睡眠变量(Dream、NonD和Sleep)对应着较小的体重(BodyWgt)或脑重(VrainWgt)。
marginplot()函数可以生成一幅散点图,在图形边界展示两个变量的缺失值信息。以做梦时长与哺乳动物妊娠期时长的关系为例,来看以下代码:
>marginplot(sleep[c("Gest","Dream")],pch = c(20),col = c("darkgray","red","blue"))
参数pch和col为可选项,控制着绘图符号和使用的颜色。
图形的主体是Gest和Dream(两变量数据都完整)的散点图。左边界的箱线图展示的是包含(深灰色)与不包含(红色)Gest值的Dream变量分布。注意,在灰度图上红色是更深的阴影。四个红点代表着缺失了Gest得分的Dream值。在底部边界,Gest和Dream间的关系反过来了。可以看到,妊娠期和做梦时长呈负相关,缺失妊娠期数据时动物的做梦时长一般更长。两个变量均有缺失值的观测个数在两边界交叉处(左下角)用蓝色输出。
VIM包有许多图形可以帮助我们理解缺失数据在数据集中的模式,包括散点图、箱线图、直方图、散点图矩阵、平行坐标图、轴须图和气泡图来展示缺失值的信息。
用相关性探索缺失值
我们可用指示变量替代数据集中的数据(1表示缺失,0表示存在),这样生成的矩阵有时被称作影子矩阵。求这些指示变量间和它们初始(可观测)变量间的相关性,有助于观察哪些变量常一起缺失,以及分析变量“缺失”与其他变量间的关系。
考虑如下代码:
> x <- as.data.frame(abs(is.na(sleep)))
若sleep的元素缺失,则数据框x对应的元素为1,否则为0.我们可以观察一下数据的前几行:
以下代码:
> sd=sapply(x,sd)
> y<-x[which(sd>0)]
可提取含(但不全部是)缺失值的变来那个,而
> cor(y)
可列出这些指示变量间的相关系数:
NonD Dream Sleep Span Gest
NonD 1.00000000 0.90711474 0.48626454 0.01519577 -0.14182716
Dream 0.90711474 1.00000000 0.20370138 0.03752394 -0.12865350
Sleep 0.48626454 0.20370138 1.00000000 -0.06896552 -0.06896552
Span 0.01519577 0.03752394 -0.06896552 1.00000000 0.19827586
Gest -0.14182716 -0.12865350 -0.06896552 0.19827586 1.00000000
此时,我们可以看到Dream和NonD常常一起缺失(r=0.91)。相对可能性较小的是Sleep和NonD一起缺失(r=0.49),以及Sleep和Dream(r=0.20)。
最后,我们可以看到含缺失值变量与其他可观测变量间的关系:
> cor(sleep,y,use = "pairwise.complete.obs")
NonD Dream Sleep Span Gest
BodyWgt 0.22682614 0.22259108 0.001684992 -0.05831706 -0.05396818
BrainWgt 0.17945923 0.16321105 0.007859438 -0.07921370 -0.07332961
NonD NA NA NA -0.04314514 -0.04553485
Dream -0.18895206 NA -0.188952059 0.11699247 0.22774685
Sleep -0.08023157 -0.08023157 NA 0.09638044 0.03976464
Span 0.08336361 0.05981377 0.005238852 NA -0.06527277
Gest 0.20239201 0.05140232 0.159701523 -0.17495305 NA
Pred 0.04758438 -0.06834378 0.202462711 0.02313860 -0.20101655
Exp 0.24546836 0.12740768 0.260772984 -0.19291879 -0.19291879
Danger 0.06528387 -0.06724755 0.208883617 -0.06666498 -0.20443928
Warning message:
In cor(sleep, y, use = "pairwise.complete.obs") : 标准差为零
在这个相关系数矩阵中,行代表可观测变量,列代表缺失的指示标量。从相关系数矩阵的第一列可以看到,体重越大(r=0.227)、妊娠期越长(r=0.202)、睡眠暴露度越大(r=0.245)的动物无梦睡眠的评分更可能缺失。其他列的信息也可以按照类似方式得出。注意,表中的相关系数并不特别大,表明数据是MCAR(完全随机缺失)的可能性比较小,更可能为MAR(随机缺失)。
不过也绝不能排除数据是NMAR(非随机缺失)的可能性,因为我们并不知道缺失数据背后对应的真实数据是怎么样的。当缺乏强力的外部证据时,我们通常假设数据时MCAR和MAR。