下面写的函数的效率和更简单的版本可现在data.table包,叫rleid
。使用它,它只是:
setDT(dataset)[, counter := seq_len(.N), by=rleid(input)]
有关更多的用法和示例请参阅?rleid
。感谢@Henrik提供的更新此帖的建议。
rle
绝对是最方便的方法(+1 @ Ananda's)。但是对于更大的数据,人们可以做得更好(速度)。大数据
require(data.table)
arun <- function(y) {
w = data.table:::duplist(list(y))
w = c(diff(w), length(y)-tail(w,1L)+1L)
data.table:::vecseq(rep(1L, length(w)), w, length(y))
}
x <- c("a","b","b","a","a","c","a","a","a","a","b","c")
arun(x)
# [1] 1 1 2 1 2 1 1 2 3 4 1 1
标杆:您可以从data.table
按如下方式使用duplist
和vecseq
功能(不出口)
set.seed(1)
x <- sample(letters, 1e6, TRUE)
# rle solution
ananda <- function(y) {
sequence(rle(y)$lengths)
}
require(microbenchmark)
microbenchmark(a1 <- arun(x), a2<-ananda(x), times=100)
Unit: milliseconds
expr min lq median uq max neval
a1 <- arun(x) 123.2827 132.6777 163.3844 185.439 563.5825 100
a2 <- ananda(x) 1382.1752 1899.2517 2066.4185 2247.233 3764.0040 100
identical(a1, a2) # [1] TRUE
欢呼声,那就像一个魅力!你怎么知道$长度部分?还有其他属性吗? (不要在R Docs中看到它们)。 – Richard
@Richard,请参阅“文件”文档的“值”部分。返回的两个值(在''''''''''''''''列表中)是'长度'和'值'。 – A5C1D2H2I1M1N2O1R2T1