Home > OS >  How can I reshape a matrix in base R without a for loop?
How can I reshape a matrix in base R without a for loop?

Time:04-03

I have some data that has the following dimension [100, 2, 100]. It represents 100 rows of observations, 2 columns of variables, repeated in 100 experiments.

I would like to have the data in a matrix with the dimensions [10000, 2], where I have effectively eliminated the concept of experiments.

Something like .reshape in python.

I found the reshape package. However I wonder if it can be done without it. Is there a more elegant way to do this in base R than a for loop?

CodePudding user response:

Let's start from a smaller example with array m

m <- array(rep(1:100, 5), c(10, 2, 5))

which is a 3-D array

> m
, , 1

      [,1] [,2]
 [1,]    1   11
 [2,]    2   12
 [3,]    3   13
 [4,]    4   14
 [5,]    5   15
 [6,]    6   16
 [7,]    7   17
 [8,]    8   18
 [9,]    9   19
[10,]   10   20

, , 2

      [,1] [,2]
 [1,]   21   31
 [2,]   22   32
 [3,]   23   33
 [4,]   24   34
 [5,]   25   35
 [6,]   26   36
 [7,]   27   37
 [8,]   28   38
 [9,]   29   39
[10,]   30   40

, , 3

      [,1] [,2]
 [1,]   41   51
 [2,]   42   52
 [3,]   43   53
 [4,]   44   54
 [5,]   45   55
 [6,]   46   56
 [7,]   47   57
 [8,]   48   58
 [9,]   49   59
[10,]   50   60

, , 4

      [,1] [,2]
 [1,]   61   71
 [2,]   62   72
 [3,]   63   73
 [4,]   64   74
 [5,]   65   75
 [6,]   66   76
 [7,]   67   77
 [8,]   68   78
 [9,]   69   79
[10,]   70   80

, , 5

      [,1] [,2]
 [1,]   81   91
 [2,]   82   92
 [3,]   83   93
 [4,]   84   94
 [5,]   85   95
 [6,]   86   96
 [7,]   87   97
 [8,]   88   98
 [9,]   89   99
[10,]   90  100

If you want to reshape it into a 50x2 array, we can try

> apply(m, 2, `[`)
      [,1] [,2]
 [1,]    1   11
 [2,]    2   12
 [3,]    3   13
 [4,]    4   14
 [5,]    5   15
 [6,]    6   16
 [7,]    7   17
 [8,]    8   18
 [9,]    9   19
[10,]   10   20
[11,]   21   31
[12,]   22   32
[13,]   23   33
[14,]   24   34
[15,]   25   35
[16,]   26   36
[17,]   27   37
[18,]   28   38
[19,]   29   39
[20,]   30   40
[21,]   41   51
[22,]   42   52
[23,]   43   53
[24,]   44   54
[25,]   45   55
[26,]   46   56
[27,]   47   57
[28,]   48   58
[29,]   49   59
[30,]   50   60
[31,]   61   71
[32,]   62   72
[33,]   63   73
[34,]   64   74
[35,]   65   75
[36,]   66   76
[37,]   67   77
[38,]   68   78
[39,]   69   79
[40,]   70   80
[41,]   81   91
[42,]   82   92
[43,]   83   93
[44,]   84   94
[45,]   85   95
[46,]   86   96
[47,]   87   97
[48,]   88   98
[49,]   89   99
[50,]   90  100

CodePudding user response:

You can simply set the dim attribute.

Let's take an example of a 3 x 2 x 3 array:

example <- array(1:18, c(3, 2, 3))

example
#> , , 1
#> 
#>      [,1] [,2]
#> [1,]    1    4
#> [2,]    2    5
#> [3,]    3    6
#> 
#> , , 2
#> 
#>      [,1] [,2]
#> [1,]    7   10
#> [2,]    8   11
#> [3,]    9   12
#> 
#> , , 3
#> 
#>      [,1] [,2]
#> [1,]   13   16
#> [2,]   14   17
#> [3,]   15   18

To get in into 2 columns, we can do:

dim(example) <- c(9, 2)

example
#>       [,1] [,2]
#>  [1,]    1   10
#>  [2,]    2   11
#>  [3,]    3   12
#>  [4,]    4   13
#>  [5,]    5   14
#>  [6,]    6   15
#>  [7,]    7   16
#>  [8,]    8   17
#>  [9,]    9   18

Created on 2022-04-02 by the reprex package (v2.0.1)

  • Related