How can I restore the original order of a vector after sorting and deleting elements?

Viewed 70

I have to delete the highest 30 elements and the lowest 30 elements of a numeric vector. My idea was to sort the vector and then select the elements in between like this:

set.seed(3758)
test.x <- rnorm(1000) 
test.x <- sort(test.x)
test.x <- test.x[- seq(length(test.x), length.out = 30)]
test.x <- test.x[- (1:30)]

My problem is that I have to restore the original order of the vector after that, but obviously it has now 60 elements less than before. So I can't use test.x[ord] with ord being ord <- order(test.x) of the original test.x. Is there a way to do this without changing my strategie, i.e. the sorting and deleting?

2 Answers

The following function removes the first (lo) and the last (hi) elements from a vector. If hi is not passed to the function, it defaults to hi = lo.

trim_vec <- function(x, lo, hi = lo){
  if(lo + hi > length(x)){
    stop("cannot remove more than 'length(x)' elements, 'lo + hi > length(x)'")
  }
  i <- order(x)
  x <- x[i]
  x <- x[-seq.int(to = length(x), length.out = hi)]
  x <- x[-seq.int(to = lo)]
  x <- x[order(i)]
  x[!is.na(x)]
}

set.seed(3758)

(x <- sample(20))
# [1] 18  1 10 19  4 16  6  3  5 13  2  7  9 12 17 14 20 15  8 11
trim_vec(x, 3)
# [1]  4 13  7  9  6  8 16  5 10 12 15 17 11 14

Just remove the elements from the order vector ord and use this for sorting

ord <- order(test.x)[-(1:30)]
ordered.x <-test.x[ord]
sub.orig.x <- ordered.x[order(ord)]

Example

set.seed(3758)
test.x <- sample(10)

ord <- order(test.x)[-(1:2)]
ordered.x <-test.x[ord]
sub.orig.x <- ordered.x[order(ord)]

all.equal(test.x[-(1:2)], sub.orig.x)
# TRUE
Related