函数is.na()允许你检测缺失值是否存在。该函数作用于检测对象之后将返回一个相同大小的对象,其中缺失值的位置被改写为true,其他不是缺失值的位置则为false。
> which(is.na(nhanes2)) #返回缺失值的位置
> sum(is.na(nhanes2)) #计算数据集nhanes2中的缺失值总数
> sum(complete.cases(nhanes2)) #统计数据集中完整样本的个数
可以通过md.pattern()获取缺失值的分布情况(mice包),其中1表示没有缺失数据,0表示存在缺失数据:
第一行第一列的13表示有13个样本数据是完整的,倒数第二行7表示有7个样本少了hyp、bmi、chl三个变量,最后一行表示各个变量缺失的样本数合计。
确定缺失值以后要在分析数据前删除这些缺失值。因为含有缺失值的算术表达式和函数的计算结果也是缺失值。
一些函数计算时拥有na.rm=TRUE,可以在计算以前移除缺失值并使用剩余值进行计算;可以通过函数complete.cases()检查变量中至少含有一个缺失数据的观测值的个数。函数compete.cases()产生一个布尔值向量,该向量的元素个数与数据框中的行数相同,如果数据框的响应行中不含NA值,函数返回值就是TRUE。
函数na.omit()移除所有含有缺失值的观测,na.omit()可以删除所有含有缺失数据的行。但踢出所有包含缺失值记录的方法是很极端的,这样处理缺失值太多的样本则样本数据几乎没有意义。
manyNAs(algae,0.2)可以找出数据集algae中缺失值个数大于列数20%的行,第二个参数中可以设置一个精确的列数作为界限。
填补含有缺失值记录的另一个方法是尝试找到这些缺失值最可能的值。对于变量分布近似正态分布时可以选用平均值;偏态分布一般采用中位数代表数据中心趋势的指标。
样本algae第48行变量mxPH有缺失值,该变量分布近似正态分布,采用平均值填补缺失值:
> algae[48,"mxPH"] <- mean(algae$mxPH,na.rm = T)
其中mean()计算数值向量的平均数。
对变量Chla使用中位数填补该列中的所有缺失值而不是像上面一样一行一行的逐个填补:
> algae[is.na(algae$Chla),"Chla"] <- median(algae$Chla,na.rm = T)
函数centralImputation()可以用数据的中心趋势值来填补数据集的所有缺失值:
> algae <- centralImputation(algae)
数值变量用中位数,名义变量采用众数。这种方法简单快速,适用于大数据集,但可能导致较大的数据偏差。
通过探寻变量值之间的相关关系获取缺失值较少偏差估计值。函数cor()的功能是产生变量之间的相关值矩阵,以下可以得到变量间的相关值:
> cor(algae[,4:18],use = "complete.obs")
参数use = "complete.obs"可以忽略含有NA的记录,另外函数symnum()可以输出用符号表示相关值的形式。测试数据集中,相关值大于0.9的两个变量可以通过相关性填补这两个变量的缺失值。以P04和oP04为例,需要先找到这两个变量之间的线性相关关系:
> lm(PO4~oPO4,data = algae)
函数lm()可以用来获取线性模型。得到PO4=42.897+1.293*oPO4
可以使用上述线性关系计算变量的缺失值,填补样本28在变量PO4上的缺失值:
> algae[28,"PO4"] <- 42.897+1.293*algae[28,"oPO4"]
可以构造函数对所有缺失值应用这个函数:
尝试使用行(观察值)之间的相似性来填补缺失值。相似性经常由描述观测值的多元度量空间的变量所定义,其中欧氏距离可以非正式地定义为任何两个案例的观测值之差的平方和。可以使用这种度量寻找与任何含有缺失值得案例最相似的10个水样并用他们来填补缺失值。
应用函数 knnImputation(),用中位数来填补缺失值:
> algae<- knnImputation(algae,k=10,meth = "median")
其中参数meth可选。通过个案之间的相似性填补缺失值也存在其他问题:可能存在不相关的变量扭曲相似性,甚至造成大型数据集的计算特别复杂等问题。
> donate <- nhanes2[which(apply(is.na(nhanes2),1,sum)==0),]
#无缺失值的样本
> accept <-nhanes2[which(apply(is.na(nhanes2),1,sum)!=0),]
#存在缺失值的样本
> sa <- donate[which(donate[,1]==accept[2,1]&donate[,3]==accept[2,3]&donate[,4]==accept[2,4]),]
对accept中的第二个样本accept[2, ]做缺失值处理,寻找与其相似的样本后,用找到的样本的对应值替代缺失值:
> sa<-donate[which(donate[,1]==accept[2,1]&donate[,3]==accept[2,3]&donate[,4]==accept[2,4]),]
实际操作时若数据量过大,可以按照某些变量将数据分层,在层中对缺失值使用均值插补,即采用冷平台插补方式。