Ich nehme an, dass der Vektor wie im Beispiel sortiert ist. Wenn nicht vorher vec <- sort(vec)
verwenden.
Hinweis: @DavidArenburg entdeckte einen Fehler in meiner ursprünglichen Antwort, wo c(min(x), x)
eigentlich c(0, x)
sein sollte. Da wir jetzt wissen, dass wir immer zuerst eine 0
hinzufügen müssen, können wir den ersten Schritt der Erstellung x
überspringen und es "on the fly" tun. Die ursprüngliche Antwort und zusätzliche Optionen werden jetzt bearbeitet, um dies zu berücksichtigen (Sie können den Bearbeitungsverlauf für den ursprünglichen Post überprüfen). Danke David!
Ein Hinweis auf Anrufe unname
: Ich unname(sapply(...))
verwendet, um sicherzustellen, dass der resultierende Vektor nicht genannt wird, sonst wäre es 0 genannt werden: (n-1), wobei n die Länge des new_vec
entspricht. Wie @Tensibai in den Kommentaren korrekt notiert, spielt es keine Rolle, ob das Endziel darin besteht, einen Vektor mit Länge 1 Zeichen zu erzeugen, wie er durch Ausführen von toString(new_vec)
erzeugt wird, da Vektornamen sowieso von toString
weggelassen werden.
Eine Option (möglicherweise nicht die kürzeste) wäre:
new_vec <- unname(sapply(split(vec, c(0, cumsum(diff(vec) > 1))), function(y) {
if(length(y) == 1) y else paste0(head(y, 1), "-", tail(y, 1))
}))
Ergebnis:
new_vec
#[1] "1-3" "5" "7-12"
toString(new_vec)
#[1] "1-3, 5, 7-12"
Dank @ Zelazny7 es unter Verwendung der range
Funktion verkürzt werden kann :
new_vec <- unname(sapply(split(vec, c(0, cumsum(diff(vec) > 1))), function(y) {
paste(unique(range(y)), collapse='-')
}))
Dank @DavidArenburg es mithilfe tapply
statt sapply
+ split
weiter verkürzt werden kann:
new_vec <- unname(tapply(vec, c(0, cumsum(diff(vec) > 1)), function(y) {
paste(unique(range(y)), collapse = "-")
}))
Welche Zauberei ist das? –
FWIW: Der Aufruf von 'as.character' ist überflüssig, da' gsub' durch Aufruf aufgerufen wird, wenn die Eingabe nicht vom Typ "character" ist. – Tensibai
Die Verwendung von 'fixed = TRUE' würde das definitiv beschleunigen –