R语言如何检测和处理数据缺失值?
专题介绍:R是一种广泛用于数据分析和统计计算的强大语言,于上世纪90年代开始发展起来。得益于全世界众多 爱好者的无尽努力,大家继而开发出了一种基于R但优于R基本文本编辑器的R Studio(用户的界面体验更好)。也正是由于全世界越来越多的数据科学社区和用户对R包的慷慨贡献,让R语言在全球范围内越来越流行。其中一些R包,例如MASS,SparkR, ggplot2,使数据操作,可视化和计算功能越来越强大。R是用于统计分析、绘图的语言和操作环境。R是属于GNU系统的一个自由、免费、源代码开放的软件,它是一个用于统计计算和统计制图的优秀工具。R作为一种统计分析软件,是集统计分析与图形显示于一体的。它可以运行于UNIX、Windows和Macintosh的操作系统上,而且嵌入了一个非常方便实用的帮助系统,相比于其他统计分析软件,R的学术性开发比较早,适合生物学和医学等学术学科的科研人员使用。
【R语言】开通了R语言群,大家相互学习和交流,请扫描下方二维码,备注:R群,我会邀请你入群,一起进步和成长。
面对一份数据,我们会做数据的缺失值检测和分析,根据数据的缺失程度,以知道数据的完整性和可用性。实际的数据,绝大部分会有缺失值现象。缺失值的产生与诸多因素有关联,例如:数据采集不成功,数据采集成功了但是数据确实没有值,数据的值受其它因素控制等。面对有缺失值的数据,我们要怎么处理、分析和应用,是我们数据工作者要思考和实践的命题。这篇文章,总结和分享R语言如何检测数据中的缺失值,以及针对不同情形下处理缺失值的方法。
R语言可以使用is.na()函数来判断数据集的取值是否为缺失值,并且利用一些汇总函数可以概述数据整体的缺失率、每个样本的缺失率和每个变量的缺失率。R语言也提供可视化工具来直观展示变量的缺失分布情况。
【代码片段】
library(pacman)
p_load(tidyverse)
p_load(mice)
p_load(VIM)
telecom_data <- read_csv('./data/telecom.csv')
telecom_data %>% glimpse()
is.na(telecom_data)
sum(is.na(telecom_data))
mean(is.na(telecom_data))
var_na_ratio <- function(x){
return(mean(is.na(x)))
}
apply(telecom_data, 2, var_na_ratio)
apply(telecom_data, 1, var_na_ratio)
【结果】
我们可以发现数据集为10行、5列,50个单元,整体缺失情况是5个缺失值,缺失率为10%。变量的缺失率情况,MonthlyCharges为30%、TotalCharges和PaymentMethod为10%,样本的缺失情况,3个样本有1个缺失值,1个样本有2个缺失值。
【代码片段】
md.pattern(telecom_data)
aggr_plot <- aggr(telecom_data,
col=c('navyblue','red'),
numbers=TRUE,
sortVars=TRUE,
labels=names(data),
cex.axis=.7,
gap=3,
ylab=c("Histogram of missing data","Pattern"))
【结果】
横向观察,表示有6个样本没有缺失,2个样本有个1个缺失值,1个样本有2个缺失依次类推;纵向观察,TotalChanges有1个缺失值,PaymentMethod有1个缺失,MonthlyCharges有3个缺失值,总共是有5个缺失。
左边的图按着变量缺失率做降序排列;右边的图从下往上看,第一行,表示60%的样本无缺失值,第二行,表示20%的样本在变量MonthlyCharges有1个缺失值,以此类推。
我们可以把缺失值化为两种类型:
MCAR:完全随机的缺失,这是缺失值的理想场景。
MNAR:非完全性随机缺失,这是常见情形,这个时候进一步检查数据收集过程并尝试理解数据缺失的原因可能是明智而必要的。数据集含有太多缺失会带来严重问题。在大数据集情况,通常我们会保留变量缺失率不超过5%或者样本缺失率不超过5%的样本,当然,这个最佳阈值,可以根据实际情况调整。
【代码片段】
# 以自带数据集airquality为例
data <- airquality
data[4:10,3] <- rep(NA,7)
data[1:5,4] <- NA
data <- data[-c(5,6)]
summary(data)
pMiss <- function(x){sum(is.na(x))/length(x)*100}
apply(data,2,pMiss)
apply(data,1,pMiss)
【结果】
可以发现变量Ozone的缺失率有24.2%,而其它变量的缺失率是5%以下,我们可以删除变量Ozone,这也是一种特征选择方法,基于数据的可用性来过滤特征。因为,我们所观察的数据集变量4个,只要一个有两个或者以上变量缺失,就出现了样本50%及以上的缺失率,因此这样的样本可以不予纳入研究。
上面的这些做法,实际属于一种常用R语言处理数据缺失值的方法,即根据变量的缺失率和样本的缺失率,来过滤不符合阈值的变量和样本集。若是在大数据和缺失率小比例的背景下,这种方法是有效的,也是简单易行的。
有时候,我们为了保留变量和样本数,需要采用别的方法来处理缺失值,常用的手段就是插补,不管是基于统计学里面平均值、中位数或者众数,还是基于某一种学习模型来完成缺失填充,这些都可以看作是插补法,只是方式不同而已。我们可以利用R语言mice包来做缺失值的插补法。
【代码片段】
# 缺失值的插补
tempData <- mice(data,m=5,maxit=50,meth='pmm',seed=500)
completedData <- complete(tempData,1)
sum(is.na(data))
sum(is.na(completedData))
缺失的值被替换为五个数据集中第一个数据集的输入值。如果希望使用另一个数据集的结果,只需更改complete()函数中的第二个参数。
【结果】
mice包提供了很多进行缺失值插补的方法,具体方法查询如下:
【代码片段】
# mice包插补缺失值方法
methods(mice)
【结果】
关于这些方法的含义,可以查看mice包的帮助文档。大家做一下,若是要用随机森林做插补法,需要用哪个方法?
总结:本文分享缺失值的检测方法和处理策略,以及缺失值两种类型,还有R 语言处理缺失值的mice包。
【完整代码片段】
#############
#R语言如何检测和处理缺失值
#2021年第8周
#Luqing Wang
#############
# R包
library(pacman)
p_load(tidyverse) # 数据科学套件
p_load(mice) # 缺失值分析包
p_load(VIM)
# 导入数据
telecom_data <- read_csv('./data/telecom.csv')
# 数据检视
telecom_data %>% glimpse()
# 10行,5列
# 4个字符型变量,1个双精度型变量
# 缺失值检验
is.na(telecom_data)
# 数据整体缺失率
sum(is.na(telecom_data))
mean(is.na(telecom_data))
# 自定义缺失率计算函数
var_na_ratio <- function(x){
return(mean(is.na(x)))
}
# 变量缺失率
apply(telecom_data, 2, var_na_ratio)
# 样本缺失率
apply(telecom_data, 1, var_na_ratio)
# 数据集缺失可视化分析
# 缺失值模式
md.pattern(telecom_data)
aggr_plot <- aggr(telecom_data,
col=c('navyblue','red'),
numbers=TRUE,
sortVars=TRUE,
labels=names(data),
cex.axis=.7,
gap=3,
ylab=c("缺失值直方图","缺失值模式"))
# 以自带数据集airquality为例
data <- airquality
data[4:10,3] <- rep(NA,7)
data[1:5,4] <- NA
data <- data[-c(5,6)]
summary(data)
pMiss <- function(x){sum(is.na(x))/length(x)*100}
apply(data,2,pMiss)
apply(data,1,pMiss)
# 缺失值的插补
tempData <- mice(data,m=5,maxit=50,meth='pmm',seed=500)
completedData <- complete(tempData,1)
sum(is.na(data))
sum(is.na(completedData))
# mice包插补缺失值方法
methods(mice)
# 其它代码
summary(tempData)
dim(tempData$imp$Ozone)
tempData$meth
xyplot(tempData,Ozone ~ Wind+Temp+Solar.R,pch=18,cex=1)
densityplot(tempData)
stripplot(tempData, pch = 20, cex = 1.2)
tempData
modelFit1 <- with(tempData,lm(Temp~ Ozone+Solar.R+Wind))
summary(pool(modelFit1))
参考资料:
1https://datascienceplus.com/imputing-missing-data-with-r-mice-package/
2 https://raw.githubusercontent.com/dataoptimal/posts/master/data%20cleaning%20with%20R%20and%20the%20tidyverse/telecom.csv
好书推荐
2 用RStudio做数据分析
4 推断统计与数据科学,moderndive和tidyverse包
公众号推荐
请关注“恒诺新知”微信公众号,感谢“R语言“,”数据那些事儿“,”老俊俊的生信笔记“,”冷🈚️思“,“珞珈R”,“生信星球”的支持!