R语言实战:处理缺失数据的高级方法

目录

本文内容来自《R 语言实战》(R in Action, 2nd),有部分修改

介绍处理缺失值的几种常见方法

library(VIM)
library(mice)

处理缺失值的步骤

完全随机缺失 (MCAR)

随机缺失 (MAR)

非随机缺失 (NMAR)

识别缺失值

data(sleep, pakcage="VIM")

列出没有缺失值的行

sleep[complete.cases(sleep),]
   BodyWgt BrainWgt NonD Dream Sleep Span Gest Pred Exp Danger
2    1e+00    7e+00    6   2.0     8    4   42    3   1      3
5    3e+03    5e+03    2   1.8     4   69  624    3   5      4
6    1e+01    2e+02    9   0.7    10   27  180    4   4      4
7    2e-02    3e-01   16   3.9    20   19   35    1   1      1
8    2e+02    2e+02    5   1.0     6   30  392    4   5      4
...

列出至少有一个缺失值的行

sleep[!complete.cases(sleep),]
   BodyWgt BrainWgt NonD Dream Sleep Span Gest Pred Exp Danger
1    7e+03     5712   NA    NA     3   39  645    3   5      3
3    3e+00       44   NA    NA    12   14   60    1   1      1
4    9e-01        6   NA    NA    16   NA   25    5   2      3
13   6e-01        2    8   2.7    10   NA   NA    2   1      2
14   2e+02      419   NA    NA     3   40  365    5   5      5
19   1e+00       18    5   1.3     6   34   NA    1   2      1
...

TRUE 和 FALSE 分别等价于数值 1 和 0

sum(is.na(sleep$Dream))
12
mean(is.na(sleep$Dream))
0.2
mean(!complete.cases(sleep))
0.3

探索缺失值模式

列表显示缺失值

mice 包中的 md.pattern() 函数

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
9        1        1    1   1      1     1    1    1     0    0  2
3        1        1    1   1      1     1    1    0     1    1  1
2        1        1    1   1      1     1    0    1     1    1  1
1        1        1    1   1      1     1    0    1     0    0  3
1        1        1    1   1      1     1    0    0     1    1  2
2        1        1    1   1      1     0    1    1     1    0  2
2        1        1    1   1      1     0    1    1     0    0  3
         0        0    0   0      0     4    4    4    12   14 38

图形探究缺失数据

VIM 包的 aggr()matrixplot()marginplot() 函数

aggr() 函数绘制每个变量的缺失值数,同时绘制每个变量组合的缺失值数

aggr(sleep, prop=FALSE, numbers=TRUE)

生成每个实例的图形

matrixplot(sleep)

marginplot() 生成散点图,在边界展示两个变量的缺失值信息

marginplot(
  sleep[c("Gest", "Dream")],
  pch=c(20),
  col=c("darkgray", "red", "blue")
)

用相关性探索缺失值

影子矩阵:用 1 表示缺失,用 0 表示存在

x <- as.data.frame(abs(is.na(sleep)))
head(sleep, n=5)
  BodyWgt BrainWgt NonD Dream Sleep Span Gest Pred Exp Danger
1   7e+03     5712   NA    NA     3   39  645    3   5      3
2   1e+00        7    6     2     8    4   42    3   1      3
3   3e+00       44   NA    NA    12   14   60    1   1      1
4   9e-01        6   NA    NA    16   NA   25    5   2      3
5   3e+03     4603    2     2     4   69  624    3   5      4
head(x, n=5)
  BodyWgt BrainWgt NonD Dream Sleep Span Gest Pred Exp Danger
1       0        0    1     1     0    0    0    0   0      0
2       0        0    0     0     0    0    0    0   0      0
3       0        0    1     1     0    0    0    0   0      0
4       0        0    1     1     0    1    0    0   0      0
5       0        0    0     0     0    0    0    0   0      0

提取含(但不全是)缺失值的变量

y <- x[which(apply(x, 2, sum) > 0)]
cor(y)
       NonD Dream Sleep  Span  Gest
