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

时间:2015-11-03 19:53:40

标签: r dplyr data.table run-length-encoding

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等效(?)或使用rleid创建dplyr行为的“最佳”方式是执行以下操作

library(dplyr)

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

df %>%
  mutate(rleid = my_rleid)

4 个答案:

答案 0 :(得分:21)

您可以这样做(当您同时加载时):

DT <- DT %>% mutate(rlid = rleid(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

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

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

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

myrleid <- data.table::rleid

答案 1 :(得分:10)

如果您只想使用基础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

答案 2 :(得分:6)

您可以使用Quick Auto Configure中的lag功能。

dplyr

给出

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

答案 3 :(得分:1)

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 <- rle(grp)$lengths), ls))