Suppongo che il vettore sia ordinato come nell'esempio. In caso contrario, utilizzare vec <- sort(vec)
in anticipo.
Modifica nota: @DavidArenburg ha individuato un errore nella mia risposta originale dove c(min(x), x)
in realtà dovrebbe essere c(0, x)
. Dato che ora sappiamo che abbiamo sempre bisogno di aggiungere uno 0
, possiamo omettere il primo passaggio della creazione di x
e farlo "al volo". La risposta originale e le opzioni aggiuntive ora vengono modificate per rispecchiare tale aspetto (puoi controllare la cronologia delle modifiche per il post originale). Grazie David!
Una nota sulle chiamate verso unname
: ho usato unname(sapply(...))
per assicurare che il vettore risultante non ha un nome, altrimenti sarebbe chiamato 0: (n-1), dove n è uguale alla lunghezza del new_vec
. Come @Tensibai ha annotato correttamente nei commenti, non importa se l'obiettivo finale è generare un vettore di lunghezza 1 come prodotto eseguendo toString(new_vec)
poiché i nomi vettoriali verranno omessi dallo toString
.
Una possibilità (forse non più breve) sarebbe:
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))
}))
risultati:
new_vec
#[1] "1-3" "5" "7-12"
toString(new_vec)
#[1] "1-3, 5, 7-12"
Grazie a @ Zelazny7 può essere accorciato utilizzando la funzione range
:
new_vec <- unname(sapply(split(vec, c(0, cumsum(diff(vec) > 1))), function(y) {
paste(unique(range(y)), collapse='-')
}))
Grazie a @DavidArenburg può essere ulteriormente ridotto utilizzando tapply
anziché sapply
+ split
:
new_vec <- unname(tapply(vec, c(0, cumsum(diff(vec) > 1)), function(y) {
paste(unique(range(y)), collapse = "-")
}))
Che stregoneria è questa? –
FWIW: la chiamata a 'as.character' è superflua quando' gsub' inizia a chiamarlo se l'input non è di tipo "character". – Tensibai
L'uso di 'fixed = TRUE' lo renderebbe sicuramente più veloce –