前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >28. R 数据整理(三:缺失值NA 的处理方法汇总)

28. R 数据整理(三:缺失值NA 的处理方法汇总)

作者头像
北野茶缸子
发布2021-12-17 09:21:41
4.3K0
发布2021-12-17 09:21:41
举报

1. 获得NA 位置

可以使用is.na() 函数对向量进行遍历,如果存在NA,则会返回TRUE,反之。

代码语言:javascript
复制
> is.na(c(1,2,3,NA,'sdas'))
[1] FALSE FALSE FALSE  TRUE FALSE

# 我们可以直接用which 获取TRUE 所在的index

但是,这个函数并不能很好的使用在数据框中,比如我们想要获得缺失值所在行呢?其会返回一个矩阵,对应的缺失值会在对应位置返回一个TRUE,如果这时候通过which 获取,其只会返回一个坐标,这是因为数据框经过is.na 后返回一个矩阵,而矩阵的坐标关系和向量又非常的微妙,其本质也就是向量的不同的排列,可以通过下面例子感受一下:

代码语言:javascript
复制
> matrix(c(1,2,3,NA,'sdas',4),ncol=2, byrow = 2)
     [,1]   [,2]
[1,] "1"    "2" 
[2,] "3"    NA  
[3,] "sdas" "4" 
> which(is.na(matrix(c(1,2,3,NA,'sdas',4),ncol=2, byrow = 2)))
[1] 5

> matrix(c(1,2,3,NA,'sdas',4),ncol=2)
     [,1] [,2]  
[1,] "1"  NA    
[2,] "2"  "sdas"
[3,] "3"  "4"   
> which(is.na(matrix(c(1,2,3,NA,'sdas',4),ncol=2)))
[1] 4

会自动按照行来进行重组,比如矩阵:

代码语言:javascript
复制
     [,1] [,2]  
[1,] "1"  NA    
[2,] "2"  "sdas"
[3,] "3"  "4" 

就相当于在1,2,3,NA... 中找了第四个NA(按照行)。

如果你是个数学鬼才,可以计算一下,也就是所在坐标对行数取余,这个余就是NA所在的行数:

代码语言:javascript
复制
> which(is.na(rcmat))
[1] 205214

> 205214%%70544
[1] 64126

> rcmat[64126,]
       CHROM      POS dp ad dp.1 ad.1
726209 chr19 50949779 NA  0    1    0

亦或是,你可以写个循环,对每行判断,一旦有any(存在TRUE) ,则该行存在NA值。

还有一个不错的方法,就是通过rowSums 函数,对行求和。我们都知道,布尔值实际就是0和1,我们可以利用这个特性,获得那些经过is.na 后,行和不是0 的行,那就代表其存在表示TRUE(NA)的数据了:

代码语言:javascript
复制
> rcmat[!rowSums(is.na(rcmat)) == 0, ]
       CHROM      POS dp ad dp.1 ad.1
726209 chr19 50949779 NA  0    1    0

2. 去除NA

非常暴力,直接使用函数na.omit() 就可以直接对向量或者数据框操作了。会直接返回一个去除NA 所在行的新向量或数据框:

代码语言:javascript
复制
> a=na.omit(c(1,2,3,NA,'sdas'))
> a
[1] "1"    "2"    "3"    "sdas"
attr(,"na.action")
[1] 4
attr(,"class")
[1] "omit"
> class(a)
[1] "character"
> as.character(a)
[1] "1"    "2"    "3"    "sdas"

3. tidyverse 中的高级函数

drop_na()

效果和na.omit 一样,但是高级之处在于,其可以指定列,对数据框某列存在NA 的行直接删除:

代码语言:javascript
复制
> X[2,2] = NA;X[6,1] = NA
> X
    X1 X2
1    A  1
2    B NA
3    C  3
4    D  4
5    E  5
6 <NA>  6

很快啊~

代码语言:javascript
复制
> library(tidyr)
> drop_na(X,X1)
  X1 X2
1  A  1
2  B NA
3  C  3
4  D  4
5  E  5

虽然我们也可以使用基础包做到,方法有很多啦~

代码语言:javascript
复制
> X[X$X1 %in% as.character(na.omit(X$X1)),]
  X1 X2
1  A  1
2  B NA
3  C  3
4  D  4
5  E  5

replace_na()

这个函数我很喜欢,可以将指定列中的NA 替换为指定的数值:

代码语言:javascript
复制
> X
    X1 X2
1    A  1
2    B NA
3    C  3
4    D  4
5    E  5
6 <NA>  6

> replace_na(X$X1,0)
[1] "A" "B" "C" "D" "E" "0"
> replace_na(X$X2,6)
[1] 1 6 3 4 5 6

fill()

不同于drop_na 的直接暴力删除,fill 非常贴心的将缺失值替换为其所在列的上一行数值的值:

代码语言:javascript
复制
> fill(X,X1,X2)
  X1 X2
1  A  1
2  B  1
3  C  3
4  D  4
5  E  5
6  E  6

> X
    X1 X2
1    A  1
2    B NA
3    C  3
4    D  4
5    E  5
6 <NA>  6

函数中参数设置

很多函数,都有参数na.rm 可以直接在对列表操作时去除NA 值,比如:

代码语言:javascript
复制
> a = c(3,4,NA)
> mean(a)
[1] NA  
> mean(a, na.rm = T)
[1] 3.5
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-09-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 北野茶缸子 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 获得NA 位置
  • 2. 去除NA
  • 3. tidyverse 中的高级函数
    • drop_na()
      • replace_na()
        • fill()
        • 函数中参数设置
        领券
        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档