解决这个问题的规范tidyverse方式是利用一个谓词函数,该函数在select(where(...))
中使用,并将其与变量名选择相结合。
首先,我们可以编写一个自定义的谓词函数,在where
中使用,仅选择包含唯一NA
的列。
all_na <- function(x) {
all(is.na(x))
}
我们可以使用这个函数和一个布尔表达式配合使用,该布尔表达式说明当(read AND
&
)它为
all_na
时,我们
不想选择
y
。
library(dplyr)
df <- data.frame(
x = c(1,2,NA),
y = NA,
z = c(3,4,5)
)
df %>%
select(!(y & where(all_na)))
为了确定这是否有效,让我们重新定义
y
,使其不仅包含
NA
,我们将看到这一次它没有被取消选择:
df2 <- data.frame(
x = c(1,2,NA),
y = c(1,2,NA),
z = c(3,4,5)
)
df2 %>%
select(!(y & where(all_na)))
我们可以在where
语句中使用lambda函数来替代自定义函数:
df %>%
select(!(y & where(~ all(is.na(.x)))))
此内容由reprex包(v0.3.0)于2021-12-07创建
在更大的tidyverse中,我们还可以使用purrr::lmap_at
并使用.at
参数选择y
,然后创建一个lambda函数,如果all(is.na(.x))
则使用空的list()
(=删除该列),否则保留该列.x
:
library(purrr)
library(dplyr)
df %>%
lmap_at("y", ~ if(all(is.na(.x))) list() else .x)
本段内容由 reprex 包 (v2.0.1) 于 2021-12-07 创建