如何根据 dplyr 中的多个条件 select 列

How to select columns depending on multiple conditions in dplyr

我正在 dplyr 中寻找解决方案,以解决 select 基于多个条件处理数据框列的任务。比如说,我们有这种 df:

X <- c("B", "C", "D", "E")
a1 <- c(1, 0, 3, 0)
a2 <- c(235, 270, 100, 1)
a3 <- c(3, 1000, 900, 2)
df1 <- data.frame(X, a1, a2, a3)

让我们进一步假设我想要 select column/those 列

也就是在这种情况下,我们要select的是列a1。如何在 dplyr 中完成此操作?我的理解是,为了 select dplyr 中的一个列,您使用 select,如果 selection 受条件约束,那么 where。但是如何组合两个这样的 select(where...) 语句呢?例如,这不是正确的方法,因为它会引发错误:

df1 %>%
  select(where(is.numeric) & where(~ all(.) < 5))
Error: `where()` must be used with functions that return `TRUE` or `FALSE`.
Run `rlang::last_error()` to see where the error occurred.
In addition: Warning message:
In all(.) : coercing argument of type 'character' to logical

where 内部,我们需要提供具有逻辑结果的函数。

library(dplyr)

select(df1, \(x) all(x < 5))

# or this, which might be more semantically correct
select(df1, where(\(x) is.numeric(x) & all(x < 5)))

  a1
1  1
2  0
3  3
4  0

数据

df1 <- structure(list(X = c("B", "C", "D", "E"), a1 = c(1, 0, 3, 0), 
    a2 = c(235, 270, 100, 1), a3 = c(3, 1000, 900, 2)), class = "data.frame", row.names = c(NA, 
-4L))

另一种可能的解决方案,基于dplyr::mutate

library(dplyr)

df1 %>% 
  mutate(across(everything(), ~ if (all(.x < 5) & is.numeric(.x)) .x))

#>   a1
#> 1  1
#> 2  0
#> 3  3
#> 4  0

或者更短:

df1 %>% 
  mutate(across(everything(), ~ if (all(.x < 5)) .x))