3

I have two vector of same length:

a = c(723, 680, 2392, 2063, 721, 746, 2053, 2129)
b = c(1, 2, 3, 4, 5, 6, 7, 8)

Now I want to merge them but with a step of 4 element, to be more precise I want as output:

723 680 2392 2063 1 2 3 4 721 746 2053 2129 5 6 7 8
Will
  • 1,619
  • 5
  • 23

2 Answers2

4

We can do this by splitting. Create a function to create a grouping variable with gl that increments at blocks of 'n' (here n is 4), then split both the vectors into a list, use Map to concatenate the corresponding list elements and unlist the list to create a vector

f1 <- function(x, n) split(x, as.integer(gl(length(x), n, length(x))))
unlist( Map(c, f1(a, 4), f1(b, 4)), use.names = FALSE)
#[1]  723  680 2392 2063    1    2    3    4
#[9]  721  746 2053 2129    5    6    7    8

Or if the lengths are the same, then we can rbind and concatenate after creating a matrix

c(rbind(matrix(a, nrow =4), matrix(b, nrow = 4)))
#[1]  723  680 2392 2063    1    2    3    4  721  746 2053 2129    5    6    7    8
akrun
  • 874,273
  • 37
  • 540
  • 662
  • 1
    Thanks it works. I used the second one since I have 2 vectors of the same length. I thought that we should use rbind with c; it's a little tricky with n=4. – Will Aug 08 '20 at 17:42
  • 1
    @Will the `rbind` with `c` should have worked if we didn't have to split up at each 'n' which the `matrix` call will do with dim attribute – akrun Aug 08 '20 at 17:44
2

Here are some other base R options

  • Using order
c(a,b)[order(c(2 * ceiling(seq_along(a) / 4) - 1, 2 * ceiling(seq_along(b) / 4)))]
  • Using split + unlist
unlist(
  split(
    c(a, b),
    c(2 * ceiling(seq_along(a) / 4) - 1, 2 * ceiling(seq_along(b) / 4))
  ),
  use.names = FALSE
)
ThomasIsCoding
  • 96,636
  • 9
  • 24
  • 81