Reputation: 115
Does anyone know how to sort a vector in R by absolute value, so (-2, 3, 1) -> (1, -2, 3)
etc?
If I were doing it in python I'd create a pair of every value and its sign, sort the list of pairs by the absolute value then reapply the sign, but I'm very new to R so have no idea how to do this.
Cheers
Upvotes: 8
Views: 12005
Reputation: 60014
@Arun's method is TRT:
v[order(abs(v))]
where v
is the vector to be sorted.
Notes:
abs(v)
of the same size as v
.
This is not very memory-efficient, but I don't think this can be avoided in R
,
like it is done in, e.g., Lisp: (sort #'< v :key #'abs)
or Python: v.sort(key=abs)
.N
times, not N*log(N)
times, which is especially important when the key is not cheap (unlike abs
or a structure field).abs(v)
is garbage collected very soon, but its allocation (and, especially, garbage collection) are expensive for large vectors and may be actually problematic if the memory is tight.See also:
Upvotes: 11
Reputation: 34907
I found it useful to package this in a function so that I could pass a vector to it, and also so that there was the option of using other options in the order
function like decreasing
. It is essentially based on the existing answer.
sort_abs <- function(x, na.last = TRUE, decreasing = FALSE) {
x[order(abs(x), na.last = na.last, decreasing = decreasing)]
}
For example,
> sort_abs(c(-1,NA,2,-2))
[1] -1 2 -2 NA
> sort_abs(c(-1,NA,2,-2), decreasing = TRUE, na.last = FALSE)
[1] NA 2 -2 -1
Upvotes: 2