2011-09-22 11 views
6

Mam długą serię czasową, w której muszę identyfikować i oznaczać sekwencje powtarzających się wartości. Oto niektóre dane:Identyfikacja sekwencji powtarzających się liczb w 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 

Więc jeśli muszę pamiętać, gdy wartość powtarza się trzy lub więcej razy, mam sekwencję czterech „126” i sekwencji trzech „132”, które muszą być oznaczone.

Jestem bardzo nowy dla R. Oczekuję, że użyję cbind do utworzenia nowej kolumny w tej tablicy z "T" w odpowiednich wierszach, ale jak poprawnie wypełnić kolumnę jest tajemnicą. Jakieś wskazówki, proszę? Wielkie dzięki.

Odpowiedz

4

Użyj rle, aby wykonać zadanie !! Jest to niesamowita funkcja, która oblicza liczbę kolejnych powtórzeń liczb w sekwencji. Oto przykładowy kod, w jaki sposób można użyć rle do oznaczenia pomyłek w danych. Spowoduje to zwrócenie wszystkich wierszy z ramki danych, które mają WDIR, które są powtarzane kolejno 3 lub więcej razy.

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

Jak mówi Ramnath, można użyć 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 zwraca się obiekt z dwóch części, długości i wartości. Możemy użyć kawałka długości do zbudowania nowej kolumny, która identyfikuje, które wartości są powtarzane więcej niż trzy razy.

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 

To będzie nasza nowa kolumna.

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

Dwie opcje dla ciebie.

Zakładając, że dane są ładowane:

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) 

Wariant 1: Sortowanie

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 

Opcja 2: Oneliner

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

myślałem będąc nowy użytkownik, który opcja 1 może być łatwiejszym krok po kroku, chociaż rep(table(), table()) może początkowo nie być intuicyjny.

Powiązane problemy