Search code examples
rarraystranspose

How can I transpose every nth (9th) column to a new row in R?


I found some similar questions but not based on R programming or not based on transposition based on the number of columns. That is why I am writing a new question.

So, I have my data as an array like in this reproducible example:

array <- structure(c(78, 101, 22, 22, 34, 64, 
                     68, 817, 44, 48, 42, 42, 44, 44, 
                     69, 78, 49, 62, 76, 92, 24, 24, 27, 36, 
                     61, 64, 44, 48, 43, 44, 42, 42, 66, 82, 
                     43, 56), .Dim = c(2L, 9L, 2L), .Dimnames = list(c("x", 
                                                                           "y"), NULL, NULL))

With that, I have an array like this:

, , 1

  [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
x   78   22   34   68   44   42   44   69   49
y  101   22   64  817   48   42   44   78   62

, , 2

  [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
x   76   24   27   61   44   43   42   66   43
y   92   24   36   64   48   44   42   82   56

Every column represents a different sample (9 samples). Those were repeated 100 times, here I am representing just 2 replicates. Besides, I have more rows than that (x,y,z,w...).

I wanted to transpose every 9th column to a new row, so at the end I will have 9 columns with 100 rows for x followed by 100 rows for y, 100 rows for z etc. Something like this:

  [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
x   78   22   34   68   44   42   44   69   49
x   76   24   27   61   44   43   42   66   43
y  101   22   64  817   48   42   44   78   62
y   92   24   36   64   48   44   42   82   56

It can be a data.frame, matrix etc. It doesn't really matter, I just plan to export to csv format after.


Solution

  • You can split the array by row, bind by column, and transpose:

    t(do.call(cbind, asplit(my_array, 1)))
    
         [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9]
    [1,]   78   22   34   68   44   42   44   69   49
    [2,]   76   24   27   61   44   43   42   66   43
    [3,]  101   22   64  817   48   42   44   78   62
    [4,]   92   24   36   64   48   44   42   82   56
    

    To re-assign the row names, use:

    `row.names<-`(t(do.call(cbind, asplit(my_array, 1))), rep(row.names(my_array), each = nrow(my_array)))
    

    Or alternatively:

    apply(asplit(my_array, 1:2), 2, unlist)