首发于 用R来上天的斑马
R语言缺失值处理

R语言缺失值处理

缺失数据的分类:

完全随机缺失:若某变量的缺失数据与其他任何观测或未观测变量都不相关,则数据为完全随机缺失(MCAR)。

随机缺失:若某变量上的缺失数据与其他观测变量相关,与它自己的未观测值不相关,则数据为随机缺失(MAR)。

非随机缺失:若缺失数据不属于MCAR或MAR,则数据为非随机缺失(NMAR) 。


处理缺失数据的方法有很多,但哪种最适合你,需要在实践中检验。

下面一副图形展示处理缺失数据的方法:



处理数据缺失的一般步骤:

1、识别缺失数据

2、检测导致数据缺失的原因

3、删除包含缺失值的实例或用合理的数值代替(插补)缺失值。


1、识别缺失数据:

R语言中,NA代表缺失值,NaN代表不可能值,Inf和-Inf代表正无穷和负无穷。

在这里,推荐使用is.na,is.nan,is.finite,is.infinite4个函数去处理。


complete.case() 可用来识别矩阵或数据框中没有缺失值的行

> library(VIM)
> data(sleep)
> View(sleep)
> sleep[!complete.cases(sleep),]
    BodyWgt BrainWgt NonD Dream Sleep Span Gest Pred Exp Danger
1  6654.000   5712.0   NA    NA   3.3 38.6  645    3   5      3
3     3.385     44.5   NA    NA  12.5 14.0   60    1   1      1
4     0.920      5.7   NA    NA  16.5   NA   25    5   2      3
13    0.550      2.4  7.6   2.7  10.3   NA   NA    2   1      2
14  187.100    419.0   NA    NA   3.1 40.0  365    5   5      5
19    1.410     17.5  4.8   1.3   6.1 34.0   NA    1   2      1
20   60.000     81.0 12.0   6.1  18.1  7.0   NA    1   1      1
21  529.000    680.0   NA   0.3    NA 28.0  400    5   5      5
24  207.000    406.0   NA    NA  12.0 39.3  252    1   4      1
26   36.330    119.5   NA    NA  13.0 16.2   63    1   1      1
30  100.000    157.0   NA    NA  10.8 22.4  100    1   1      1
31   35.000     56.0   NA    NA    NA 16.3   33    3   5      4
35    0.122      3.0  8.2   2.4  10.6   NA   30    2   1      1
36    1.350      8.1  8.4   2.8  11.2   NA   45    3   1      3
41  250.000    490.0   NA   1.0    NA 23.6  440    5   5      5
47    4.288     39.2   NA    NA  12.5 13.7   63    2   2      2
53   14.830     98.2   NA    NA   2.6 17.0  150    5   5      5
55    1.400     12.5   NA    NA  11.0 12.7   90    2   2      2
56    0.060      1.0  8.1   2.2  10.3  3.5   NA    3   1      2
62    4.050     17.0   NA    NA    NA 13.0   38    3   1      1


判断数据有多少缺失值

> sum(is.na(sleep))
[1] 38


针对复杂的数据集,怎么更好的探索数据缺失情况呢?

mice包 中的 md.pattern() 函数可以生成一个以矩阵或数据框形式展示缺失值模式的表格。

> library(mice)
> md.pattern(sleep)
   BodyWgt BrainWgt Pred Exp Danger Sleep Span Gest Dream NonD   
42       1        1    1   1      1     1    1    1     1    1  0
 2       1        1    1   1      1     1    0    1     1    1  1
 3       1        1    1   1      1     1    1    0     1    1  1
 9       1        1    1   1      1     1    1    1     0    0  2
 2       1        1    1   1      1     0    1    1     1    0  2
 1       1        1    1   1      1     1    0    0     1    1  2
 2       1        1    1   1      1     0    1    1     0    0  3
 1       1        1    1   1      1     1    0    1     0    0  3
         0        0    0   0      0     4    4    4    12   14 38

备注:0表示变量的列中没有缺失,1则表示有缺失值。

第一行给出了没有缺失值的数目(共多少行)。

第一列表示各缺失值的模式。

最后一行给出了每个变量的缺失值数目。

最后一列给出了变量的数目(这些变量存在缺失值)。

在这个数据集中,总共有38个数据缺失。


图形化展示缺失数据:

> aggr(sleep,prop=F,numbers=T)



> matrixplot(sleep)



浅色表示值小,深色表示值大,默认缺失值为红色。


2、缺失值数据的处理

行删除法:数据集中含有缺失值的行都会被删除,一般假定缺失数据是完全随机产生的,并且缺失值只是很少一部分,对结果不会造成大的影响。

即:要有足够的样本量,并且删除缺失值后不会有大的偏差!

行删除的函数有na.omit()和complete.case()

newdata<-na.omit(sleep)
newdata<-sleep[complete.cases(sleep),]


均值/中位数等填充:这种方法简单粗暴,如果填充值对结果影响不怎么大,这种方法倒是可以接受,并且有可能会产生令人满意的结果。


Hmisc包 更加简单,可以插补均值、中位数等,你也可以插补指定值。

> library(Hmisc)
> newdata<-sleep
> impute(newdata$Dream,mean)
> impute(newdata$Dream,median)
> impute(newdata$Dream,2)


mice包插补缺失数据: 链式方程多元插值,首先利用mice函数建模再用complete函数生成完整数据。

下图展示mice包的操作过程:


mice():从一个含缺失值的数据框开始,返回一个包含多个完整数据集对象(默认可以模拟参数5个完整的数据集)

with():可依次对每个完整数据集应用统计建模

pool():将with()生成的单独结果整合到一起

> library(mice)
> newdata<-sleep
> data<-mice(newdata,m=5,method = "pmm",maxit = 100,seed=1)

插补方法是pmm:预测均值匹配,可以用methods(mice)查看其他方法

maxit指迭代次数,seed指设定种子数(和set.seed同义)

> methods(mice)
 [1] mice.impute.2l.norm      mice.impute.2l.pan       mice.impute.2lonly.mean 
 [4] mice.impute.2lonly.norm  mice.impute.2lonly.pmm   mice.impute.cart        
 [7] mice.impute.fastpmm      mice.impute.lda          mice.impute.logreg      
[10] mice.impute.logreg.boot  mice.impute.mean         mice.impute.midastouch  
[13] mice.impute.norm         mice.impute.norm.boot    mice.impute.norm.nob    
[16] mice.impute.norm.predict mice.impute.passive      mice.impute.pmm         
[19] mice.impute.polr         mice.impute.polyreg      mice.impute.quadratic   
[22] mice.impute.rf           mice.impute.ri           mice.impute.sample      
[25] mice.mids                mice.theme              
see '?methods' for accessing help and source code


> summary(data)
Multiply imputed data set
Call:
mice(data = newdata, m = 5, method = "pmm", maxit = 100, seed = 1)
Number of multiple imputations:  5
Missing cells per column:
 BodyWgt BrainWgt     NonD    Dream    Sleep     Span     Gest     Pred      Exp   Danger 
       0        0       14       12        4        4        4        0        0        0 
Imputation methods:
 BodyWgt BrainWgt     NonD    Dream    Sleep     Span     Gest     Pred      Exp   Danger 
   "pmm"    "pmm"    "pmm"    "pmm"    "pmm"    "pmm"    "pmm"    "pmm"    "pmm"    "pmm" 
VisitSequence:
 NonD Dream Sleep  Span  Gest 
    3     4     5     6     7 
PredictorMatrix:
         BodyWgt BrainWgt NonD Dream Sleep Span Gest Pred Exp Danger
BodyWgt        0        0    0     0     0    0    0    0   0      0
BrainWgt       0        0    0     0     0    0    0    0   0      0
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
Gest           1        1    1     1     1    1    0    1   1      1
Pred           0        0    0     0     0    0    0    0   0      0
Exp            0        0    0     0     0    0    0    0   0      0
Danger         0        0    0     0     0    0    0    0   0      0
Random generator seed value:  1 

在这上面可以看到数据集中变量的观测值缺失情况,每个变量的插补方法, VisitSequence 从左至右展示了插补的变量, 预测变量矩阵 (PredictorMatrix)展示了进行插补过程的含有缺失数据的变量,它们利用了数据集中其他变量的信息。(在矩阵中,行代表插补变量,列代表为插补提供信息的变量, 1和0分别表示使用和未使用。)


查看整体插补的数据:

> data$imp

查看具体变量的插补数据:

> data$imp$Dream

最后,最重要的是生成一个完整的数据集

> completedata<-complete(data)
> head(completedata)
   BodyWgt BrainWgt NonD Dream Sleep Span Gest Pred Exp Danger
1 6654.000   5712.0  2.1   0.5   3.3 38.6  645    3   5      3
2    1.000      6.6  6.3   2.0   8.3  4.5   42    3   1      3
3    3.385     44.5 10.9   1.8  12.5 14.0   60    1   1      1
4    0.920      5.7 13.2   3.1  16.5  2.3   25    5   2      3
5 2547.000   4603.0  2.1   1.8   3.9 69.0  624    3   5      4
6   10.550    179.5  9.1   0.7   9.8 27.0  180    4   4      4

判断还有没有缺失值,如果没有,结果返回FLASE

> anyNA(completedata)


针对以上插补结果,我们可以查看原始数据和插补后的数据的分布情况

图上,插补值是洋红点呈现出的形状,观测值是蓝色点。


> densityplot(data)


图上,洋红线是每个插补数据集的数据密度曲线,蓝色是观测值数据的密度曲线

> stripplot(data,pch=12)

上图中,0代表原始数据,1-5代表5次插补的数据,洋红色的点代表插补值


下面我们分析对数据拟合一个线性模型:

完整数据:

> library(mice)
> newdata<-sleep
> data<-mice(newdata,m = 5,method=’pmm’,maxit=100,seed=1)
> model<-with(data,lm(Dream~Span+Gest))
> pooled<-pool(model)
> summary(pooled)
                     est         se          t       df     Pr(>|t|)        lo 95
(Intercept)  2.527581179 0.24068442 10.5016403 54.36478 1.065814e-14  2.045112117
Span        -0.005492745 0.01139327 -0.4821045 55.44497 6.316294e-01 -0.028321243
Gest        -0.003754241 0.00142867 -2.6277875 53.85804 1.117229e-02 -0.006618725
                    hi 95 nmis        fmi     lambda
(Intercept)  3.0100502401   NA 0.06699282 0.03328882
Span         0.0173357526    4 0.05569090 0.02223144
Gest        -0.0008897574    4 0.07184834 0.03801003


fim指的是各个变量缺失信息的比例,lambda指的是每个变量对缺失数据的贡献大小

缺失数据(在运行中,自动会行删除):

> lm.fit <- lm(Dream~Span+Gest, data = sleep,na.action=na.omit)