2016-05-13 4 views
0

Lasst uns sagen, dass ich alphaPeriodizität von Variablen in einem Array in R

alpha = c(a,a,a,b,c,c,c,a,c,c) 

haben Wie kann ich die Periodizität so feststellen, dass ich ein anderes Array konstruieren beta

beta = c(3,1,3,1,2) 

ohne den Inhalt des alpha mit im Code? Gibt es eine Möglichkeit, Lead oder Lag zu verwenden, um dies zu beantworten?

+4

Suchen Sie Run Length Encoding ('rle')? Ich bin mir nicht sicher, was Sie mit "ohne den Inhalt von Alpha" meinen. Was genau sind Ihre Eingaben und gewünschten Ausgaben? Dies scheint zu tun, was Sie beschreiben: Alpha = c ("a", "a", "a", "b", "c", "c", "c", "a", "c", " c "); rle (alpha) $ lengths – MrFlick

+0

Ich zweite @MrFlick Kommentar. Kannst du mehr darüber ausarbeiten, was du meinst, wenn du dafür Blei oder Verzögerung verwendest? – zyurnaidi

+0

danke! Ich war auf der Suche nach RLE !!! – sharp

Antwort

0

Wenn Sie die Werte in Alpha blind halten möchten, können Sie eine for-Schleife erstellen und Logik verwenden, um einen Zähler zu erstellen, wenn diese Iteration von alpha gleich der letzten ist. Sie müssen ein vergangenes Alpha festlegen, um den aktuellen Wert zu akzeptieren und den nächsten zu vergleichen.

Sobald die beiden Werte nicht übereinstimmen, wird die Zählernummer mit dem Vektor verknüpft, den Sie außerhalb der Schleife erstellt haben, und der Zähler wird auf eins zurückgesetzt.

Es ist einfach genug, dass Sie dies selbst tun sollten, um zu lernen, wie.

Sie können eine Datei in eine Variable einlesen, aber Zahlen nicht manuell eingeben oder sie immer sichtbar machen. Wenn die Daten in irgendeiner Weise 'geschützt' ist ...

1

Hier ist eine Option tabulate und rleid

library(data.table) 
tabulate(rleid(alpha)) 
#[1] 3 1 3 1 2 
1

Just for fun mit, hier ist eine gewundene Lösung:

alpha <- c('a','a','a','b','c','c','c','a','c','c'); 
diff(c(0L,which(c(alpha[-1L]!=alpha[-length(alpha)],T)))); 
## [1] 3 1 3 1 2 

Erklärung


alpha[-1L]!=alpha[-length(alpha)]; 
## [1] FALSE FALSE TRUE TRUE FALSE FALSE TRUE TRUE FALSE 

Berechnen Sie zuerst einen logischen Vektor, der angibt, welche benachbarten Paare von Eingabeelementen Brüche in der Wertgleichheit darstellen und welche nicht. Der Index jedes Elements in dem logischen Vektor entspricht dem Index des ersten Elements des Paars in dem Eingabevektor.


c(alpha[-1L]!=alpha[-length(alpha)],T); 
## [1] FALSE FALSE TRUE TRUE FALSE FALSE TRUE TRUE FALSE TRUE 

Anfügen einen TRUE Wert eine pseudo-Pause am Ende des Vektors zu schaffen. Weitere Informationen finden Sie im nächsten Schritt.


which(c(alpha[-1L]!=alpha[-length(alpha)],T)); 
## [1] 3 4 7 8 10 

Konvertieren der logischen Vektor an einen Indexvektor die Endpunkte der Lauflängen in dem Eingangsvektor darstellt. Nun sollte klar sein, warum wir im vorherigen Schritt TRUE anhängen mussten; der Endpunkt der endgültigen Lauflänge würde ansonsten weggelassen werden.


c(0L,which(c(alpha[-1L]!=alpha[-length(alpha)],T))); 
## [1] 0 3 4 7 8 10 

Prepend eine Null. Dies kann konzeptionell als Umwandlung des Indexvektors in einen "Grenzvektor" betrachtet werden, wobei jedes Element entweder die internen oder externen Grenzen der Lauflängen des Eingangsvektors darstellt. Weitere Informationen finden Sie im nächsten Schritt.


diff(c(0L,which(c(alpha[-1L]!=alpha[-length(alpha)],T)))); 
## [1] 3 1 3 1 2 

die Differenz zwischen aufeinander folgenden Grenzen nehmen. Dies liefert die gewünschten Lauflängen.


Benchmarking

library(data.table); 
library(microbenchmark); 

bgoldst <- function(alpha) diff(c(0L,which(c(alpha[-1L]!=alpha[-length(alpha)],T)))); 
akrun <- function(alpha) tabulate(rleid(alpha)); 
bethany <- function(alpha) { if (length(alpha)==0L) return(integer()); res <- integer(); last <- alpha[1L]; cnt <- 1L; i <- 2L; while (i<=length(alpha)) { if (alpha[i]==last) cnt <- cnt+1L else { res[length(res)+1L] <- cnt; last <- alpha[i]; cnt <- 1L; }; i <- i+1L; }; res[length(res)+1L] <- cnt; res; }; 
flick <- function(alpha) rle(alpha)$lengths; 

alpha <- c('a','a','a','b','c','c','c','a','c','c'); 

expected <- c(3L,1L,3L,1L,2L); 
identical(expected,bgoldst(alpha)); 
## [1] TRUE 
identical(expected,akrun(alpha)); 
## [1] TRUE 
identical(expected,bethany(alpha)); 
## [1] TRUE 
identical(expected,flick(alpha)); 
## [1] TRUE 

microbenchmark(bgoldst(alpha),akrun(alpha),bethany(alpha),flick(alpha)); 
## Unit: microseconds 
##   expr  min  lq  mean median  uq  max neval 
## bgoldst(alpha) 8.553 11.1200 14.85308 12.8300 15.3970 70.136 100 
## akrun(alpha) 129.151 144.9745 163.64182 156.7350 171.4895 313.898 100 
## bethany(alpha) 20.101 23.9500 30.43242 26.5155 37.8475 70.136 100 
## flick(alpha) 20.100 23.9495 30.44956 28.0120 32.2890 62.866 100 

set.seed(1L); N <- 1e5L; alpha <- sample(letters[1:3],N,T); 

expected <- bgoldst(alpha); 
identical(expected,akrun(alpha)); 
## [1] TRUE 
identical(expected,bethany(alpha)); 
## [1] TRUE 
identical(expected,flick(alpha)); 
## [1] TRUE 

microbenchmark(bgoldst(alpha),akrun(alpha),bethany(alpha),flick(alpha),times=10L); 
## Unit: milliseconds 
##   expr   min   lq  mean  median   uq   max neval 
## bgoldst(alpha) 5.497899 6.469098 11.007558 6.521699 7.297460 49.891634 10 
## akrun(alpha) 1.300492 1.370199 1.547461 1.401631 1.464282 2.816091 10 
## bethany(alpha) 2865.335271 2891.594408 2941.352229 2924.165053 2997.881411 3024.234204 10 
## flick(alpha) 8.060392 9.355323 13.646002 10.055176 10.841843 48.312741 10