缺失数据处理方法简介

现实情况下,研究人员手上拿到的数据,无论多少,一般都会包含缺失值。
如何妥善处理缺失值,以获得可靠的统计分析结果,是重多研究者关注的问题。

本文基于多篇文献及网络资料,重点从缺失原因,缺失数类型,以及处理方法,对以上问题进行了一定程度的解答。另外本文提供了一部分网络收集的R代码,供实战参考,如有建议或疑问,评论区留言。

在这里插入图片描述

数据缺失的3大原因
(1)采集过程损失。客观条件的限制,如历史条件下,设备的局限导致无法获取完整的信息
(2)运输过程缺失。数据的运输转移需要靠人来完成,因此人为操作、判定的失误会导致数据错误或者丢失。
(3)存储过程损失。由于存储介质发生故障及损坏而导致的数据缺失:以及存储过程中对数据进行压缩而导致丢失。

数据缺失的分类

  1. 根据缺失模式分类
    1.1 单变量缺失模
    式单变量缺失模式是指单属性维度存在缺失值,即所研究数据集中只有一个属性维度存在缺失值,其余属性维度数据完整。
    1.2 多变量缺失模式
    多变量缺失模式是指中多属性维度含有缺失值,即所研究数据集中有一个及以上属性维度存在缺失值。
    1.3 单调缺失模式
    指所研究数据集在多属性维度含有缺失值的基础上,缺失数据形成的矩阵进行排列变换后能呈现单调层级模式。个人理解,就是在多个观测丢的一样变量的数据。
    1.4一般缺失模式
    简单点说就是所研究数据集中缺失数据分布在不同属性之间。并且毫无规律可循。这是目前最常见的缺失模式。这个观测丢变量1的数据,那个观测丢变量2的数据,类似这样。

  2. 缺失机制分类
    2.1完全随机缺失(MissingCompletelyAtRandom,MCAR)
    完全随机缺失
    指数据缺失是随机发生的,与自身属性以及其他属性取值无关,例如研究数学、语文和英语三个属性时,数学属性的缺失与语文和英语两个属性无关,它是完全随机缺失。目前来说,完全随机缺失并不常见。
    例如:一调查问卷中的性别字段,是否缺失完全随机,取决于调查对象。
    2.2随机缺失(MissingAtRandom.MAR)
    随机缺失指数据缺失只和完整属性取值有关。例如研究数学和语文两属性时,已知数学属性的缺失和语文属性相关,则可以认为这是随机缺失的。或者说该类数据的缺失依赖于其他完全变量。
    比如:一个关于教育的数据集缺失了很多小孩的IQ测试分数,只是因为相比十二岁的孩子,四岁的孩子很少会通过这个测试。所以出现的空值与IQ实际值没有相关性,而与年龄相关。IQ字段缺失记录主要集中在低年龄人群中!
    2.3非随机缺失(NotMissingAtRandom,NMAR)
    非随机缺失指数据缺失不仅与自身取值有关而且与完整属性取值也有关,这种缺失是不可忽略的缺失。由于隐私敏感等问题,隐去某些属性值,这就是非随机缺失。

  3. 缺失值处理基本思路
    删除,填充,不处理
    3.1 简单删除法:
    3.1.1 对象删除:当包含缺失值的病例比例较少时,可以选择直接删除对象。
    3.1.2 变量删除:在某一变量中包含了较多缺失值,可以考虑将该变量删除。需要考虑该变量的删除后对后续研究的影响。
    3.2 权重法
    3.3 填补
    3.3.1 均值/众数填补
    3.3.2 多重插补

提供了常用的Rcode,顺序较乱,自行整理。

###########################################################
getwd()
options(digits = 3)
#setwd("C:\Users\mutong_chen\Desktop\TEST")
#https://www.zhihu.com/question/389341228
#----
Sys.setenv(LANGUAGE = "en")
options(stringsAsFactors = FALSE)
rm(list=ls())
#----
library(data.table)
library(dplyr)
library(tidyverse)
library(ggplot2)
#1.2.1 mpg数据框
#----
library(tidyverse)

#R语言缺失值处理#####################################################

library(VIM)
data(sleep)
View(sleep)

str(sleep)

sleep[!complete.cases(sleep),]#识别矩阵或数据框中没有缺失值的行
sleep[!complete.cases(sleep),] %>% colnames() %>% length()
#10个包括缺失值的病例

sum(is.na(sleep))#判断数据有多少缺失值

library(mice)
md.pattern(sleep)
#mice包中的md.pattern()函数可以生成一个以矩阵或数据框形式展示缺失值模式的表格。
aggr(sleep,prop=F,numbers=T) #图形化展示缺失数据


#2、缺失值数据的处理

#2.1 直接删除法
#如果样本量大,假定缺失数据是完全随机产生的,并且缺失值只是很少一部分
newdata<-na.omit(sleep)
newdata<-sleep[complete.cases(sleep),]


#2.2 均值/中位数等填充:
#这种方法简单粗暴,如果填充值对结果影响不怎么大,
#这种方法倒是可以接受,并且有可能会产生令人满意的结果。
options(digits = 3)
library(Hmisc)
newdata<-sleep
newdata$Dream
impute_dream=impute(newdata$Dream,mean) %>% as.numeric()
impute(newdata$Dream,median)
impute(newdata$Dream,2)
impute(newdata$Dream,mode)#需要有character才能使用众数填补


