【问题标题】:Count sequence of rows by group and restart the count every time the group changes [duplicate]按组计算行序列并在每次组更改时重新开始计数[重复]
【发布时间】:2020-11-10 13:28:41
【问题描述】:

如果我有以下数据:

library(dplyr)

tibble(
  id = rep(c("A", "B"), each = 3) %>% rep(2)
)
#> # A tibble: 12 x 1
#>    id   
#>    <chr>
#>  1 A    
#>  2 A    
#>  3 A    
#>  4 B    
#>  5 B    
#>  6 B    
#>  7 A    
#>  8 A    
#>  9 A    
#> 10 B    
#> 11 B    
#> 12 B

如果我想按组计算行的顺序,我通常会执行以下操作:

tibble(
  id = rep(c("A", "B"), each = 3) %>% rep(2)
) %>% 
  group_by(id) %>% 
  mutate(sequence_group = seq_along(id))
#> # A tibble: 12 x 2
#> # Groups:   id [2]
#>    id    sequence_group
#>    <chr>          <int>
#>  1 A                  1
#>  2 A                  2
#>  3 A                  3
#>  4 B                  1
#>  5 B                  2
#>  6 B                  3
#>  7 A                  4
#>  8 A                  5
#>  9 A                  6
#> 10 B                  4
#> 11 B                  5
#> 12 B                  6

但是,我会在每次组更改时重新开始计数。这是预期的输出

#> # A tibble: 12 x 2
#>    id    sequence_group
#>    <chr>          <int>
#>  1 A                  1
#>  2 A                  2
#>  3 A                  3
#>  4 B                  1
#>  5 B                  2
#>  6 B                  3
#>  7 A                  1
#>  8 A                  2
#>  9 A                  3
#> 10 B                  1
#> 11 B                  2
#> 12 B                  3

有什么建议吗?

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    使用data.table 辅助函数:

    library(data.table)
    df$sequence_group <- rowid(rleid(df$id))    
    df
    #    id    sequence_group
    #    <chr>          <int>
    #  1 A                  1
    #  2 A                  2
    #  3 A                  3
    #  4 B                  1
    #  5 B                  2
    #  6 B                  3
    #  7 A                  1
    #  8 A                  2
    #  9 A                  3
    # 10 B                  1
    # 11 B                  2
    # 12 B                  3
    

    与您的 dplyr 工作流程更相似的是:

    df %>% 
      group_by(tmp = rleid(id)) %>% 
      mutate(sequence_group = seq_along(id)) %>% 
      ungroup() %>% 
      select(-tmp)
    # Or simply
    df <- df %>% mutate(sequence_group = rowid(rleid(id)))
    

    最后,只使用基础 R:

    df$sequence_group <- unlist(lapply(rle(df$id)$lengths, seq_len))
    

    【讨论】:

      【解决方案2】:

      这行得通吗:

      library(dplyr)
      df %>% mutate(rids = rep(seq_along(rle(id)$values), rle(id)$lengths)) %>% 
         group_by(rids) %>% mutate(sequence_group = row_number()) %>% ungroup() %>% select(-rids)
      # A tibble: 12 x 2
         id    sequence_group
         <chr>          <int>
       1 A                  1
       2 A                  2
       3 A                  3
       4 B                  1
       5 B                  2
       6 B                  3
       7 A                  1
       8 A                  2
       9 A                  3
      10 B                  1
      11 B                  2
      12 B                  3
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-06-09
        • 1970-01-01
        • 2014-10-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-04
        • 1970-01-01
        相关资源
        最近更新 更多