We could also do:
x <- c(0, which(diff(vec) != 1), length(vec)) unlist(sapply(seq(length(x) - 1), function(i) rev(vec[(x[i]+1):x[i+1]])))
The idea is to first cut a vector based on the positions of consecutive numbers. Then we cross these sections and apply rev .
Data
vec <- c(1, 2, 3, 7, 2, 8, 9)
Benchmarking
library(microbenchmark) vec1 <- c(1, 2, 3, 7, 2, 8, 9) vec2 <- c(1:1000, sample.int(100, 10), 5:500, sample.int(100, 10), 100:125) f_MrFlick <- function(x){ revsort<-function(...) sort(...,decreasing=TRUE) grp <- cumsum(!c(TRUE, diff(x)==1)) ave(x, grp, FUN=revsort) } f_989 <- function(vec){ x <- c(0, which(diff(vec) != 1), length(vec)) unlist(sapply(seq(length(x) - 1), function(i) rev(vec[(x[i]+1):x[i+1]]))) } all(f_MrFlick(vec1)==f_989(vec1))
source share