繁体   English   中英

删除除一列之外的所有列都具有 NA 值的行?

[英]Remove rows where all columns except one have NA values?

我有一个包含三列的日期框,其中一列有一个参与者 ID 变量,没有 NA 值,另外两个(目标变量)有一些分散在各处。 我正在尝试使用此处解释的解决方案( 删除除 2 列之外的所有列都是 NA的行)来删除两个目标变量都具有 NA 的行,但由于某种原因,我的实现似乎不加选择地删除了所有 NA。

这是未处理的 df 的示例:

ID 一个 b
1 抗体 不适用
1 不适用 抗体
1 不适用 不适用

这是我希望处理后的 df 的样子:

ID 一个 b
1 抗体 不适用
1 不适用 抗体

这是我用来尝试完成此操作的代码:

na_rows = df %>% 
  select(-"ID") %>% 
  is.na() %>% 
  rowSums() > 0

processeddf <- df %>% 
  filter(!na_rows)

但是,此代码返回一个 df ,它完全删除了任何包含 NA 的行。 所以对于上面的示例,它将返回一个空的 df。 我在哪里错了? 我无法弄清楚我的逻辑错误发生在哪里。

我们可以在filter中使用if_all - select if_all 中的 a 到 b 列,应用if_all (检查 NA),如果 a 和 b 都具有 NA,则is.na对于一行将为 TRUE,取反( ! )转换为 TRUE -> FALSE 和 FALSE->TRUE

library(dplyr)
df %>%
   filter(!if_all(a:b, is.na))

-输出

ID    a    b
1  1   ab <NA>
2  1 <NA>   ab

或者,我们可以将complete.casesif_any一起使用,而不是否定 ( ! )

df %>% 
  filter(if_any(a:b, complete.cases))
  ID    a    b
1  1   ab <NA>
2  1 <NA>   ab

关于 OP 代码中的问题,逻辑是通过查看是否存在至少一个 NA ( > 0 ) 来创建的,这对于所有行都是正确的。 相反,它应该都是 NA 然后取反

na_rows <- df %>% 
  select(-"ID") %>% 
  is.na() %>% 
  {rowSums(.) == ncol(.)}

数据

df <- structure(list(ID = c(1L, 1L, 1L), a = c("ab", NA, NA), b = c(NA, 
"ab", NA)), class = "data.frame", row.names = c(NA, -3L))

另外还有一个 data.table 解决方案(感谢 akrun 提供的数据)。

library(data.table)
dt= data.table(structure(list(ID = c(1L, 1L, 1L), a = c("ab", NA, NA), 
                     b = c(NA, "ab", NA)), class = "data.frame", row.names = c(NA, -3L)))

dt[!(is.na(a) & is.na(b))]

Output:

   ID    a    b
1:  1   ab <NA>
2:  1 <NA>   ab

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM