Search code examples
rmatrixcbind

Combine rows of same size by cbind in R


I would like to rearrange the matrix b in the following way:

> b <- matrix(1:24, 6, 4)
> b
      [,1] [,2] [,3] [,4]
[1,]    1    7   13   19
[2,]    2    8   14   20
[3,]    3    9   15   21
[4,]    4   10   16   22
[5,]    5   11   17   23
[6,]    6   12   18   24

> cbind(b[1:2, ], b[3:4, ], b[5:6, ])
     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
[1,]    1    7   13   19    3    9   15   21    5    11    17    23
[2,]    2    8   14   20    4   10   16   22    6    12    18    24

The number of rows (2 here) is always going to be the same but the matrix b is going to be very large, on the dimension of about 1M x 100. Is there some fast way I can do this without a for loop? Thanks.


Solution

  • First, split b into chunks of two rows using lapply and then cbind the subgroups together using do.call.

    do.call(cbind, lapply(seq(1, NROW(b), 2), function(i) b[i:(i+1),]))
    #     [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10] [,11] [,12]
    #[1,]    1    7   13   19    3    9   15   21    5    11    17    23
    #[2,]    2    8   14   20    4   10   16   22    6    12    18    24
    

    Another way is to separate elements of odd and even rows into two vectors and rbind them

    rbind(do.call(c, data.frame(t(b[(1:NROW(b) %% 2) == 1,]))),
          do.call(c, data.frame(t(b[(1:NROW(b) %% 2) == 0,]))))
    #     X11 X12 X13 X14 X21 X22 X23 X24 X31 X32 X33 X34
    #[1,]   1   7  13  19   3   9  15  21   5  11  17  23
    #[2,]   2   8  14  20   4  10  16  22   6  12  18  24
    

    Yet another way which is, for the most part, similar to the second approach

    do.call(rbind, lapply(split(data.frame(b), 1:2), function(x) do.call(c, data.frame(t(x)))))
    #  X11 X12 X13 X14 X31 X32 X33 X34 X51 X52 X53 X54
    #1   1   7  13  19   3   9  15  21   5  11  17  23
    #2   2   8  14  20   4  10  16  22   6  12  18  24