14

Is there a way to combine three arrays in R so that the first row of the first array is followed by the first row of the second array and that is followed by the third row of the third array? So, if I ran the following code:

> number1<-rbind(rep("A",3), rep("B",3), rep("C",3))
> number1
     [,1] [,2] [,3]
[1,] "A"  "A"  "A" 
[2,] "B"  "B"  "B" 
[3,] "C"  "C"  "C" 
> number2<-rbind(rep(1,3), rep(2,3), rep(3,3))
> number2
     [,1] [,2] [,3]
[1,]    1    1    1
[2,]    2    2    2
[3,]    3    3    3
> number3<-rbind(rep("X",3), rep("Y",3), rep("Z",3))
> number3
     [,1] [,2] [,3]
[1,] "X"  "X"  "X" 
[2,] "Y"  "Y"  "Y" 
[3,] "Z"  "Z"  "Z"

The result would look like this:

      [,1] [,2] [,3]
 [1,] "A"  "A"  "A" 
 [2,] "1"  "1"  "1" 
 [3,] "X"  "X"  "X" 
 [4,] "B"  "B"  "B" 
 [5,] "2"  "2"  "2" 
 [6,] "Y"  "Y"  "Y" 
 [7,] "C"  "C"  "C" 
 [8,] "3"  "3"  "3" 
 [9,] "Z"  "Z"  "Z"

I have tried melt but I can't get it to work.

Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455
user3390169
  • 1,015
  • 1
  • 11
  • 34

3 Answers3

18

You could try this:

> matrix(t(cbind(number1,number2,number3)),ncol=3, byrow=T)
#      [,1] [,2] [,3]
# [1,] "A"  "A"  "A" 
# [2,] "1"  "1"  "1" 
# [3,] "X"  "X"  "X" 
# [4,] "B"  "B"  "B" 
# [5,] "2"  "2"  "2" 
# [6,] "Y"  "Y"  "Y" 
# [7,] "C"  "C"  "C" 
# [8,] "3"  "3"  "3" 
# [9,] "Z"  "Z"  "Z" 
RHertel
  • 23,412
  • 5
  • 38
  • 64
  • 2
    Now, this is just some impressive deep understanding of `matrix` – Vlo Aug 26 '15 at 18:16
  • wow, I never would have guessed that. working from the inside out, I understand how it works until you get to the most outer function. How did you know it would do that? – user3390169 Aug 26 '15 at 18:26
  • I don't know how I came up with that. Probably just experience and some intuition. – RHertel Aug 26 '15 at 18:30
4

Copying Arun's approach to interleaving two lists...

intermat <- function(...) 
  do.call(rbind,list(...))[ 
    order(sapply(list(...),function(x) 1:nrow(x))), ]

intermat(number1,number2,number3)

      [,1] [,2] [,3]
 [1,] "A"  "A"  "A" 
 [2,] "1"  "1"  "1" 
 [3,] "X"  "X"  "X" 
 [4,] "B"  "B"  "B" 
 [5,] "2"  "2"  "2" 
 [6,] "Y"  "Y"  "Y" 
 [7,] "C"  "C"  "C" 
 [8,] "3"  "3"  "3" 
 [9,] "Z"  "Z"  "Z" 

This also "works" (i.e., does something sensible) for matrices with different numbers of rows.

Community
  • 1
  • 1
Frank
  • 66,179
  • 8
  • 96
  • 180
0

Kind of hacky, but since I'd typed it out before @RHertel posted a superior solution:

wrong_order <- rbind (number1, number2, number3)
row_n <- nrow (wrong_order)

right_order <- wrong_order[ 
  c(seq (1, row_n, by=3),
    seq (2, row_n, by=3),
    seq (3, row_n, by=3)
    ),
  ]
janattack
  • 410
  • 3
  • 11