前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >R语言中如何删除缺失数据

R语言中如何删除缺失数据

作者头像
邓飞
发布2021-10-18 10:29:41
4.1K0
发布2021-10-18 10:29:41
举报
文章被收录于专栏:育种数据分析之放飞自我

在数据分析中,有时候需要将缺失数据进行删除。删除数据很有讲究,比如多性状模型分析时,个体ID1的y1性状缺失,y2性状不缺失,评估y1时,不仅可以通过亲缘关系矩阵和固定因子进行评估,还可以根据y1和y2的遗传相关进行评估,这时候,y1的缺失就不需要删除。

有时候y1和y2性状都缺失,这时候就没有必要保留了,增加运算量,还增加错误的可能性,这时候就需要将其删除。

一般都是使用tidyverse进行清洗数据,但是drop_na函数没有这个功能,这里总结一下,如果有这种需求,如何处理。

tidyverse的drop_na函数,当面对多个列时,它的选择是“或”,即是只有有有一列有缺失,都删掉。有时候我们想将两列都为缺失的删掉,如果只有一列有缺失,要保留。

举个例子:

「示例数据:」

代码语言:javascript
复制
set.seed(123)
dat = data.frame(ID = 1:10,y1 = c(NA,NA,1.05,NA,rnorm(6)), y2 = c(1,NA,NA,NA,rnorm(6)))
dat
代码语言:javascript
复制
> dat
   ID          y1         y2
1   1          NA  1.0000000
2   2          NA         NA
3   3  1.05000000         NA
4   4          NA         NA
5   5 -0.56047565  0.4609162
6   6 -0.23017749 -1.2650612
7   7  1.55870831 -0.6868529
8   8  0.07050839 -0.4456620
9   9  0.12928774  1.2240818
10 10  1.71506499  0.3598138

这个数据中:

  • y1 缺失的行有:1,2,4
  • y2 缺失的行有:2,3,4
  • y1和y2都缺失的行有:2,4

1. 把y1缺失的删掉

代码语言:javascript
复制
> # 去掉y1缺失的行
> dat %>% drop_na(y1)
  ID          y1         y2
1  3  1.05000000         NA
2  5 -0.56047565  0.4609162
3  6 -0.23017749 -1.2650612
4  7  1.55870831 -0.6868529
5  8  0.07050839 -0.4456620
6  9  0.12928774  1.2240818
7 10  1.71506499  0.3598138

可以看到,1,2,4行被删掉了

2. 把y2缺失的删掉

代码语言:javascript
复制
> # 去掉y2缺失的行
> dat %>% drop_na(y2)
  ID          y1         y2
1  1          NA  1.0000000
2  5 -0.56047565  0.4609162
3  6 -0.23017749 -1.2650612
4  7  1.55870831 -0.6868529
5  8  0.07050839 -0.4456620
6  9  0.12928774  1.2240818
7 10  1.71506499  0.3598138

可以看到,2,3,4行被删掉了

3. 把y1或者y2缺失的都删掉

代码语言:javascript
复制
> # 去掉y1或者y2缺失的行:1,2,3,4,
> dat %>% drop_na(y1,y2)
  ID          y1         y2
1  5 -0.56047565  0.4609162
2  6 -0.23017749 -1.2650612
3  7  1.55870831 -0.6868529
4  8  0.07050839 -0.4456620
5  9  0.12928774  1.2240818
6 10  1.71506499  0.3598138

可以看到,1,2,3,4行被删掉了

上面都是常规操作,drop_na完全没问题。但是我想把y1和y2同时缺失的行删掉,这个就不太好办了。drop_na好像没有相关的选项。

我看到一个issues:https://github.com/tidyverse/tidyr/issues/1054

想问hardey能不能增加这样的参数,有一个.logic参数,默认为or,可以设置and,但是hardy反手给另一个回答点赞了……

「错误的代码:」

代码语言:javascript
复制
penguins %>% 
  drop_na(body_mass_g, sex, .logic = "AND")

「正确的代码:」

代码语言:javascript
复制
palmerpenguins::penguins %>% 
  filter(!across(c(body_mass_g, sex), .fns = is.na))

4. 把y1和y2缺失同时缺失的删掉

代码语言:javascript
复制
dat %>% filter(!(is.na(y1) & is.na(y2)))
代码语言:javascript
复制
> dat %>% filter(!(is.na(y1) & is.na(y2)))
  ID          y1         y2
1  1          NA  1.0000000
2  3  1.05000000         NA
3  5 -0.56047565  0.4609162
4  6 -0.23017749 -1.2650612
5  7  1.55870831 -0.6868529
6  8  0.07050839 -0.4456620
7  9  0.12928774  1.2240818
8 10  1.71506499  0.3598138

可以看到,2,4行y1和y2都缺失,删掉了。

另一种方法:

代码语言:javascript
复制
dat %>% filter(!is.na(y1) | !is.na(y2))
代码语言:javascript
复制
> dat %>% filter(!(is.na(y1) & is.na(y2)))
  ID          y1         y2
1  1          NA  1.0000000
2  3  1.05000000         NA
3  5 -0.56047565  0.4609162
4  6 -0.23017749 -1.2650612
5  7  1.55870831 -0.6868529
6  8  0.07050839 -0.4456620
7  9  0.12928774  1.2240818
8 10  1.71506499  0.3598138

还有一种,hardey赞同的方法:

代码语言:javascript
复制
# 去掉y1和y2同时缺失的行:2,4
dat %>% filter(!across(c(y1,y2), .fns = is.na))
代码语言:javascript
复制
> dat %>% filter(!across(c(y1,y2), .fns = is.na))
  ID          y1         y2
1  3  1.05000000         NA
2  5 -0.56047565  0.4609162
3  6 -0.23017749 -1.2650612
4  7  1.55870831 -0.6868529
5  8  0.07050839 -0.4456620
6  9  0.12928774  1.2240818
7 10  1.71506499  0.3598138

方法看起来很复杂。还是我写的比较简单:

代码语言:javascript
复制
# 去掉y1和y2同时缺失的行:2,4
dat %>% filter(!is.na(y1) | !is.na(y2))

dat %>% filter(!(is.na(y1) & is.na(y2)))

5. 所有测试代码汇总

代码语言:javascript
复制
set.seed(123)
dat = data.frame(ID = 1:10,y1 = c(NA,NA,1.05,NA,rnorm(6)), y2 = c(1,NA,NA,NA,rnorm(6)))
dat

## y1 缺失的行有:1,2,4
## y2 缺失的行有:2,3,4
## y1和y2都缺失的行有:2,4


library(tidyverse)

# 去掉y1缺失的行
dat %>% drop_na(y1)

# 去掉y2缺失的行
dat %>% drop_na(y2)

# 去掉y1或者y2缺失的行:1,2,3,4,
dat %>% drop_na(y1,y2)


# 去掉y1和y2同时缺失的行:2,4
dat %>% filter(!is.na(y1) | !is.na(y2))

dat %>% filter(!(is.na(y1) & is.na(y2)))



# 去掉y1和y2同时缺失的行:2,4
dat %>% filter(!across(c(y1,y2), .fns = is.na))

❝欢迎关注我的公众号:育种数据分析之放飞自我。主要分享R语言,Python,育种数据分析,生物统计,数量遗传学,混合线性模型,GWAS和GS相关的知识。 ❞

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2021-10-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 育种数据分析之放飞自我 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 把y1缺失的删掉
  • 2. 把y2缺失的删掉
  • 3. 把y1或者y2缺失的都删掉
  • 4. 把y1和y2缺失同时缺失的删掉
  • 5. 所有测试代码汇总
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档