【问题标题】:How to pass an arbitrary size list of columns to dplyr::filter?如何将任意大小的列列表传递给 dplyr::filter?
【发布时间】:2022-12-12 18:16:42
【问题描述】:

假设我们有这个数据框:

> data <- data.frame('a' = c('a', 'b', 'c'), 
                   'b' = c('d', 'e', 'f'), 
                   'c' = c('g', 'h', 'i'),
                   'd' = c('j', 'k', 'l'))

如果我想根据 a 列进行过滤以获得一些价值,我可以这样做:

> library(dplyr)
> data %>% filter(a == "b")

  a b c d
1 b e h k

如果我想根据 a 和 b 列进行过滤以获得一些价值,我可以这样做:

> library(dplyr)
> data %>% filter(a == "c" & b == "f")

  a b c d
1 c f i l

如果我有一个任意长度的列列表怎么办? 有没有办法做这样的事情?

> data %>% filter(c(a,b) == c("c","f"))

因此,我可以将任意列名列表以及所需值列表传递给过滤器函数。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    您可以使用 data.frame 来跟踪条件并使用连接语法而不是 filter():

    filter_df <- data.frame(a = "c", b = "f")
    
    data |>  
      inner_join(filter_df)
    
    #   a b c d
    # 1 c f i l
    

    【讨论】:

      【解决方案2】:

      使用if_any;保持一排,如果任何的列匹配相等性。

      library(dplyr)
      data %>% 
        filter(if_any(c(a, b), `%in%`, c("c","f")))
      
      #  a b c d
      #1 c f i l
      

      或者if_all;保持一排,如果全部(选定的)列匹配相等性。所以在这里,如果所有列至少有 "c""f"

      data %>% 
        filter(if_all(c(a, b), `%in%`, c("c","f")))
      
      #  a b c d
      #1 c f i l
      

      查看tidyselect 函数以了解更多如何轻松选择if_* 的第一个参数中的列。

      【讨论】:

      • 看起来 OP 正在寻找 if all not if any。正确的?
      • 不完全确定。两者都会导致相同的答案。
      猜你喜欢
      • 1970-01-01
      • 2017-10-16
      • 2012-12-04
      • 2017-09-12
      • 1970-01-01
      • 1970-01-01
      • 2017-02-24
      • 2015-04-04
      • 1970-01-01
      相关资源
      最近更新 更多