在R中仅针对确诊组删除含超过2个NA的行
问题:仅删除diagnosis为"yes"组中含超过2个NA的行,避免误删"no"组数据
原始数据定义
ID <- c("x", "y", "z", "ad", "tgfg", "gfgh", "asj", "gh", "sdf", "asdgz") diagnosis <- c("yes", "no", "yes", "yes", "yes", "no", "yes", "no", "no", "no") Q1 <- c("A",NA,"A",NA,NA,"C","D","A","B", NA) Q2 <- c("D",NA,"D","C",NA,NA,"A","A","A","A") Q3 <- c("B","B","C","A",NA,"A","B","D","E",NA) Q4 <- c("B",NA,"C","C","C","C","D","B",NA,"A") mydf <- data.frame(ID, diagnosis, Q1,Q2,Q3,Q4)
数据展示
ID diagnosis Q1 Q2 Q3 Q4 x yes A D B B y no <NA> <NA> B <NA> z yes A D C C ad yes <NA> C A C tgfg yes <NA> <NA> <NA> C gfgh no C <NA> A C asj yes D A B D gh no A A D B sdf no B A E <NA> asdgz no <NA> A <NA> A
需求说明
仅删除diagnosis为"yes"组中含超过2个NA的行,diagnosis为"no"的组无论NA数量多少都保留。
你尝试的错误代码
delete.na <- function(DF, n=0) { DF[rowSums(is.na(DF)) <= n,] } new_df <- mydf %>% group_by(diagnosis== "yes") %>% delete.na(2) %>% ungroup()
错误原因
你用group_by(diagnosis== "yes")会把数据分成**TRUE(yes组)和FALSE(no组)**两组,然后对两组都执行了delete.na(2)过滤,导致"no"组里NA数超过2的行(比如y行有3个NA)被误删。
正确解决方案
方法1:直接用dplyr的filter(推荐)
不需要分组,直接通过条件筛选:要么是"no"组,要么是"yes"组且NA数≤2。
library(dplyr) new_df <- mydf %>% # 计算Q1-Q4列的NA数量 mutate(na_count = rowSums(is.na(select(., Q1:Q4)))) %>% # 核心筛选逻辑 filter(diagnosis == "no" | (diagnosis == "yes" & na_count <= 2)) %>% # 移除临时计算的na_count列 select(-na_count)
方法2:分组后针对性处理
如果想用分组逻辑,可以按diagnosis分组,对不同组应用不同规则:
delete.na <- function(DF, n=0) { DF[rowSums(is.na(DF)) <= n,] } new_df <- mydf %>% group_by(diagnosis) %>% group_modify(function(data, key) { if(key$diagnosis == "yes") { delete.na(data, 2) # yes组执行NA过滤 } else { data # no组直接保留原数据 } }) %>% ungroup()
执行后,"no"组的y行会被完整保留,"yes"组中只有tgfg行(含3个NA)会被删除,完全符合需求。
内容的提问来源于stack exchange,提问作者dplyr
相关产品推荐
相关产品推荐

