一、判断缺失数据
在R语言中缺失值通常以NA表示,判断是否缺失值的函数是is.na。另一个常用到的函数是complete.cases,它对数据框进行分析,判断某一观测样本是否完整。下面我们读取VIM包中的sleep数据作为例子,它的样本数为62,变量数为10,由complete.cases函数计算可知完整的样本个数为42。
----------------------
data(sleep, package="VIM")
dim(sleep)
sum(complete.cases(sleep))
----------------------
二、探索缺失数据的模式
存在缺失数据情况下,需进一步判断缺失数据的模式是否随机。在R中是利用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
上表中的1表示没有缺失数据,0表示存在缺失数据。第一列第一行的42表示有42个样本是完整的,第一列最后一行的1表示有一个样本缺少了span、dream、nond三个变量,最后一行表示各个变量缺失的样本数合计。
此外还可以使用vim包的aggr函数以图形方式描述缺失数据
----------------------
aggr(sleep)
----------------------
上面的左图显示各变量缺失数据比例,右图显示了各种缺失模式和对应的样本数目,显示nond和dream经常同时出现缺失值。
三、处理缺失数据
- 删除缺失数据样本,其前提是缺失数据的比例较少,而且缺失数据是随机出现的,这样删除缺失数据后对分析结果影响不大。
- 用变量均值或中位数来代替缺失值,其优点在于不会减少样本信息,处理简单。但是缺点在于当缺失数据不是随机出现时会产成偏误。
- 多重插补法(Multiple imputation):多重插补是通过变量间关系来预测缺失数据,利用蒙特卡罗方法生成多个完整数据集,再对这些数据集分别进行分析,最后对这些分析结果进行汇总处理。在R语言中实现方法是使用mice包中的mice函数,生成多个完整数据集存在imp中,再对imp进行线性回归,最后用pool函数对回归结果进行汇总。汇总结果的前面部分和普通回归结果相似,nmis表示了变量中的缺失数据个数,fmi表示fraction of missing information,即由缺失数据贡献的变异。
library(mice)
imp=mice(sleep,seed=1234)
fit=with(imp,lm(Dream~Span+Gest))
pooled=pool(fit)
summary(pooled)
----------------------
参考资料:R in Action
求指教:
回复删除提一个初级数据处理的问题。
我从SAS转出一个数据文件(csv)对象人数12万人左右,变量数超过700. csv文件是可以用excel打开,但是略改动一下就很耗时间(电脑的问题还是excel的问题?),我的问题是,转出的文件中缺失值都是用点表示(“.")差不多有好几百个变量中都有缺失值。 该如何在R环境下转换成NA呢。
可以先将这个csv读入R中,转成统一的字符矩阵x,然后用下面的命令
删除x[x==“."] <- NA
但我担心的是,这个CSV文件可以过大,读不进R里头去。如果读不了的话再试试R的一些大矩阵处理函数。
问题搞定,看来还不算太大,先读成字符矩阵,然后转换成NA。
删除感激不尽~
希望请教楼主,当缺失值比例达到多少时采用imputation的方法比较妥当?毕竟直接采用imputation,采用什么模型imputation,生成数据是否合理会引发争议。
回复删除这个我也只是初步涉及,还在看文献,还没有总结出来。
删除肖凯兄,我想问在R里面对一些非正态的连续型缺失值,缺失比例较大时,有什么好的处理办法
回复删除缺失比例较大的话,看能否通过其它变量来预测查补。但如果说其它变量可以很好的补充这个缺失变量的话,这个变量也就是冗余的,意义不大了。
删除請問一下,我若在R中想找出我的missing是第幾筆,使用while...do....until的迴圈,應如何順利顯示出? 謝謝
回复删除sapply(df, function(x) sum(is.na(x)))
删除