第18章 处理缺失数据的高级方法

# 目的:识别缺失数据;检查导致数据缺失的原因;删除包含的缺失值的实例或用合理的数值代替(插补)缺失值
#主要包: mice包
#主要数据集:VIM包中的sleep数据集

18.1 处理缺失值流程

1.识别缺失值

2.检查导致出局缺失的原因

3.删除包含缺失值的实例或用合理的值代替缺失值

18.2 识别缺失值 

NA(不可得)代表缺失值,NaN(不是一个数)代表不可能的值。另外,符号Inf和-Inf分别代表正无穷和负无穷。函数is.na()、is.nan()和is.infinite()可分别用来识别缺失值、不可能值和无穷值。每个返回结果都是TRUE或FALSE。

#complete.cases()函数可以用来是被矩阵或者数据框中有无缺失值的行
library(VIM)
data(sleep,package="VIM")
complete.cases(sleep)

#注意complete.cases()函数将Na和NaN识别为缺失值,无穷值被当做有效值
sleep1 <- sleep[complete.cases(sleep),]  #列出没有缺失值的行
sleep2 <- sleep[!complete.cases(sleep),] #列出有缺失值的行
str(sleep1) #42行完整数据
str(sleep2) #20行含有缺失值的数据

sum(is.na(sleep$Dream))   #Dream中含有缺失值的个数
mean(is.na(sleep$Dream)) #Dream中含有缺失值的比例
mean(!complete.cases(sleep))  #含有缺失值的行所占比例

18.3 探索缺失值模式

18.3.1 列表显示缺失值

library(mice)
data(sleep,package="VIM")
mice::md.pattern(sleep)

R语言去空 r语言去掉空数据_缺失值

    

R语言去空 r语言去掉空数据_缺失值_02



18.3.2 图形探究缺失数据

#方法1

library(VIM)
aggr(sleep,prop=FALSE,number=TRUE)

R语言去空 r语言去掉空数据_数据集_03

#方法2

matrixplot(sleep)

R语言去空 r语言去掉空数据_r语言_04


#方法3
marginplot(sleep[c("Gest","Dream")],pch = c(20),
           col = c("darkgrey","red","blue"))

R语言去空 r语言去掉空数据_R语言去空_05

18.3.3 用相关性探索缺失值

可用指示变量替代数据集中的数据(1表示缺失,0表示存在),这样生成的矩阵有时称作影子矩阵。求这些指示变量间和它们与初始(可观测)变量间的相关性,有助于观察哪些变量常一起缺失,以及分析变量“缺失”与其他变量间的关系。

head(sleep)
x <- as.data.frame(abs(is.na(sleep)))
x
#若sleep的元素缺失,则数据框x对应的元素为1,否则为0

R语言去空 r语言去掉空数据_数据集_06

 y <- x[which(apply(x, 2, sum)>0)]

# apply中2表示对列进行运算 此处是找出列之和大于0的 

R语言去空 r语言去掉空数据_缺失值_07

cor(y)

# cor(y) 对存在缺失值的项进行相关性分析 可以看到NonD常常与Dream一起缺失 r=0.907

R语言去空 r语言去掉空数据_数据_08

cor(sleep,y,use = "pairwise.complete.obs")

#进行含缺失值变量与其它可观测变量之间的关系分析;
#在相关系数矩阵中行表示可观测变量,列表示指代变量。表中相关系数并不特别大,表明数据是完全随机确实的可能性较小,更可能是随机缺失;
#当缺乏强有力的外部证据时,我们通常假设数据是完全随机缺失或随机缺失;

R语言去空 r语言去掉空数据_缺失值_09

# 可以忽略矩阵中的警告信息和NA值 这是因为我们选择了pairwise.complete.obs认为因素导致的

 注意:回顾!!!

