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

Jas*_*lns 15 r run-length-encoding dplyr data.table

data.tablerleid为游程编码提供了一个很好的便利功能:

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
Run Code Online (Sandbox Code Playgroud)

我可以在以下基础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
Run Code Online (Sandbox Code Playgroud)

有没有人知道dplyr等效(?)或创建rleid行为的"最佳"方法dplyr是执行以下操作

library(dplyr)

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

df %>%
  mutate(rleid = my_rleid)
Run Code Online (Sandbox Code Playgroud)

Jaa*_*aap 21

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

DT <- DT %>% mutate(rlid = rleid(grp))
Run Code Online (Sandbox Code Playgroud)

这给了:

> 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
Run Code Online (Sandbox Code Playgroud)

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

DT <- DT %>% mutate(rlid = data.table::rleid(grp))
Run Code Online (Sandbox Code Playgroud)

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

myrleid <- data.table::rleid
Run Code Online (Sandbox Code Playgroud)

  • 偷了它......`myrleid < - data.table :: rleid` (11认同)
  • @JasonAizkalns如果你只是要使用hadley-verse,那么你将非常自我限制. (8认同)
  • @JasonAizkalns为什么?如果我可以问? (3认同)
  • @RichardScriven这可能是我要求的,但看看是否有其他人有其他想法.另一个原因是为教学/教育目的保留一个"范例",并避免向新用户引入太多包. (3认同)
  • 如果你做`DT%>%mutate(rlid = data.table :: rleid(grp)),你不需要加载(刚刚安装)`data.table` (2认同)

Jos*_*ien 11

如果你只想使用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
Run Code Online (Sandbox Code Playgroud)

  • 小记:`RLEID()`设计与列表/ data.frames/data.tables工作为好,如`RLEID(C(1,1,1,2,2,2),C(3,4 ,4,5,5,6))`.没有什么特别的实施它,只是要注意区别. (7认同)
  • 是的,但它是`rleidv(mtcars)`(SE版).`rleid()`将`...`作为输入 - 所以我们必须单独提供每一列..(对于交互式情况). (5认同)

H 1*_*H 1 10

v1.1.0 consecutive_id()添加了建模函数,data.table::rleid()对多个向量和值的处理具有相同的支持NA

 library(dplyr)
 
 DT %>%
   mutate(id = consecutive_id(grp)) 

    grp value id
 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
Run Code Online (Sandbox Code Playgroud)


Ale*_*lex 6

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

DT <-
    DT %>%
    mutate(rleid = (grp != lag(grp, 1, default = "asdf"))) %>%
    mutate(rleid = cumsum(rleid))
Run Code Online (Sandbox Code Playgroud)

> 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
Run Code Online (Sandbox Code Playgroud)


tmf*_*mnk 5

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
Run Code Online (Sandbox Code Playgroud)

或者:

DT %>%
 mutate(rleid = rep(seq(ls <- rle(grp)$lengths), ls))
Run Code Online (Sandbox Code Playgroud)