【问题标题】:Efficient way to filter only first rows where condition is met?仅过滤满足条件的第一行的有效方法?
【发布时间】:2020-11-26 15:25:36
【问题描述】:

假设我有一个类似的数据框,

library(dplyr)

data <- tibble(
   label = c("a","a","b","a","c","c","a")
)
data$index <- 1:nrow(data)

我不想子集label == "a" 所在的所有行,而仅这是正确的第一行

在示例中,我想要前两行:

  label index
  <chr> <int>
1 a         1
2 a         2

因为下一行标签是“b”。应忽略 label == "a" 的所有后续行。

我已经用 for 循环实现了一个丑陋的解决方案,但肯定有一种有效的过滤方式吗?

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    你可以使用:

    data %>% 
      filter(data.table::rleid(label) == 1)
    
    # A tibble: 2 x 2
      label index
      <chr> <int>
    1 a         1
    2 a         2
    

    【讨论】:

      【解决方案2】:

      一个选项可能是:

      data %>%
       slice_max(label == "a", n = 2, with_ties = FALSE)
      
        label index
        <chr> <int>
      1 a         1
      2 a         2
      

      但是,当 n 大于实际组大小时,可能会产生意想不到的结果。解决此问题的解决方案:

      data %>%
       slice(head(which(label == "c"), 3))
      
        label index
        <chr> <int>
      1 c         5
      2 c         6
      

      【讨论】:

        【解决方案3】:

        如果你只想使用 rle:

        library(dplyr)
        data %>% filter(rep(seq_along(rle(label)$values), rle(label)$lengths) == 1)
        # A tibble: 2 x 2
          label index
          <chr> <int>
        1 a         1
        2 a         2
        

        【讨论】:

          【解决方案4】:

          还有一个选项是与列的lag 进行比较,使用cumsum 创建一个数字索引并将其转换为逻辑到filter

          library(dplyr)
          data %>% 
                filter(cumsum(label != lag(label, default = first(label))) < 1)
          # A tibble: 2 x 2
          #  label index
          #  <chr> <int>
          #1 a         1
          #2 a         2
          

          【讨论】:

            猜你喜欢
            • 2013-04-08
            • 2022-12-21
            • 2018-03-20
            • 2020-01-31
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2021-11-30
            • 1970-01-01
            相关资源
            最近更新 更多