
删除上面数据框中的第二行和第四行!
在数据分析中,有时候需要将缺失数据进行删除。删除数据很有讲究,比如多性状模型分析时,个体ID1的y1性状缺失,y2性状不缺失,评估y1时,不仅可以通过亲缘关系矩阵和固定因子进行评估,还可以根据y1和y2的遗传相关进行评估,这时候,y1的缺失就不需要删除。
有时候y1和y2性状都缺失,这时候就没有必要保留了,增加运算量,还增加错误的可能性,这时候就需要将其删除。
一般都是使用tidyverse进行清洗数据,但是drop_na函数没有这个功能,这里总结一下,如果有这种需求,如何处理。
tidyverse的drop_na函数,当面对多个列时,它的选择是“或”,即是只有有有一列有缺失,都删掉。有时候我们想将两列都为缺失的删掉,如果只有一列有缺失,要保留。
举个例子:
「示例数据:」
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
> 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缺失的删掉
> # 去掉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缺失的删掉
> # 去掉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缺失的都删掉
> # 去掉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反手给另一个回答点赞了……
4. 把y1和y2缺失同时缺失的删掉
dat %>% filter(!(is.na(y1) & is.na(y2)))
> 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都缺失,删掉了。但是如果你有20个性状呢?代码写得太长了,不讲究呀!
另一种方法:
dat %>% filter(!is.na(y1) | !is.na(y2))
> 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
看起来很复杂,但是如果你有20个性状呢?代码写得太长了,不讲究呀!
简单的方法:
# 第一种:dat %>% filter(!if_all(c(y1,y2), .fns = is.na))# 第二种:dat %>% filter(!if_all(-ID, .fns = is.na))
特别是第二种方法,你有20个性状没问题,即使你有200个性状也是没问题的!
5. 所有测试代码汇总
欢迎关注我的公众号:
❞育种数据分析之放飞自我。主要分享R语言,Python,育种数据分析,生物统计,数量遗传学,混合线性模型,GWAS和GS相关的知识。
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,4library(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,4dat %>% filter(!is.na(y1) | !is.na(y2))dat %>% filter(!(is.na(y1) & is.na(y2)))# 去掉y1和y2同时缺失的行:2,4dat %>% filter(!if_all(c(y1,y2), .fns = is.na))# 下面这种也可以dat %>% filter(!if_all(-ID, .fns = is.na))
分割线
大家好,我是邓飞,一个持续分享的农业数据分析师,这里我将自己公众号的干货内容挑重点罗列一下,方便大家阅读和使用。
1,GWAS学习教程(快来领取 | 飞哥的GWAS分析教程),这个pdf是我将公众号的内容进行了汇总,更方便从头学习GWAS分析,里面配套了数据、代码和讲解,属于干货推荐的Number 1。
2,农学人如何入门数据分析资料汇总(飞哥汇总 | 入门数据分析资源推荐),里面推荐了免费的教程,包括编程、统计和专业书籍。
3,数量遗传学电子书下载(数量遗传学,分享几本书的电子版)
4,R语言电子书线上书籍推荐(R语言学习看最新版的电子书不香嘛?)
加微信好友,互秀朋友圈呀,你扫我,还是我扫你?


