为相等值

时间:2015-05-19 00:01:50

标签: r performance loops indexing counting

制作计数器索引的方法是否比使用循环更快?在相等值的连续运行中,索引应该相同。我发现循环非常慢,特别是当数据太大时。

为了说明,这里是输入和所需的输出

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}
}

4 个答案:

答案 0 :(得分:9)

使用data.table,其函数为rleid()

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

答案 1 :(得分:8)

如果你有这样的数值,你可以使用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

答案 2 :(得分:6)

这将适用于字符值的数字:

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一次(大约快2倍)可以提高效率,并且可以使用rep.int代替{{em>非常轻微提高速度{1}}:

rep

答案 3 :(得分:1)

Jota的Above answer可以进一步简化,这样会更快

with(rle(x), rep(1:length(lengths), lengths))

 [1] 1 2 3 4 5 5 6 7 7 8 8 8 9