【问题标题】:Filter data.frame with multiple conditions without writing them out过滤具有多个条件的data.frame而不写出它们
【发布时间】:2020-12-02 07:58:25
【问题描述】:

如何在不实际写出的情况下通过多个条件有效地过滤data.frame

为了更清楚,让我们看一下下面的小而简化的示例,其中希望提取介于 1 和 2 或 4 和 6 或 60 和 65 之间的从 1 到 100 的所有整数:

df <- data.frame(number = 1:100, someothermeasure = rnorm(100))
filters <- matrix(c(1,2,4,6,60,65), ncol = 2, byrow = T)

我想要与以下相同的结果,但没有手动列出各个条件:

dplyr::filter(df, (number >= filters[1,1] & number <= filters[1,2])|(number >= filters[2,1] & number <= filters[2,2])|(number >= filters[3,1] & number <= filters[3,2]))

只有在有少量条件需要过滤时才可以写出来。但是,当过滤条件dim(filters)[1] 等于10000 时该怎么办?这种情况该如何处理?

【问题讨论】:

    标签: r dataframe filter dplyr tidyverse


    【解决方案1】:

    带有rowwise()filter()dplyr 解决方案。

    library(dplyr)
    
    df %>%
      rowwise() %>%
      filter(any(number >= filters[, 1] & number <= filters[, 2])) %>%
      ungroup()
    
    

    或者您可以在purrr 中使用pmap_dfr(),它会自动按行组合所有过滤后的数据。

    library(purrr)
    
    pmap_dfr(as.data.frame(filters),
             ~ filter(df, number >= .x & number <= .y))
    

    两种方法都给出

    # # A tibble: 11 x 2
    #    number someothermeasure
    #     <int>            <dbl>
    #  1      1           -0.319
    #  2      2            0.497
    #  3      4            0.501
    #  4      5            1.20 
    #  5      6           -0.741
    #  6     60            0.954
    #  7     61            1.59 
    #  8     62            1.10 
    #  9     63            0.348
    # 10     64            0.242
    # 11     65           -0.170
    

    【讨论】:

    • @Joshua 我更新了另一个,其概念类似于 SebSta 的答案,但可能更简洁。
    • @Darren Tsai,这个也不错,不知道那个功能。非常感谢。
    【解决方案2】:

    apply 是一个很好的工具,可以多次应用一个函数:

    apply(X = filters, MARGIN = 1, FUN = function(x,y){
      y %>% 
        dplyr::filter(number >= x[1] & number <= x[2])
    }, y = df)
    

    【讨论】:

    • 谢谢,好主意,然后我会用do.call(rbind, ) 包裹它。
    • 没错。我想知道rbind 还是rbind.data.frame 在这里更好,但这毕竟是一个不同的问题。
    猜你喜欢
    • 2020-04-17
    • 2021-01-27
    • 1970-01-01
    • 1970-01-01
    • 2013-01-18
    • 2019-08-25
    • 1970-01-01
    • 2021-07-05
    • 1970-01-01
    相关资源
    最近更新 更多