R初级数据管理——缺失值NA的处理

缺失值

在问卷数据或实验数据中,经常会包含由于未作答、设备故障或误编码数据的缘故出现缺失值。在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,不显示缺失值的占比或数量。

image

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个)。每个完整数据集都是通过对原始数据中的缺失数据进行插补而生成的。在每个完整的数据集上引用标准的统计方法,最后,把这些单独的分析结果整合为一组结果。

多重插补法大致分为三步:

  • 为每个空值产生一套可能的插补值,这些值反映了无响应模型的不确定性;每个值都被用来插补数据集中的缺失值,产生若干个完整数据集合。
  • 每个插补数据集合都用针对完整数据集的统计方法进行统计分析。
  • 对来自各个插补数据集的结果进行整合,产生最终的统计推断,这一推断考虑到了由于数据插补而产生的不确定性。该方法将空缺值视为随机样本,这样计算出来的统计推断可能受到空缺值的不确定性的影响。


    image

基于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分别表示使用和未使用。)

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,686评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,668评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,160评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,736评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,847评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,043评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,129评论 3 410
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,872评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,318评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,645评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,777评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,470评论 4 333
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,126评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,861评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,095评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,589评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,687评论 2 351

推荐阅读更多精彩内容