取datatable某一列的值_R-缺失值识别与处理

本文介绍了R语言中处理缺失值的步骤,包括缺失值的定义、识别、定位和去除,以及单变量和多变量填补方法。重点讲述了如何使用sum、is.na、colSums、describe、mice等函数进行统计和处理,并提到了随机森林、奇异值分解等高级填补技术。
摘要由CSDN通过智能技术生成

缺失值是我们进行批量数据处理中常常遇到的一个问题,比如研究中常常遇到指标缺失,需要对缺失进行统计,然后进一步判断,是丢弃这些变量呢(丢弃一般不太好),还是对数据进行替换,插补等操作后进行建模。下面讲一下R中的缺失值的识别与处理:

0、缺失值定义

缺失值从数据分布上可被分为三类 :完全随机缺失(MCAR), 随机缺失(MAR), 非随机缺失(NMAR)。

  • 完全随机缺失(MCAR):若某变量的缺失数据与其他任何观测或未观测变量都不相关
  • 随机缺失(MAR):若某变量上的缺失数据与其他观测变量相关,与它自己的未观测值不相关
  • 非随机缺失(NMAR):某一变量的缺失和该变量本身的数值相关;或者若缺失数据不属于MCAR或MAR,则数据为非随机缺失。如,仪器的最低检测线:某被检测物质的含量低于该检测线则会产生非随机缺失(left-censored missing);做梦时长越短的动物也更可能有做梦数据的缺失(可能由于难以测量时长较短的事件), 那么数据可认为是NMAR。

目前大部分填补缺失值的方法都是基于MCAR和MAR,对于这些数据,可以忽略缺失数据的生成机制,并且(在替换或删除缺失数据后)可以直接对感兴趣的关系进行建模。当数据是NMAR时,想对它进行恰当地分析比较困难,你既要对感兴趣的关系进行建模,还要对缺失值的生成机制进行建模。(目前分析NMAR数据的方法有模型选择法和模式混合法。由于NMAR数据的分析十分复杂,我们将忽略对它的讨论。)

1、识别缺失值

a <- c(1,2,3,4)
b <- c(6,7,8,NA)
m <- cbind(a,b)
m

# m
#     a  b
#[1,] 1  6
#[2,] 2  7
#[3,] 3  8
#[4,] 4 NA
  • 1.1 对NA进行统计,可以用sum函数和is.na连用;或用colSums函数
> sum(is.na(m))
[1] 1
#或者对行和列分别进行统计,注意colSums和rowSums是中间的大写
> colSums(is.na(m))
a b 
0 1 
> rowSums(is.na(m))
[1] 0 0 0 1
  • 或者可以用summary函数

14c6f98eb1f0a8e35c1971ca36b80e5b.png
  • 可以用sapply函数,sapply(m, function(x) sum(is.na(x)))

96b8a43d0c2a014dc2abbaba1d7e84fa.png
  • 1.2 用Hmisc包中的describe()
> library(Hmisc)
> Hmisc::describe(m)
m 

 2  Variables      4  Observations
--------------------------------------------------------------------------------------------------
a 
       n  missing distinct     Info     Mean      Gmd 
       4        0        4        1      2.5    1.667 
                              
Value         1    2    3    4
Frequency     1    1    1    1
Proportion 0.25 0.25 0.25 0.25
--------------------------------------------------------------------------------------------------
b 
       n  missing distinct     Info     Mean      Gmd 
       3        1        3        1        7    1.333 
                            
Value          6     7     8
Frequency      1     1     1
Proportion 0.333 0.333 0.333
--------------------------------------------------------------------------------------------------
  • 1.3 psych包中的describe()计算缺失值(效果较好)
psych::describe(m)
  vars n mean   sd median trimmed  mad min max range skew kurtosis   se
a    1 4  2.5 1.29    2.5     2.5 1.48   1   4     3    0    -2.08 0.65
b    2 3  7.0 1.00    7.0     7.0 1.48   6   8     2    0    -2.33 0.58
  • 1.4 mice包中的mice包中的md.pattern()函数。会出现一个二维的表格,以及对应的图(如果数据较多,作图可能会慢一些)
#从这开始以diabetes数据集为例,包含在VIM包中
library(VIM)
library(mice)
data('diabetes')
d <- diabetes

ac25b0f35fba4079c83bef5e74e3b9bf.png
diabetes数据集

b74c5324003d2f150f29c71b5d9456e8.png
查看缺失值个数


md.pattern(d)

f1a0c63cd1b9dba77a7024ac5e1f21b1.png

cf1188a1423b01527d85463e4d1f702f.png
  • 1.5 library(VIM)的aggr函数画图
library(VIM)
aggr(d)
#代码aggr(sleep, prop = TRUE, numbers = TRUE)将生成相同的图形,但用比例代替了计数。选项numbers = FALSE(默认)删去数值型标签。

064cd4d5d5ccd1041008272bad32fb53.png
  • 或者也可以使用VIM包的matrixplot函数
> matrixplot(d)

