首页 文章

是否存在与data.table :: rleid等效的dplyr?

提问于
浏览
13

data.table 提供了一个很好的便利函数,rleid用于游程编码:

library(data.table)
DT = data.table(grp=rep(c("A", "B", "C", "A", "B"), c(2, 2, 3, 1, 2)), value=1:10)
rleid(DT$grp)
# [1] 1 1 2 2 3 3 3 4 5 5

我可以在 R 基础上模仿这个:

df <- data.frame(DT)
rep(seq_along(rle(df$grp)$values), times = rle(df$grp)$lengths)
# [1] 1 1 2 2 3 3 3 4 5 5

有没有人知道 dplyr 等价物(?)或"best"用 dplyr 创建 rleid 行为的方法是做类似下面的事情

library(dplyr)

my_rleid = rep(seq_along(rle(df$grp)$values), times = rle(df$grp)$lengths)

df %>%
  mutate(rleid = my_rleid)

3 回答

  • 5

    你可以这样做(当你同时加载data.tabledplyr时):

    DT <- DT %>% mutate(rlid = rleid(grp))
    

    这给了:

    DT
    grp值rlid
    1:A 1 1
    2:A 2 1
    3:B 3 2
    4:B 4 2
    5:C 5 3
    6:C 6 3
    7:C 7 3
    8:A 8 4
    9:B 9 5
    10:B 10 5

    当您不想单独加载data.table时,您也可以使用(如评论中@DavidArenburg所述):

    DT <- DT %>% mutate(rlid = data.table::rleid(grp))
    

    正如@RichardScriven在评论中所说,你可以复制/窃取它:

    myrleid <- data.table::rleid
    
  • 19

    如果你只想使用基数R和 dplyr ,更好的方法是将你自己的一行或两行版本的 rleid() 作为一个函数包装起来,然后在你需要的时候应用它 .

    library(dplyr)
    
    myrleid <- function(x) {
        x <- rle(x)$lengths
        rep(seq_along(x), times=x)
    }
    
    ## Try it out
    DT <- DT %>% mutate(rlid = myrleid(grp))
    DT
    #   grp value rlid
    # 1:   A     1    1
    # 2:   A     2    1
    # 3:   B     3    2
    # 4:   B     4    2
    # 5:   C     5    3
    # 6:   C     6    3
    # 7:   C     7    3
    # 8:   A     8    4
    # 9:   B     9    5
    #10:   B    10    5
    
  • 9

    你可以使用 dplyr 中的 lag 函数来完成它 .

    DT <-
        DT %>%
        mutate(rleid = (grp != lag(grp, 1, default = "asdf"))) %>%
        mutate(rleid = cumsum(rleid))
    

    > DT
        grp value rleid
     1:   A     1     1
     2:   A     2     1
     3:   B     3     2
     4:   B     4     2
     5:   C     5     3
     6:   C     6     3
     7:   C     7     3
     8:   A     8     4
     9:   B     9     5
    10:   B    10     5
    

相关问题