#2.3mice包多重插补
library(mice)
newdata<-sleep
methods(mice)


data<-mice(newdata,m=5,method = "pmm",maxit = 100,seed=1)
#插补方法是pmm:预测均值匹配,可以用methods(mice)查看其他方法
#maxit指迭代次数,seed指设定种子数(和set.seed同义)

summary(data)

data$imp#查看整体插补的数据:

data$imp$Dream#查看具体变量的插补数据:


completedata<-complete(data)#生成一个完整的数据集

anyNA(completedata)#判断还有没有缺失值,如果没有,结果返回FLASE


#针对以上插补结果,我们可以查看原始数据和插补后的数据的分布情况
densityplot(data)#洋红线是每个插补数据集的数据密度曲线,蓝色是观测值数据的密度曲线




#########################
#下面我们分析对数据拟合一个线性模型:
library(mice)
newdata<-sleep
data<-mice(newdata,m = 5,method="pmm",maxit=100,seed=1)
model<-with(data,lm(Dream~Span+Gest))
pooled<-pool(model)
summary(pooled)
pooled
#fim指的是各个变量缺失信息的比例,lambda指的是每个变量对缺失数据的贡献大小

lm.fit <- lm(Dream~Span+Gest, data = sleep,na.action=na.omit)
summary(lm.fit) 




data(sleep)

data=sleep


sum(is.na(data))              #查看data里缺失值个数
sum(is.na(data$Dream))   #查看data里维度DINNER_PRICE缺失值个数
   
data[!is.na(data$Dream),]     #删除DINNER_PRICE缺失样本
na.omit(data)              #去除有NA的行(方法1)
data[complete.cases(data),]     #去除有NA的行(方法2)
data[complete.cases(data[,5:6]),]    #只过滤第5列,第6列中含有NA的行


sum(complete.cases(data))   #不含缺失值记录
sum(!complete.cases(data))    #含缺失值记录
mean(!complete.cases(data))       #有缺失值记录比例
head(data[!complete.cases(data),])  #筛选出有缺失值的记录
sum(is.na(data))     #数据集中缺失值总计数量  多少个na?



###################################################
#检测异常值

#1.方法1:箱线图检验离群值
hon_01=data
hon_01 %>% rename(CHARGE_T = Gest) ->hon_01

sp=boxplot(hon_01$CHARGE_T,boxwex=0.7)
title("异常值检测箱线图")
xi=1.1
sd.s=sd(hon_01[complete.cases(hon_01),]$CHARGE_T)
mn.s=mean(hon_01[complete.cases(hon_01),]$CHARGE_T)
points(xi,mn.s,col="red",pch=18)
arrows(xi, mn.s - sd.s, xi, mn.s + sd.s, code = 3, col = "pink", angle = 75, length = .1)
text(rep(c(1.05,1.05,0.95,0.95),length=length(sp$out)),labels=sp$out[order(sp$out)],
     sp$out[order(sp$out)]+rep(c(150,-150,150,-150),length=length(sp$out)),col="red")

#2.当前值在平均值的±3个标准差之外
a<-matrix(1:12,nrow=3)
list_mean<- apply(a,2,mean)        #按列求均值
list_sd<-apply(a,2,sd)            #按列求标准差
max<-list_mean+3*(list_sd)         #按列求最大值
min<-list_mean-3*list_sd           #按列求最小值
apply(a,2,mean,na.rm=TRUE)         #如果有空值,可以加入na.rm=TRUE,忽略掉空值

which()


####################################
library(VIM)
data(sleep)
write.csv(sleep,file = "sleep.csv",row.names=F)


data = fread("sleep.csv", sep = ",", header = TRUE, stringsAsFactors = FALSE)

#方法3 寻找四分位数间距
计算下四分位数、上四分位数和四分位距
QL <- quantile(data$Gest, probs = 0.25,na.rm=T)
QU <- quantile(data$Gest, probs = 0.75,na.rm=T)
QU_QL <- QU-QL
#3.2、找出异常点
QU + 1.5*QU_QL -> Up
which(data$Gest > (QU + 1.5*QU_QL))
data$Gest[which(data$Gest>QU + 1.5*QU_QL)]


#异常值的处理
#盖帽法:整行替换数据框里99%以上和1%以下的点,
#将99%以上的点值=99%的点值;小于1%的点值=1%的点值

q1 <- quantile(data$Gest, 0.01,na.rm=T)        #取得时1%时的变量值
q99 <- quantile(data$Gest, 0.99,na.rm=T)       #取得时99%时的变量值
data[data$Gest < q1,]$Gest <- q1
data[data$Gest > q99,]$Gest <- q99
summary(data$Gest)      #盖帽法之后,查看数据情况

参考blog:
https://blog.csdn.net/jwtning/article/details/116125819
R语言实战,第15章

参考文献:
[1]熊中敏, 郭怀宇, 吴月欣. 缺失数据处理方法研究综述[J]. 计算机工程与应用, 2021, 57(14):12.

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值