0cfefcbd0fdbc732e35e80091c2285e7.png
#或者用VIM 包的marginplot ,注意,这个图只适用于对两个变量作图
marginplot(m)

0476f82819a9ccb4f562a5d525fa3a22.png
  • 1.6 可以用Amelia包中的missmap函数(这个函数对大量的数据,效果会好一些,运行速度相对较快;格式必须是data.frame输入,matrix不行
library(Amelia)
m <- as.data.frame(d)
missmap(d, col = c("white", "lightblue"))

318536be3eba5a54ac477f27f6779af2.png

2、定位和去除缺失值

2.1 行删除

  • 最简单的方法就是is.na(),返回的是ture和false,然后就可以定位缺失值
r <- is.na(d)

dda03cac812262bab177d80e6dd52d87.png
is.na返回的结果
  • 根据某一列来选择
d1 <- d[!r$BloodPressure, ]
#选择BloodPressure不是NA的行

57750c33a82be3d2958787c2b7a2f28a.png
可以看到,这样用false的反面(true)选择了733行,含有NA的35行被丢弃
  • 同样可以使用na.omit函数(去除所有含缺失值的行)

df21f8f83591932c50ae8dec24c9fdb3.png
可以看到na.omit去除了所有含缺失值的行
  • 或者用complete.case函数

4cb7844e7e82b93176307175b74eddf3.png

2.2 80%规则。在代谢组学中,有一个80%规则,少于80%的variable应当去除。

 rowSums(is.na(d))/ncol(d) #计算缺失值的比例

3c4d0fc2573e3b61aa65962070991172.png
r1 <- rowSums(is.na(d))/ncol(d) >= 0.2
#r1是缺失值大于0.2的行
d5 <- d[!r1, ]
#取子集

0c5f181bdf04e96060e437083c7209d7.png

3、缺失值填补(包括单变量填补和多变量填补)

单变量填补(即单一变量,如0,均值,中位数,众数等等)

简单插补的一个优点是,解决“缺失值问题”时不会减少分析过程中可用的样本量。虽然简单插补用法很简单,但是对于非MCAR的数据会产生有偏的结果。若缺失数据的数目非常大,那么简单插补很可能会低估标准差、曲解变量间的相关性,并会生成不正确的统计检验的p值。与成对删除一样,我建议在解决缺失数据的问题时尽量避免使用该方法。
from 《R语言实战》
  • 3.1 使用固定值,如0,进行填补, 用R编写一个函数,然后用apply或者sapply进行遍历
fix(m)#修改m,修改后如下:
> m
  a  b
1 1 10
2 3  1
3 3  8
4 9 NA
#def function
fun1 <- function(x) {
     x[is.na(x)] <- 0
     x
}
> sapply(m, fun1)
     a  b
[1,] 1 10
[2,] 3  1
[3,] 3  8
[4,] 9  0
  • 或者直接用is.na进行0的赋值
m[is.na(m)] <- 0
#############
m
  a  b
1 1 10
2 3  1
3 3  8
4 9  0
  • 3.2 使用均值、中位数填补,同样:
#mean
fun2 <- function(x) {
    x[is.na(x)] <- mean(x, na.rm = TRUE)
    x
}
sapply(m, fun2)
     a         b
[1,] 1 10.000000
[2,] 3  1.000000
[3,] 3  8.000000
[4,] 9  6.333333
#median
fun3 <- function(x) {
    x[is.na(x)] <- median(x, na.rm = TRUE)
    x
}
sapply(m, fun3)
     a  b
[1,] 1 10
[2,] 3  1
[3,] 3  8
[4,] 9  8

多变量填补:如随机森林(RF),奇异值分解(SVD),k最近邻(kNN)和左删失数据的分位数回归插补(QRILC)等

  • 3.3 其它赋值方式,如随机森林(RF),奇异值分解(SVD),k最近邻(kNN)和左删失数据的分位数回归插补(QRILC)等,这些方法由于时间原因,留待以后进行实现。
  • 可参考:R语言之缺失值和异常值处理
  • 我觉得下面一张图能够很好的总结我上面讨论的,缺失值识别的一系列问题,以及相对应的解决方法:

172778f4580b93c1cf01e3010e055875.png

d7dbbaae43afd71ff30a98876df01a78.png
from 《R语言实战》

Reference:

  1. 数据预处理中的缺失值问题
  2. Wei, R. , Wang, J. , Su, M. , Jia, E. , Chen, S. , & Chen, T. , et al. (2018). Missing value imputation approach for mass spectrometry-based metabolomics data.Scientific Reports,8(1), 663.
  3. Bijlsma, S. , Bobeldijk, I. , Verheij, E. R. , Ramaker, R. , Kochhar, S. , & Macdonald, I. A. , et al. (2006). Large-scale human metabolomics studies:? a strategy for data (pre-) processing and validation.Analytical Chemistry,78(2), 567-574.
  4. RobertI.Kabacoff, 卡巴科弗, 陈钢, 肖楠, & 高涛. (2013). R语言实战.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值