NonD   1.00  0.91  0.49  0.02 -0.14
Dream  0.91  1.00  0.20  0.04 -0.13
Sleep  0.49  0.20  1.00 -0.07 -0.07
Span   0.02  0.04 -0.07  1.00  0.20
Gest  -0.14 -0.13 -0.07  0.20  1.00
cor(sleep, y, use="pairwise.complete.obs")
          NonD Dream  Sleep  Span  Gest
BodyWgt   0.23  0.22  0.002 -0.06 -0.05
BrainWgt  0.18  0.16  0.008 -0.08 -0.07
NonD        NA    NA     NA -0.04 -0.05
Dream    -0.19    NA -0.189  0.12  0.23
Sleep    -0.08 -0.08     NA  0.10  0.04
Span      0.08  0.06  0.005    NA -0.07
Gest      0.20  0.05  0.160 -0.17    NA
Pred      0.05 -0.07  0.202  0.02 -0.20
Exp       0.25  0.13  0.261 -0.19 -0.19
Danger    0.07 -0.07  0.209 -0.07 -0.20

理解缺失数据的来由和影响

分析生成缺失数据的潜在机制

评价缺失数据对回答实质性问题的影响

理性处理不完整数据

推理方法会根据变量间的数学或逻辑关系来填补或恢复缺失值

完整示例分析 (行删除)

options(digits=1)
cor(na.omit(sleep))
         BodyWgt BrainWgt NonD Dream Sleep  Span  Gest  Pred  Exp Danger
BodyWgt     1.00     0.96 -0.4 -0.07  -0.3  0.47  0.71  0.10  0.4   0.26
BrainWgt    0.96     1.00 -0.4 -0.07  -0.3  0.63  0.73 -0.02  0.3   0.15
NonD       -0.39    -0.39  1.0  0.52   1.0 -0.37 -0.61 -0.35 -0.6  -0.53
Dream      -0.07    -0.07  0.5  1.00   0.7 -0.27 -0.41 -0.40 -0.5  -0.57
Sleep      -0.34    -0.34  1.0  0.72   1.0 -0.38 -0.61 -0.40 -0.6  -0.60
Span        0.47     0.63 -0.4 -0.27  -0.4  1.00  0.65 -0.17  0.3   0.01
Gest        0.71     0.73 -0.6 -0.41  -0.6  0.65  1.00  0.09  0.6   0.31
Pred        0.10    -0.02 -0.4 -0.40  -0.4 -0.17  0.09  1.00  0.6   0.93
Exp         0.41     0.32 -0.6 -0.50  -0.6  0.32  0.57  0.63  1.0   0.79
Danger      0.26     0.15 -0.5 -0.57  -0.6  0.01  0.31  0.93  0.8   1.00
fit <- lm(Dream ~ Span + Gest, data=na.omit(sleep))
summary(fit)
Call:
lm(formula = Dream ~ Span + Gest, data = na.omit(sleep))

Residuals:
   Min     1Q Median     3Q    Max 
-2.333 -0.915 -0.221  0.382  4.183 

Coefficients:
             Estimate Std. Error t value Pr(>|t|)    
(Intercept)  2.480122   0.298476    8.31  3.7e-10 ***
Span        -0.000472   0.013130   -0.04    0.971    
Gest        -0.004394   0.002081   -2.11    0.041 *  
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 1 on 39 degrees of freedom
Multiple R-squared:  0.167,	Adjusted R-squared:  0.125 
F-statistic: 3.92 on 2 and 39 DF,  p-value: 0.0282

多重插补

一种基于重复模拟的处理缺失值的方法。

library(mice)

含有插补数据集的列表对象,默认为 5 个

imp <- mice(sleep, seed=1234)
 iter imp variable
  1   1  NonD  Dream  Sleep  Span  Gest
  1   2  NonD  Dream  Sleep  Span  Gest
  1   3  NonD  Dream  Sleep  Span  Gest
  1   4  NonD  Dream  Sleep  Span  Gest
  1   5  NonD  Dream  Sleep  Span  Gest
  2   1  NonD  Dream  Sleep  Span  Gest
  2   2  NonD  Dream  Sleep  Span  Gest
...

为每个插补对象单独统计,本例中为计算线性回归

