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?

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