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

是否存在与data.table::rleid等效的dplyr?,r,dplyr,data.table,run-length-encoding,R,Dplyr,Data.table,Run Length Encoding,data.table为行程编码提供了一个非常方便的功能: 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 我可以在baseR中模拟这一点: df <- data.frame(DT) rep(seq_along(rle(df$grp)$values), t

data.table
为行程编码提供了一个非常方便的功能:

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
我可以在base
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
您只需执行以下操作(当您同时拥有和加载了这两个选项时):

当您不想单独加载时,也可以使用(如@davidernburg在评论中提到的):

DT%突变(rlid=data.table::rleid(grp))
正如@RichardScriven在他的评论中所说,你可以复制/窃取它:

myrleid <- data.table::rleid

myrleid如果只想使用base 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
库(dplyr)

myrleid您可以使用
dplyr
中的
lag
功能来执行此操作

DT <-
    DT %>%
    mutate(rleid = (grp != lag(grp, 1, default = "asdf"))) %>%
    mutate(rleid = cumsum(rleid))
OP使用的方法的简化(不涉及额外的程序包)可以是:

DT %>%
 mutate(rleid = with(rle(grp), rep(seq_along(lengths), lengths)))

   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
或:

DT%>%

mutate(rleid=rep)(seq(ls-Dplyr与data.table兼容。如果出于某种原因,您不想加载data.table,我认为您的基本解决方案是好的。您可以尝试向Dplyr提交功能请求,但我认为接收良好的几率不超过50/50。
cumsum(c(1L,df$grp[-nrow(df)]!=df$grp[-1]))
同样适用于baseAgreed,但我希望尽可能避免调用
data.table::rleid
。@JasonAizkalns为什么?如果我可以问的话?偷走它…
myrleid@RichardScriven这可能是我要求助的,但看看其他人是否有其他想法。另一个原因是停留在一个“范式”中出于教学/教育目的,避免向新用户介绍太多的软件包。@JasonAizkalns如果你只打算使用哈德利诗句,那么你将在很大程度上限制自己。小注:
rleid()
设计用于处理列表/data.frames/data.tables,例如
rleid(c(1,1,1,2,2),c(3,4,5,6))
。实现它没有什么特别之处,只是要注意区别。@Arun应该
数据。table::rleid(mtcars)
工作?(对我来说,它不工作,尽管它的帮助文件会让我相信它应该……)是的,但它是
rleidv(mtcars)
(SE版本)。
rleid()
..
作为输入,因此我们必须分别提供每个列(用于交互式案例)。注意:如果
NA
此解决方案不提供与
数据相同的解决方案。table::rleid
。签出
x
myrleid <- data.table::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
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
DT %>%
 mutate(rleid = with(rle(grp), rep(seq_along(lengths), lengths)))

   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
DT %>%
 mutate(rleid = rep(seq(ls <- rle(grp)$lengths), ls))