![](/img/trans.png)
[英]Remove any rows where values don't match across specific columns, except if other value(s) is 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.cases
与if_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.