boshek boshek - 4 years ago 123
R Question

First index of longest ordered portion of a vector

I am looking to extract the longest ordered portion of a vector. So for example with this vector:

x <- c(1,2,1,0.5,1,4,2,1:10)
x
[1] 1.0 2.0 1.0 0.5 1.0 4.0 2.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0


I'd apply some function, get the following returned:

x_ord <- some_func(x)
x_ord
[1] 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 10.0


I've been trying to leverage
is.unsorted()
to determine at what point the vector is no longer sorted. Here is my messy attempt and what I have so far:

for(i in 1:length(x)){
if( is.unsorted(x[i:length(x)])==TRUE ){
cat(i,"\n")}
else{x_ord=print(x[i])}
}


However, this clearly isn't right as
x_ord
is producing a
10
. I am also hoping to make this more general and cover non increasing numbers after the ordered sequence as well with a vector something like this:

x2 <- c(1,2,1,0.5,1,4,2,1:10,2,3)


Right now though I am stuck on identifying the increasing sequence in the first vector mentioned.

Any ideas?

Answer Source

This seems to work:

s = 1L + c(0L, which( x[-1L] < x[-length(x)] ), length(x))
w = which.max(diff(s))

x[s[w]:(s[w+1]-1L)]
# 1  2  3  4  5  6  7  8  9 10

s are where the runs start, plus length(x)+1, for convenience.

diff(s) are the lengths of the runs and which.max takes the first maximizer, to break ties.


Alternately, split and then select the desired subvector:

sp = split(x, cumsum(x < c(-Inf, x[-length(x)])))
sp[[which.max(lengths(sp))]]
# 1  2  3  4  5  6  7  8  9 10
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download