So, if the input is a vector such as
v <- (1, 2, 3, 7, 2, 8, 9)
The output would be
(3, 2, 1, 7, 2, 9, 8)
I have tried using nested for and if loops with the condition as an is.sorted
function, but have not had any success.
R – Reverse a Vector To reverse a vector in R programming, call rev() function and pass given vector as argument to it. rev() function returns returns a new vector with the contents of given vector in reversed order. The rev() function returns a vector.
In order to reverse a list without using the built-in reverse() function, we use the Slicing Operator. The slicing operator is another method used for reversing the data elements.
Convert the given number (say n) to a string (say str) using the to_string(n) function. Then reversing str using the inbuilt reverse function. Printing str, which now holds n in reversed form.
With the sample data
x <- c(1, 2, 3, 7, 2, 8, 9)
You can partition into "sequential groups" with
grp <- cumsum(!c(TRUE, diff(x)==1))
grp
# [1] 0 0 0 1 2 3 3
Basically we look at the diff from the previous element and track changes anytime that value isn't equal to 1.
You can use this group information to re-order those values with ave
(this does a within-group transformation).
revsort<-function(...) sort(...,decreasing=TRUE)
ave(x, grp, FUN=revsort)
# [1] 3 2 1 7 2 9 8
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]])))
#[1] 3 2 1 7 2 9 8
The idea is to first cut the vector based on the positions of consecutive numbers. We then traverse these cuts 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))
# [1] TRUE
all(f_MrFlick(vec2)==f_989(vec2))
# [1] TRUE
length(vec1)
# [1] 7
microbenchmark(f_MrFlick(vec1), f_989(vec1))
# Unit: microseconds
# expr min lq mean median uq max neval
# f_MrFlick(vec1) 287.006 297.0585 305.6340 302.833 312.6695 479.912 100
# f_989(vec1) 113.348 119.7645 124.7901 121.903 127.0360 268.186 100
# --------------------------------------------------------------------------
length(vec2)
# [1] 1542
microbenchmark(f_MrFlick(vec2), f_989(vec2))
# Unit: microseconds
# expr min lq mean median uq max neval
# f_MrFlick(vec2) 1532.553 1565.2745 1725.7540 1627.937 1698.084 3914.149 100
# f_989(vec2) 426.874 454.6765 546.9115 466.439 489.322 2634.383 100
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With