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 reverse 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 vectors, loop through the vector, order the absolute 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