使用 filter() 和 cross() 保留包含任何变量缺失值的数据帧的所有行

Bra*_*ell 15 r dplyr r4epi

有时我想查看数据框中的所有行,如果我删除所有变量的缺失值的所有行,这些行将被删除。在这种情况下,我对如何使用动词内部使用的dplyr1.0across()函数执行此操作特别感兴趣filter()

这是一个示例数据框:

df <- tribble(
  ~id, ~x, ~y,
  1, 1, 0,
  2, 1, 1,
  3, NA, 1,
  4, 0, 0,
  5, 1, NA
)
Run Code Online (Sandbox Code Playgroud)

tidyverse 网站上提供了用于保留包含任何缺失值的行的代码。具体来说,我可以使用:

df %>% 
  filter(
    across(
      .cols = everything(),
      .fns = ~ !is.na(.x)
    )
  )
Run Code Online (Sandbox Code Playgroud)

返回:

# A tibble: 3 x 3
     id     x     y
  <dbl> <dbl> <dbl>
1     1     1     0
2     2     1     1
3     4     0     0
Run Code Online (Sandbox Code Playgroud)

但是,我想不出如何返回相反-行任何变量缺失值。我正在寻找的结果是:

# A tibble: 2 x 3
     id     x     y
  <dbl> <dbl> <dbl>
1     3    NA     1
2     5     1    NA
Run Code Online (Sandbox Code Playgroud)

我的第一个想法是删除!

df %>% 
  filter(
    across(
      .cols = everything(),
      .fns = ~ is.na(.x)
    )
  )
Run Code Online (Sandbox Code Playgroud)

但是,它返回零行。

当然,如果我提前知道所有具有缺失值的变量,我可以通过这段代码得到我想要的答案:

df %>% 
  filter(is.na(x) | is.na(y))
Run Code Online (Sandbox Code Playgroud)

但是,我正在寻找一种不需要我提前知道哪些变量具有缺失值的解决方案。此外,我知道如何使用该filter_all()函数执行此操作:

df %>% 
  filter_all(any_vars(is.na(.)))
Run Code Online (Sandbox Code Playgroud)

但是,该filter_all()功能已被across()现有动词中的使用取代。见https://dplyr.tidyverse.org/articles/colwise.html

我所做的其他不成功的尝试是:

df %>% 
  filter(
    across(
      .cols = everything(),
      .fns = ~any_vars(is.na(.x))
    )
  )

df %>% 
  filter(
    across(
      .cols = everything(),
      .fns = ~!!any_vars(is.na(.x))
    )
  )

df %>% 
  filter(
    across(
      .cols = everything(),
      .fns = ~!!any_vars(is.na(.))
    )
  )

df %>% 
  filter(
    across(
      .cols = everything(),
      .fns = ~any(is.na(.x))
    )
  )

df %>% 
  filter(
    across(
      .cols = everything(),
      .fns = ~any(is.na(.))
    )
  )
Run Code Online (Sandbox Code Playgroud)

Emm*_*man 10

现在可以使用dplyr1.0.4。过滤用例的新if_any()替换across()

library(dplyr)

df <- tribble(~ id, ~ x, ~ y,
              1, 1, 0,
              2, 1, 1,
              3, NA, 1,
              4, 0, 0,
              5, 1, NA)

df %>% 
  filter(if_any(everything(), is.na))
#> # A tibble: 2 x 3
#>      id     x     y
#>   <dbl> <dbl> <dbl>
#> 1     3    NA     1
#> 2     5     1    NA
Run Code Online (Sandbox Code Playgroud)

reprex 包(v0.3.0)于2021年 2 月 10 日创建

有关更多详细信息,请参见此处:https : //www.tidyverse.org/blog/2021/02/dplyr-1-0-4-if-any/