fit <- with(imp, lm(Dream ~ Span + Gest))

计算平均结果

pooled <- pool(fit)
summary(pooled)
         term estimate std.error statistic df p.value
1 (Intercept)    2.597     0.249      10.4 52   2e-14
2        Span   -0.004     0.012      -0.3 56   7e-01
3        Gest   -0.004     0.001      -3.0 55   5e-03

获取更多信息

imp
Class: mids
Number of multiple imputations:  5 
Imputation methods:
 BodyWgt BrainWgt     NonD    Dream    Sleep     Span     Gest     Pred 
      ""       ""    "pmm"    "pmm"    "pmm"    "pmm"    "pmm"       "" 
     Exp   Danger 
      ""       "" 
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:  5 
  it im  dep meth   out
1  3  2 Span  pmm Sleep
2  3  2 Gest  pmm Sleep
3  4  2 Span  pmm Sleep
4  4  2 Gest  pmm Sleep
5  4  4 Span  pmm Sleep

查看实际的插补值

imp$imp$Dream
     1   2   3   4   5
1  0.0 0.5 0.5 0.5 0.3
3  0.5 1.4 1.5 1.5 1.3
4  3.6 4.1 3.1 4.1 2.7
14 0.3 1.0 0.5 0.0 0.0
24 3.6 0.8 1.4 1.4 0.9
26 2.4 0.5 3.9 3.4 1.2
30 2.6 0.8 2.4 2.2 3.1
31 0.6 1.3 1.2 1.8 2.1
47 1.3 1.8 1.8 1.8 3.9
53 0.5 0.5 0.6 0.5 0.3
55 2.6 3.6 2.4 1.8 0.5
62 1.5 3.4 3.9 3.4 2.2

complete() 函数用于观察插补数据集

dataset3 <- complete(imp, action=3)
dataset3
   BodyWgt BrainWgt NonD Dream Sleep Span Gest Pred Exp Danger
1    7e+03    6e+03    3   0.5     3   39  645    3   5      3
2    1e+00    7e+00    6   2.0     8    4   42    3   1      3
3    3e+00    4e+01   11   1.5    12   14   60    1   1      1
4    9e-01    6e+00   13   3.1    16    7   25    5   2      3
5    3e+03    5e+03    2   1.8     4   69  624    3   5      4
...

处理缺失值的其他方法

成对删除

不推荐使用

cor(sleep, use="pairwise.complete.obs")
         BodyWgt BrainWgt NonD Dream Sleep  Span Gest  Pred  Exp Danger
BodyWgt     1.00     0.93 -0.4  -0.1  -0.3  0.30  0.7  0.06  0.3   0.13
BrainWgt    0.93     1.00 -0.4  -0.1  -0.4  0.51  0.7  0.03  0.4   0.15
NonD       -0.38    -0.37  1.0   0.5   1.0 -0.38 -0.6 -0.32 -0.5  -0.48
Dream      -0.11    -0.11  0.5   1.0   0.7 -0.30 -0.5 -0.45 -0.5  -0.58
Sleep      -0.31    -0.36  1.0   0.7   1.0 -0.41 -0.6 -0.40 -0.6  -0.59
Span        0.30     0.51 -0.4  -0.3  -0.4  1.00  0.6 -0.10  0.4   0.06
Gest        0.65     0.75 -0.6  -0.5  -0.6  0.61  1.0  0.20  0.6   0.38
Pred        0.06     0.03 -0.3  -0.4  -0.4 -0.10  0.2  1.00  0.6   0.92
Exp         0.34     0.37 -0.5  -0.5  -0.6  0.36  0.6  0.62  1.0   0.79
Danger      0.13     0.15 -0.5  -0.6  -0.6  0.06  0.4  0.92  0.8   1.00

简单 (非随机) 插补

用某个值 (如均值、中位数或众数) 替换变量中的缺失值。

尽量避免使用

参考

https://github.com/perillaroc/r-in-action-study

R 语言实战

图形初阶

基本数据管理

高级数据管理

基本图形

基本统计分析

回归

方差分析

中级绘图

重抽样与自助法

广义线性模型

主成分分析和因子分析

时间序列

聚类

分类