2011-09-22 18 views
6

Tengo una larga serie temporal en la que necesito identificar y marcar secuencias de valores repetidos. He aquí algunos datos:Identificando secuencias de números repetidos en 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 

Así que si tengo que tener en cuenta cuando un valor se repite tres o más veces, tengo una secuencia de cuatro '126' y una secuencia de tres '132' que necesitan ser marcado.

Soy nuevo en R. Espero que use cbind para crear una nueva columna en esta matriz con una "T" en las filas correspondientes, pero cómo llenar la columna correctamente es un misterio. ¿Alguna sugerencia, por favor? Gracias un montón.

Respuesta

4

¡Usa rle para hacer el trabajo! Es una función sorprendente que calcula el número de repeticiones sucesivas de números en una secuencia. Aquí hay un código de ejemplo sobre cómo puede usar rle para marcar los herejes en sus datos. Esto devolverá todas las filas del marco de datos que tienen WDIR que se repiten 3 o más veces sucesivamente.

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

Como dice Ramnath, puede usar 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 devuelve un objeto con dos componentes, longitudes y valores. Podemos usar la pieza de longitudes para construir una nueva columna que identifique qué valores se repiten más de tres veces.

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 

Esta será nuestra nueva columna.

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

Dos opciones para usted.

Suponiendo que se carga los datos:

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) 

Opción 1: Clasificación

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 

Opción 2: Oneliner

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

pensé ser un nuevo usuario que opción 1 podría ser un enfoque paso a paso más fácil, aunque el rep(table(), table()) puede no ser intuitivo inicialmente.

Cuestiones relacionadas