相关系数计算基本形式:cor(x,use="“,method=“ ”)

x :  矩阵或数据框

use : 指定缺失数据的处理方式。可选的方式为all.obs(假设不存在缺失数据——遇到缺失数据时将报错)、everything(默认,遇到缺失数据时,相关系数的计算结果将被设为missing)、complete.obs(行删除)以及 pairwise.complete.obs(成对删除,pairwise deletion)

method : 指定相关系数的类型。可选类型为pearson、spearman或kendll住y

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

识别缺失数据的数目、分布和模式有两个目的:

(1)分析生成缺失数据的潜在机制;

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


具体来讲,我们想弄清楚以下几个问题。
缺失数据的比例多大?
缺失数据是否集中在少数几个变量上,抑或广泛存在?
缺失是随机产生的吗?
缺失数据间的相关性或与可观测数据间的相关性,是否可以表明产生缺失值的机制呢?

回答这些问题将有助于判断哪种统计方法最适合用来分析你的数据。

假使已经知道了缺失数据的来源和影响,那么让我们看看如何转换标准的统计方法来适应缺失数据的分析。我们将重点学习三种非常流行的方法:恢复数据的推理方法、涉及删除缺失值的传统方法、涉及模拟的现代方法

18.5 理性处理不完整数据

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

推理研究法常常需要创造性和想法,同时还需要许多数据处理技巧,而且数据的恢复可能是准确的或者近似的。

18.6 完整实例分析(行删除)

只有每个变量都包含了有效数据值的观测才会保留下来做进一步的分析。

实际上,这样会导致包含一个或多个缺失值的任意一行都会被删除,因此常称作行删除法(listwise)、个案删除(case-wise)或剔除。

newdata <- mydata[complete.cases(mydata),]
newdata <- na.omit(mydata)
两行代码表示的意思都是:mydata中所有包含缺失数据的行都被删除,然后结果才存储到newdata中。

#假设我们对睡眠研究中变量间的关系感兴趣,计算相关系数前,可以使用行删除法
#删除包含缺失值的所有行
options <- (digits=1)
cor(na.omit(sleep))

fit <- lm(Dream~Span+Gest,data = na.omit(sleep))
summary(fit) #整个分析基于有完整数据的42个实例

fit1 <- lm(Dream~Span+Gest,data = sleep)
summary(fit1) #整个分析基于有Dream+Span+Gest数据的44个实例;若仅损失其它数据但是Dream+Span+Gest仍然含有,则不会被删除

R语言去空 r语言去掉空数据_缺失值_10

R语言去空 r语言去掉空数据_数据_11

R语言去空 r语言去掉空数据_数据集_12

18.7 多重插补法 

多重插补(MI)是一种基于重复模拟的处理缺失值的方法。在面对复杂的缺失值问题时,MI是最常选用的方法,它将从一个包含缺失值的数据集中生成一组完整的数据集(通常是3到10个)。每个模拟数据集中,缺失数据将用蒙特卡洛方法来填补。此时,标准的统计方法便可应用到每个模拟的数据集上,通过组合输出结果给出估计的结果,以及引入缺失值时的置信区间。R中可利用Amelia、mice和mi包来执行这些操作。本节中,我们将重点学习mice包(利用链式方程的多元插补)提供的方法。

基于mice包的分析通常符合以下分析过程:
library(mice)
imp <- mice(data, m)
fit <- with(imp, analysis)
pooled <- pool(fit)
summary(pooled)
 mydata是一个包含缺失值的矩阵或数据框。
 imp是一个包含m个插补数据集的列表对象,同时还含有完成插补过程的信息。默认m为5。
 analysis是一个表达式对象,用来设定应用于m个插补数据集的统计分析方法。方法包括做线性回归模型的lm()函数、做广义线性模型的glm()函数、做广义可加模型的gam(),以及做负二项模型的nbrm()函数。表达式在函数的括号中,~的左边是响应变量,右边是预测变量(用+符号分隔开)。
 fit是一个包含m个单独统计分析结果的列表对象。
 pooled是一个包含这m个统计分析平均结果的列表对象。

library(mice)
data("sleep",package="VIM")
imp <- mice(sleep,seed = 1234)
fit <- with(imp,lm(Dream~Span+Gest))
pooled <- pool(fit)
summary(pooled)

#此时的结果与18.6#整个分析基于有完整数据的42个实例结果完全不一样 span不显著但是gest显著

R语言去空 r语言去掉空数据_缺失值_13

 

R语言去空 r语言去掉空数据_数据_14

#获得更多插补信息
imp

R语言去空 r语言去掉空数据_数据_15


#观测实际的插补值


imp$imp$Dream

R语言去空 r语言去掉空数据_数据集_16

#展示多重插补过程中创建的某个完整数据集
datase3 <- complete(imp,action=3)
datase3

#利用 complete() 函数可以观察m个插补数据集中的任意一个。格式为:complete(imp, action=*),其中 * 指定m个完整数据集中的一个来展示。

R语言去空 r语言去掉空数据_R语言去空_17

18.8 其它处理缺失值的方法

R语言去空 r语言去掉空数据_数据集_18

15.8.1 成对删除

处理含缺失值的数据集时,成对删除常作为行删除的备选方法使用。对于成对删除,观测只是当它含缺失数据的变量涉及某个特定分析时才会被删除。

15.8.2 简单(非随机)插补

所谓简单插补,即用某个值(如均值、中位数或众数)来替换变量中的缺失值。若使用均值替换,Dream变量中的缺失值可用1.97来替换,NonD中的缺失值可用8.67来替换(两个值分别是Dream和NonD的均值)。注意这些替换是非随机的,这意味着不会引入随机误差(与多重插补不同)。
简单插补的一个优点是,解决“缺失值问题”时不会减少分析过程中可用的样本量。虽然简单插补用法很简单,但是对于非MCAR的数据会产生有偏的结果。若缺失数据的数目非常大,那么简单插补很可能会低估标准差、曲解变量间的相关性,并会生成不正确的统计检验的p值。与成对删除一样,我建议在解决缺失数据的问题时尽量避免使用该方法。