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
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
Ich zweite @MrFlick Kommentar. Kannst du mehr darüber ausarbeiten, was du meinst, wenn du dafür Blei oder Verzögerung verwendest? – zyurnaidi
danke! Ich war auf der Suche nach RLE !!! – sharp