【问题标题】:How can I filter by NAs in R programming with Dplyr如何使用 Dplyr 在 R 编程中按 NA 过滤
【发布时间】:2026-01-26 20:50:02
【问题描述】:

我正在尝试使用 Dplyr 和 filter 函数按 NA 进行过滤(只需将具有 NA 的行保留在指定列中)。使用下面的代码,只是返回没有数据的列标签。我是否正确编写代码?此外,如果没有 dplyr 有可能(或更容易)做,那也很有趣。谢谢。

filter(tata4, CompleteSolution == "NA", KeptInformed == "NA")

【问题讨论】:

  • tata4[is.na(tata4&CompleteSolution) & is.na(tata4$KeptInformed),] 假设这些是每一列。无论如何,我认为 is.na() 是您所追求的。
  • 使用is.na 而不是== "NA",后者会查找字符串。
  • 下一次,请考虑提供一个可重现的例子,就像 Steven 在他的回答的“数据”部分所做的那样。

标签: r dplyr na


【解决方案1】:

你可以使用complete.cases()

dplyr::filter(df, !complete.cases(col1, col2))

这给出了:

#  col1 col2 col3
#1   NA    5    5
#2   NA    6    6
#3    5   NA    7

基准测试

large_df <- df[rep(seq_len(nrow(df)), 10e5), ]

目前的结果:

library(microbenchmark)
mbm <- microbenchmark(
  akrun1 = large_df[rowSums(is.na(large_df[1:2]))!=0, ],
  akrun2 = large_df[Reduce(`|`, lapply(large_df[1:2], is.na)), ],
  steven = filter(large_df, !complete.cases(col1, col2)),
  times = 10)

#Unit: milliseconds
#   expr      min       lq      mean    median        uq       max neval cld
# akrun1 814.0226 924.0837 1248.9911 1208.7924 1434.2415 2057.1338    10   c
# akrun2 499.3404 671.9900  736.2418  687.9194  861.4477 1068.1232    10  b 
# steven 112.9394 113.0604  214.1688  198.4542  299.7585  355.1795    10 a 

数据

df <- structure(list(col1 = c(1, 2, 3, 4, NA, NA, 5), col2 = c(1, 2, 
3, 4, 5, 6, NA), col3 = c(1, 2, 3, 4, 5, 6, 7)), .Names = c("col1", 
"col2", "col3"), row.names = c(NA, -7L), class = "data.frame")

【讨论】:

  • 知道了。谢谢。
【解决方案2】:

在 dplyr 中,您可以通过以下方式过滤 NAs

tata4 %>%
filter(is.na(CompleteSolution), is.na(KeptInformed))

【讨论】:

    【解决方案3】:

    我们可以在逻辑矩阵(is.na(df[1:2]))上使用rowSums,检查它是否不等于0,得到一个逻辑向量并将其用于子集。

     df[rowSums(is.na(df[1:2]))!=0,]
     #    col1 col2 col3
     #5   NA    5    5
     #6   NA    6    6
     #7    5   NA    7
    

    或者Reducelapply

    df[Reduce(`|`, lapply(df[1:2], is.na)),]
    

    【讨论】: