I have a list of
-0.5, -0.6, 0.7, 1, 1.5, 3, -5
and I would like to sort it as
3, -5, 1.5, -0.6, 1, -0.5, 0.7
In other words, I would like to sparate the list into positive and negative lists, then sort them from largest to smallest, but alternating.
How can I do this?
How about
pos <- sort(x[x>0], decreasing = T)
neg <- sort(x[x<0], decreasing = T)
c(rbind(pos,neg))[1:length(x)]
#[1] 3.0 -0.5 1.5 -0.6 1.0 -5.0 0.7
Data
x <- c(-0.5, -0.6, 0.7, 1, 1.5, 3, -5)
Use rbind()
to create an alternate indices vector.
ind <- seq_along(x)
sort(x, decreasing = T)[rbind(ind, rev(ind))][ind]
# [1] 3.0 -5.0 1.5 -0.6 1.0 -0.5 0.7
The above method should be memory consuming because it will create a twice longer vector. To conquer it, you can set a midpoint as the end index. In this case, it will be ceiling(7 / 2) = 4
.
n <- length(x)
ind <- 1:ceiling(n / 2) # [1] 1 2 3 4
sort(x, decreasing = T)[rbind(ind, (n:1)[ind])][1:n]
# [1] 3.0 -5.0 1.5 -0.6 1.0 -0.5 0.7
We can split
the list based on sign
and sort
them. We then create a new list by taking alternating elements from positive and negative lists making sure to rev
erse the positive part of the list.
new_list <- sapply(split(x, sign(x)), sort)
c(rbind(rev(new_list[['1']]), new_list[['-1']]))[1:length(x)]
#[1] 3.0 -5.0 1.5 -0.6 1.0 -0.5 0.7
data
x <- c(-0.5, -.6, 0.7, 1, 1.5, 3, -5 )
One option is to split
the vector
by the sign
of the vector
into a list
of vector
s, loop through the vector
, order
the abs
olute value of the elements in decreasing
order, get the lengths
of the list
elements same with padding NA
at the end, rbind
them together as a matrix
, convert it to vector
with c
and remove the NA
elements with na.omit
lst1 <- sapply(split(v1, sign(v1)), function(x)
x[order(abs(x), decreasing = TRUE)])[2:1]
c(na.omit(c(do.call(rbind, lapply(lst1, `length<-`, max(lengths(lst1)))))))
#[1] 3.0 -5.0 1.5 -0.6 1.0 -0.5 0.7
v1 <- c(-0.5, -0.6, 0.7, 1, 1.5, 3, -5)
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