¿Hay un dplyr equivalente a data.table :: rleid?

data.table ofrece una buena función de conveniencia, rleid para la encoding de longitud de ejecución:

 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 

Puedo imitar esto en la base R con:

 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 

¿Alguien sabe de un equivalente dplyr (?) O es la “mejor” forma de crear el comportamiento dplyr con dplyr es hacer algo como lo siguiente

 library(dplyr) my_rleid = rep(seq_along(rle(df$grp)$values), times = rle(df$grp)$lengths) df %>% mutate(rleid = my_rleid) 

Puede hacer (cuando tiene ambos data.table y dplyr cargados):

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

esto da:

 > 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 

Cuando no desee cargar data.table por separado, también puede usar (como lo menciona @DavidArenburg en los comentarios):

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

Y como dijo @RichardScriven en su comentario, puedes copiarlo / robarlo:

 myrleid <- data.table::rleid 

Si desea usar solo la base R y dplyr , la mejor manera es terminar su propia versión de una o dos líneas de rleid() como una función y luego aplicar eso cuando lo necesite.

 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 

Puede hacerlo utilizando la función de lag de dplyr .

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

da

 > 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