Creating alternate series in r

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

data

v1 <- c(-0.5, -0.6, 0.7, 1, 1.5, 3, -5)

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

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 )

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

Tags:

Sorting

R