缺失值
在问卷数据或实验数据中,经常会包含由于未作答、设备故障或误编码数据的缘故出现缺失值。在R中,缺失值以符号NA(Not Available,不可用)表示。不可能出现的值(例如,被0除的结果) 通过符号NaN(Not a Number,非数值)来表示。
1. 缺失值得识别与可视化
首先我们来安装两个R包,VIM和mice包。
> install.packages(c("VIM","mice"))
本次分析使用的数据集sleep就是VIM包中包含的数据集,来源于Allison和Chichetti (1976)的研究。
自变量:生态学变量、体质变量
因变量:睡眠变量
生态学变量包含:物种被捕食程度(Pred),睡眠时的暴露程度(Exp),面临的总危险度(Danger)。体质变量包含:体重(BodyWgt,单位kg),脑重(BrainWgt,单位g),寿命(Span,单位年),妊娠期(Gest,单位为天)。
睡眠变量包含:做梦时长(Dream),不做梦时长(NonD)以及它们的和(Sleep)。
1.1 is.na( )函数
函数 is.na( ) 允许你检测缺失值是否存在,作用于一个对象上,也将返回一个相同大小的对象,如果某个元素是缺失值,相应的位置将被改写为TRUE,不是缺失值的位置则为FALSE。
> is.na(head(sleep))
BodyWgt BrainWgt NonD Dream Sleep Span Gest Pred Exp Danger
1 FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
2 FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
3 FALSE FALSE TRUE TRUE FALSE FALSE FALSE FALSE FALSE FALSE
4 FALSE FALSE TRUE TRUE FALSE TRUE FALSE FALSE FALSE FALSE
5 FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
6 FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
由图可以看出,所有显示TRUE的地方都是缺失值。
1.2 complete.cases( )函数
该可以用来识别矩阵或数据框中没有缺失值的行。若每行都包含完整实例,则返回TRUE的逻辑向量;若每行有一个或多个缺失值,则返回FALSE。
> complete.cases(head(sleep))
[1] FALSE TRUE FALSE FALSE TRUE TRUE
可以看出1、3、4行存在缺失值。
> head_sleep <- head(sleep)
> print(head_sleep[complete.cases(head_sleep)]) #只输出不含缺失值的列
BrainWgt Sleep Span Pred
1 5712.0 3.3 38.6 3
2 6.6 8.3 4.5 3
3 44.5 12.5 14.0 1
4 5.7 16.5 NA 5
5 4603.0 3.9 69.0 3
6 179.5 9.8 27.0 4
> head_sleep <- head(sleep)
> print(head_sleep[complete.cases(head_sleep),]) #只输出不含缺失值的行
BodyWgt BrainWgt NonD Dream Sleep Span Gest Pred Exp Danger
2 1.00 6.6 6.3 2.0 8.3 4.5 42 3 1 3
5 2547.00 4603.0 2.1 1.8 3.9 69.0 624 3 5 4
6 10.55 179.5 9.1 0.7 9.8 27.0 180 4 4 4
1.3 md.pattern( ) 函数
mice包中的md.pattern,形成缺失表。
> md.pattern(head_sleep)
BodyWgt BrainWgt Sleep Gest Pred Exp Danger Span NonD Dream
3 1 1 1 1 1 1 1 1 1 1 0
2 1 1 1 1 1 1 1 1 0 0 2
1 1 1 1 1 1 1 1 0 0 0 3
0 0 0 0 0 0 0 1 3 3 7
1.4 aggr ( ) 函数
aggr ( ) 是VIM包中的函数,可以形成缺失图。
aggr(sleep, prop = F, number = T) #表示用数字而不是比例
prob:当为TRUE时,显示为缺失值的占比;当为FALSE时,显示为缺失值的数量;
number:是否显示数值,默认为FALSE,不显示缺失值的占比或数量。
2. 缺失值的处理
2.1 推理恢复
根据变量之间的关系来填补或恢复缺失值,通过推理,数据的恢复可能是准确的或近似的。
2.2 行删除
把包含一个或多个缺失值的行删除,称作行删除法,或个案删除,大部分统计软件包默认采用的是行删除法。
通过函数 na.omit( ) 移除所有含有缺失值的观测。na.omit( ) 可以删除所有含有缺失数据的行。
na.omit(head_sleep)
BodyWgt BrainWgt NonD Dream Sleep Span Gest Pred Exp Danger
2 1.00 6.6 6.3 2.0 8.3 4.5 42 3 1 3
5 2547.00 4603.0 2.1 1.8 3.9 69.0 624 3 5 4
6 10.55 179.5 9.1 0.7 9.8 27.0 180 4 4 4
2.3 简单插补
当然,我们有时并不想把缺失的行直接删除,因为这样难以避免造成了数据的损失。简单插补是用均值,中位数或众数来替换变量中缺失的值。将初始数据集中的属性分为数值属性和非数值属性来分别进行处理。
如果空值是数值型的,就根据该属性在其他所有对象的取值的平均值来填充该缺失的属性值;
如果空值是非数值型的,就根据统计学中的众数原理,用该属性在其他所有对象的取值次数最多的值(即出现频率最高的值)来补齐该缺失的属性值。
2.4 高级插补
对缺失值的高级处理方式有很多,大致有回归插补、多重插补、热卡插补,K最近距离邻法等等,现在只介绍多重插补的原理:
多重插补(MI)是一种基于重复模拟的处理缺失值的方法,它从一个包含缺失值的数据集中生成一组数据完整的数据集(即不包含缺失值的数据集,通常是3-10个)。每个完整数据集都是通过对原始数据中的缺失数据进行插补而生成的。在每个完整的数据集上引用标准的统计方法,最后,把这些单独的分析结果整合为一组结果。
多重插补法大致分为三步:
- 为每个空值产生一套可能的插补值,这些值反映了无响应模型的不确定性;每个值都被用来插补数据集中的缺失值,产生若干个完整数据集合。
- 每个插补数据集合都用针对完整数据集的统计方法进行统计分析。
对来自各个插补数据集的结果进行整合,产生最终的统计推断,这一推断考虑到了由于数据插补而产生的不确定性。该方法将空缺值视为随机样本,这样计算出来的统计推断可能受到空缺值的不确定性的影响。
基于mice包的分析通常符合以下分析过程:
library(mice)
imp <- mice(data seed=m)
fit <- with( imp, lm())
po<- pool(fit)
summary(po)
- mydata是一个包含缺失值的矩阵或数据框。
- imp是一个包含m个插补数据集的列表对象,同时还含有完成插补过程的信息。默认地, m为5。
- analysis是一个表达式对象,用来设定应用于m个插补数据集的统计分析方法。方法包括做线性回归模型的 lm() 函数、做广义线性模型的 glm() 函数、做广义可加模型的 gam(),以及做负二项模型的nbrm()函数。表达式在函数的括号中,~的左边是响应变量, 右边是预测变量(用+符号分隔开)。
- fit是一个包含m个单独统计分析结果的列表对象。
- pooled是一个包含这m个统计分析平均结果的列表对象。
现在我们尝试插补之前的sleep数据:
library(mice)
data(sleep,package="VIM")
imp<-mice(sleep,seed=1234)
fit<-with(imp,lm(Dream~Span+Gest))
pooled<-pool(fit)
summary(pooled)
完全按照上面的抄就可以,summary之后可以看到:
summary(pooled)
term estimate std.error statistic df p.value
1 (Intercept) 2.531560872 0.260063277 9.7344035 44.41076 1.379785e-12
2 Span -0.004478330 0.011716849 -0.3822128 55.79406 7.037555e-01
3 Gest -0.004022046 0.001481345 -2.7151303 53.29365 8.909314e-03
可以通过检查分析过程所创建的对象来获取更多的插补信息。例如,来看imp对象的汇总信息:
imp
Class: mids
Number of multiple imputations: 5
Imputation methods:
BodyWgt BrainWgt NonD Dream Sleep Span Gest Pred Exp Danger
"" "" "pmm" "pmm" "pmm" "pmm" "pmm" "" "" ""
PredictorMatrix:
BodyWgt BrainWgt NonD Dream Sleep Span Gest Pred Exp Danger
BodyWgt 0 1 1 1 1 1 1 1 1 1
BrainWgt 1 0 1 1 1 1 1 1 1 1
NonD 1 1 0 1 1 1 1 1 1 1
Dream 1 1 1 0 1 1 1 1 1 1
Sleep 1 1 1 1 0 1 1 1 1 1
Span 1 1 1 1 1 0 1 1 1 1
Number of logged events: 7
it im dep meth out
1 1 1 Span pmm Sleep
2 1 1 Gest pmm Sleep
3 2 4 Span pmm Sleep
4 2 4 Gest pmm Sleep
5 2 5 Span pmm Sleep
6 2 5 Gest pmm Sleep
从输出结果可以看到,五个数据集同时被创建,预测均值(pmm)匹配法被用来处理每个含 缺失数据的变量。BodyWgt、BrainWgt、Pred、Exp和Danger没有进行插补(" "),因为它们并没有缺失数据。VisitSequence从左至右展示了插补的变量,从NonD开始,以Gest结束。最后,预测变量矩阵(PredictorMatrix)展示了进行插补过程的含有缺失数据的变量,它们利 用了数据集中其他变量的信息.(在矩阵中,行代表插补变量,列代表为插补提供信息的变量,1 和0分别表示使用和未使用。)