![](/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.