2011-09-22 23 views
6

Ho una serie storica lunga in cui ho bisogno di identificare e segnalare sequenze di valori ripetuti. Ecco alcuni dati:Identificare sequenze di numeri ripetuti in R

DATETIME WDIR 
1 40360.04 22 
2 40360.08 23 
3 40360.12 126 
4 40360.17 126 
5 40360.21 126 
6 40360.25 126 
7 40360.29 25 
8 40360.33 26 
9 40360.38 132 
10 40360.42 132 
11 40360.46 132 
12 40360.50 30 
13 40360.54 132 
14 40360.58 35 

Quindi, se ho bisogno di rilevare quando un valore viene ripetuto tre o più volte, ho una sequenza di quattro '126' e una sequenza di tre '132' che devono essere contrassegnati.

Sono molto nuovo a R. Prevedo di utilizzare cbind per creare una nuova colonna in questo array con una "T" nelle righe corrispondenti, ma come popolare correttamente la colonna è un mistero. Qualsiasi suggerimento per favore? Grazie mille.

risposta

4

Utilizzare rle per fare il lavoro !! È una funzione incredibile che calcola il numero di ripetizioni successive di numeri in una sequenza. Ecco alcuni esempi di codice su come utilizzare rle per contrassegnare i miscredenti nei dati. Ciò restituirà tutte le righe dal frame di dati che hanno WDIR che si ripetono 3 o più volte in successione.

runs = rle(mydf$WDIR) 
subset(mydf, WDIR %in% runs$values[runs$lengths >= 3]) 
9

Come dice Ramnath, è possibile utilizzare rle.

rle(dat$WDIR) 
Run Length Encoding 
    lengths: int [1:9] 1 1 4 1 1 3 1 1 1 
    values : int [1:9] 22 23 126 25 26 132 30 132 35 

rle restituisce un oggetto con due componenti, lunghezze e valori. Possiamo usare il pezzo delle lunghezze per costruire una nuova colonna che identifichi quali valori sono ripetuti più di tre volte.

tmp <- rle(dat$WDIR) 
rep(tmp$lengths >= 3,times = tmp$lengths) 
[1] FALSE FALSE TRUE TRUE TRUE TRUE FALSE FALSE TRUE TRUE TRUE FALSE FALSE FALSE 

Questa sarà la nostra nuova colonna.

newCol <- rep(tmp$lengths > 1,times = tmp$lengths) 
cbind(dat,newCol) 
    DATETIME WDIR newCol 
1 40360.04 22 FALSE 
2 40360.08 23 FALSE 
3 40360.12 126 TRUE 
4 40360.17 126 TRUE 
5 40360.21 126 TRUE 
6 40360.25 126 TRUE 
7 40360.29 25 FALSE 
8 40360.33 26 FALSE 
9 40360.38 132 TRUE 
10 40360.42 132 TRUE 
11 40360.46 132 TRUE 
12 40360.50 30 FALSE 
13 40360.54 132 FALSE 
14 40360.58 35 FALSE 
0

Due opzioni per voi.

Supponendo che i dati vengono caricati:

dat <- read.table(textConnection(" 
DATETIME WDIR 
40360.04 22 
40360.08 23 
40360.12 126 
40360.17 126 
40360.21 126 
40360.25 126 
40360.29 25 
40360.33 26 
40360.38 132 
40360.42 132 
40360.46 132 
40360.50 30 
40360.54 132 
40360.58 35"), header=T) 

Opzione 1: Ordinamento

dat <- dat[order(dat$WDIR),] # needed for the 'repeats' to be pasted into the correct rows in next step 
dat$count <- rep(table(dat$WDIR),table(dat$WDIR)) 
dat$more4 <- ifelse(dat$count < 4, F, T) 
dat <- dat[order(dat$DATETIME),] # sort back to original order 
dat 

Opzione 2: Oneliner

dat$more4 <- ifelse(dat$WDIR %in% names(which(table(dat$WDIR)>3)),T,F) 
dat 

ho pensato di essere un nuovo utente che opzione 1 potrebbe essere un approccio più semplice, anche se il rep(table(), table()) potrebbe non essere inizialmente intuitivo.

Problemi correlati