将索引添加到等值的连续运行

做一个计数器索引比使用循环有更快的方法吗? 在相同价值的连续运行中,指数应该是相同的。 我发现这个循环非常慢,特别是当数据太大的时候。

为了说明,这里是input和期望的输出

x <- c(2, 3, 9, 2, 4, 4, 3, 4, 4, 5, 5, 5, 1) 

期望的结果计数器:

 c(1, 2, 3, 4, 5, 5, 6, 7, 7, 8, 8, 8, 9) 

请注意, 连续的运行具有不同的索引。 例如,请参阅值24的所需索引

我低效率的代码是这样的:

 group[1]<-1 counter<-1 for (i in 2:n){ if (x[i]==x[i-1]){ group[i]<-counter }else{ counter<-counter+1 group[1]<-counter} } 

如果你有这样的数字值,你可以使用diffcumsum来加起来的值的变化

 x <- c(2,3,9,2,4,4,3,4,4,5,5,5,1) cumsum(c(1,diff(x)!=0)) # [1] 1 2 3 4 5 5 6 7 7 8 8 8 9 

使用具有函数rleid()

 require(data.table) # v1.9.5+ rleid(x) # [1] 1 2 3 4 5 5 6 7 7 8 8 8 9 

这将与字符值的数字一起工作:

 rep(1:length(rle(x)$values), times = rle(x)$lengths) #[1] 1 2 3 4 5 5 6 7 7 8 8 8 9 

你可以通过调用rle一次(约快两倍)来提高rep.int而使用rep.int而不是rep可以使速度改善很小:

 y <- rle(x) rep.int(1:length(y$values), times = y$lengths)