1.判断缺失值
函数:is.na()、complete.cases()
complete.cases()可用来识别矩阵或数据框中没有缺失值的行!可呈现出有缺失值的行sleep[!complete.cases(sleep),]
###2.针对复杂的数据集,需要探索数据缺失情况
(1)用列表显示缺失值
mice包中的md.pattern()函数可以生成一个以矩阵或数据框形式展示缺失值模式的表格。
library(mice)
library(VIM) #以VIM包中sleep数据集为例
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
-
备注:
-
0表示变量的列中没有缺失,1则表示有缺失值。
第一行给出了没有缺失值的数目(共多少行)。
第一列表示各缺失值的模式。
最后一行给出了每个变量的缺失值数目。
最后一列给出了变量的数目(这些变量存在缺失值)。
在这个数据集中,总共有38个数据缺失。
(2)用图形显示缺失值
VIM包中提供大量能可视化数据集中缺失值模式的函数:aggr()、matrixplot()、scattMiss()。
library(VIM)
aggr(sleep,prop=FALSE,numbers=TRUE)
#(prop为FALSE表示计数,TRUE则表示比例)
matrixplot(sleep) #此函数可生成展示每个实例数据的图形
浅色表示值小,深色表示值大;默认缺失值为红色。
###3.缺失值数据的处理
(1)行删除法:数据集中含有缺失值的行都会被删除,一般假定缺失数据是完全随机产生的,并且缺失值只是很少一部分,对结果不会造成大的影响。意思就是只要有足够的样本量,并且删除缺失值后不会有大的偏差!
行删除的函数有na.omit()和complete.case()
newdata1<-na.omit(sleep)
sum(is.na(newdata1)) #计算还有多少缺失值
newdata2<-sleep[complete.cases(sleep),]
sum(is.na(newdata2)) #计算还有多少缺失值
(2)均值/中位数等填充:这种方法非常简单,如果填充值对结果影响不太大的话,这种方法倒是可以接受,并且有可能会产生令人满意的结果。
newdata<-sleep mean_d<-mean(newdata$Dream,na.rm = T) newdata[is.na(newdata$Dream),"Dream"]<-mean_d
(3)用函数包来处理
- Hmisc包可以插补均值、中位数等,也可以插补指定值。
library(Hmisc)
impute(newdata$Dream,median)
impute(newdata$Dream,5)
- mice包-预测值来处理缺失值
mice是链式方程多元插值的简写(Multivariate Imputation by Chained Equations)。mice包提供了多种先进的缺失值处理方法。它使用一种不同寻常的方法来进行两步插值:首先利用mice函数建模再用complete函数生成完整数据。mice(df)会返回df的多个完整副本,每个副本都对缺失的数据插补了不同的值。complete()函数则会返回这些数据集中的一个(默认)或多个。
下图展示mice包的操作过程:
-
备注:
-
mice():从一个含缺失值的数据框开始,返回一个包含多个完整数据集对象(默认可以模拟参数5个完整的数据集)
with():可依次对每个完整数据集应用统计建模
pool():将with()生成的单独结果整合到一起
library(mice)
newdata<-sleep #操作数据的时候尽量不要对原数据集直接操作
data<-mice(newdata,m = 5,method='pmm',maxit=100,seed=1)
#m是默认值5,指插补数据集的数量
#插补方法是pmm:预测均值匹配,methods(mice)查看其他方法
#maxit指迭代次数,seed指设定种子数(和set.seed同义)
comp_data<-complete(data) #生成完整数据
anyNA(comp_data) #判断是否还有缺失值,没有则结果返回FALSE
参考雪晴数据网
推荐 Selva Prabhakaran 关于缺失值的处理
###4.噪声值的处理
(1)盖帽法:整行去掉数据框里99%以上和1%以下的点,所用数据集应保证数据没有缺失值。
summary(comp_data$Dream) #盖帽法之前,查看数据情况,保证数据无缺失值
hist(comp_data$Dream)
q1<-quantile(comp_data$Dream, 0.01)
q99<-quantile(comp_data$Dream,0.99)
comp_data[comp_data$Dream<q1,]$Dream<-q1
comp_data[comp_data$Dream>q99,]$Dream<-q99
summary(comp_data$Dream) #盖帽法之后,查看数据情况
(2)分箱法:通过考察数据的“近邻”来光滑有序数据的值,有序值分布到一些桶或箱中。
- 等深分箱:每个分箱中的样本量一致;(较好)
- 等宽分箱:每个分箱中的取值范围一致。
比如价格排序后数据:4,8,15,21,21,24,25,28,34
划分为( 等深) 箱:
- 箱1: 4,8,15
- 箱2: 21,21,24
- 箱3: 25,28,34
划分为( 等宽)箱:
- 箱1: 4,8
- 箱2: 15,21,21,24
- 箱3: 25,28,34
等深分箱代码:
parts<-4
min_da<-0.00001#极小值
quant<-quantile(comp_data$Dream,probs = seq(0,1,1/parts))
#等比分为4段
table(quant)
requant<-mapply(function(x){
for (i in 1:(parts-1)) {
if(x>=(quant[i]-min_da)&x<quant[i+1]){
return(i)
}
}
if(x+min_da>quant[parts]){
return(parts)
}
return(-1)
},comp_data$Dream)
table(requant)
comp_data$Dream1<-paste("L",requant,sep="")
#将连续变量转化成定序变量
table(comp_data$Dream1)
comp_data$dream2<-tapply(comp_data$Dream,comp_data$Dream1,mean)[comp_data$Dream1]
#使用箱均值进行光滑处理
head(comp_data)
等宽分箱代码:
cutt<-cut(comp_data$Dream,4) #这里以Dream字段等宽分为4段
table(cutt)
levels(cutt)<-paste("L",1:4,sep="")#将连续变量转化成定序变量
comp_data$Dream1<-cutt
table(comp_data$Dream1)