在“dplyr”中一次按多列进行过滤

Hug*_*den 6 r dplyr

这是一些示例数据

library(tidyverse)

data <- matrix(runif(20), ncol = 4) 
colnames(data) <- c("mt100", "cp001", "cp002", "cp003")
data <- as_tibble(data)
Run Code Online (Sandbox Code Playgroud)

真实的数据集有更多的列,但实际上有很多列都以“cp”开头。我dplyr可以选择所有这些列

data %>%
  select(starts_with("cp"))
Run Code Online (Sandbox Code Playgroud)

有没有一种方法可以使用starts_with(或类似的函数)按多列进行过滤,而不必显式地全部写入?我在想这样的事情

data %>%
  filter(starts_with("cp") > 0.2)
Run Code Online (Sandbox Code Playgroud)

谢谢!

Tar*_*Jae 23

我们可以使用if_allif_any正如 Anil 在他的评论中指出的那样:对于您的代码,这将是:

\n

https://www.tidyverse.org/blog/2021/02/dplyr-1-0-4-if-any/

\n

if_any() 和 if_all()

\n

“across() 在 summarise() 和 mutate() 中非常有用,但是\xe2\x80\x99s 很难将它与 filter() 一起使用,因为不清楚如何将结果组合成一个逻辑向量。因此为了填补这个空白,我们\xe2\x80\x99引入了两个新函数if_all()和if_any()。”

\n

我摔倒

\n
data %>% \n  filter(if_all(starts_with("cp"), ~ . > 0.2))\n
Run Code Online (Sandbox Code Playgroud)\n
  mt100 cp001 cp002 cp003\n  <dbl> <dbl> <dbl> <dbl>\n1 0.688 0.402 0.467 0.646\n2 0.663 0.757 0.728 0.335\n3 0.472 0.533 0.717 0.638\n
Run Code Online (Sandbox Code Playgroud)\n

如果有:

\n
data %>% \n  filter(if_any(starts_with("cp"), ~ . > 0.2))\n
Run Code Online (Sandbox Code Playgroud)\n
  mt100 cp001   cp002 cp003\n  <dbl> <dbl>   <dbl> <dbl>\n1 0.554 0.970 0.874   0.187\n2 0.688 0.402 0.467   0.646\n3 0.658 0.850 0.00813 0.542\n4 0.663 0.757 0.728   0.335\n5 0.472 0.533 0.717   0.638\n
Run Code Online (Sandbox Code Playgroud)\n

  • 我相信 op 需要 `if_all` 它将给出与 `cross` 类似的结果 (2认同)

Gre*_*gor 8

dplyr::across()您可以与 purrr 风格的匿名函数一起使用:

\n
data %>%\n  filter(across(starts_with("cp"), ~ . > .2))\n# # A tibble: 3 \xc3\x97 4\n#   mt100 cp001 cp002 cp003\n#   <dbl> <dbl> <dbl> <dbl>\n# 1 0.628 0.604 0.802 0.501\n# 2 0.744 0.283 0.702 0.493\n# 3 0.279 0.372 0.975 0.751\n
Run Code Online (Sandbox Code Playgroud)\n

(请注意,如果没有set.seed(),我们的结果会因 RNG 的不同而有所不同。)

\n