Hier ist eine Funktion, es zu tun. Das ist übrigens ein Problem in der Genetik - Tandem-Repeats zu finden. Here's a link to an algorithm paper das ist eine viel bessere Behandlung als das, aber viel komplizierter zu implementieren.
Die Ausgabe ist ein Vektor von Gruppen, in die x aufgeteilt werden soll.
Zunächst wird eine Hilfsfunktion:
factorise <- function(x) {
x <- length(x)
if(x == 1){return(1)}
todivide <- seq(from = 2, to = x)
out <- todivide[x %% todivide == 0L]
return(out)
}
Nun ist die Hauptfunktion:
findreps <- function(x, counter = NULL){
if(is.null(counter)){
counter <- c()
maxcounter <- 0
} else {
maxcounter <- max(counter)
}
holding <- lapply(1:length(x), function(y){x[1:y]})
factors <- lapply(holding, factorise)
repeats <- sapply(1:length(factors), function(index) {any(sapply(1:length(factors[[index]]), function(zz) {all((rep(holding[[index]][1:(length(holding[[index]])/factors[[index]][zz])], factors[[index]][zz]))==holding[[index]])}))})
holding <- holding[max(which(repeats))][[1]]
if(length(holding) == length(x)){
return(c(counter, rep(maxcounter + 1, length(x))))
} else {
counter <- c(counter, rep(maxcounter + 1, length(holding)))
return(findreps(x[(length(holding) + 1):length(x)], counter))
}
}
Wie es funktioniert: Es ist eine rekursive Funktion, die ausgeführt wird, schneidet die größte Wiederholungen Gruppe off es finden kann aus der Anfang des Vektors, und dann läuft, bis sie alle weg sind.
Zuerst machen wir eine counter
für die endgültige Ausgabe.
Als nächstes teilen wir x
in jede Teilmenge beginnend von 1 in eine Liste, holding
.
Dann finden wir alle Faktoren der Größe einer Gruppe, mit Ausnahme 1.
Dann das Schlimmste ist. Wir nehmen jede Teilmenge der größten Teilmenge und prüfen, ob sie der größten Teilmenge in ihrer Gruppe entspricht, nachdem sie die sinnvolle Anzahl von Malen wiederholt wurde.
findreps(x)
[1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3
[37] 3 3 3 3 3 4 5 6 7 7 7 7 7 7 7 7 7
Wenn Sie nicht-Wiederholungen wollen gruppiert werden, können wir ein wenig dplyr
und tidyr
verwenden:
library(dplyr)
library(tidyr)
z <- data.frame(x = x, y = findreps(x))
z %>% mutate(y = ifelse(duplicated(y) | rev(duplicated(rev(y))), y, NA),
holding = c(0, y[2:n()])) %>%
fill(holding) %>%
mutate(y = ifelse(is.na(y), holding +1, y)) %>%
select(-holding)
Welche gibt:
[1] 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 4 4 4 7 7 7 7 7 7 7 7
[53] 7
Upvoting aber diese Partitionierung Regel nicht sicher ist, wohldefiniert. Kann '1 1 2' ein sich wiederholendes Muster sein oder sind nums innerhalb eines Laufs immer eindeutig? – Frank
Gibt es eine maximale Länge, die ein Muster haben kann? – RHA
@RHA keine maximale Länge –