2015-05-19 17 views
6

C'è un modo più rapido per fare un indice contatore rispetto all'utilizzo di un ciclo? All'interno di esecuzioni contigue di valori uguali, l'indice dovrebbe essere lo stesso. Trovo il loop molto lento specialmente quando i dati sono così grandi.Aggiungere l'indice alle corse contigue di uguali valori

Per illustrazione, ecco l'ingresso e l'uscita desiderata

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

desiderata contatore risultante:

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

noti che non piste -contiguous hanno differenti indici. Per esempio. consultare gli indici desiderati dei valori 2 e 4

mio codice inefficiente è questo:

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

Grazie TimoSta per le modifiche =) – Rens

risposta

7

Se si dispone di valori numerici in questo modo, è possibile utilizzare diff e cumsum a sommare i cambiamenti nei valori

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 
+0

Grazie! Questo codice funziona bene. =) – Rens

+0

Decisamente più veloce della mia risposta. Al momento non è possibile valutare la risposta 'data.table' di Arun. – Jota

+0

Grazie Frank per questo commento. Ora userò il suggerimento di MrFlick. Sembra che sia necessaria qualche installazione per il suggerimento data.table di Arun. – Rens

8

Utilizzando data.table, che ha la funzione rleid():

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

Grazie per l'aiuto! =) – Rens

6

Questo funziona con numerica di valori di carattere:

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

Si può anche essere un po 'più efficiente chiamando rle solo una volta (circa 2 volte più veloce) e una molto lieve miglioramento della velocità può essere effettuato utilizzando rep.int invece di rep:

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

Grazie. Anche questo codice funziona! =) – Rens