1

I would like to know how to turn a 3d array into a matrix, by e.g. summing, averaging, or taking the maximum or minimum over the 3rd dimension.

This sounds like something that would have already been asked, I did look around quite a bit but couldn't find exactly this.

A MWE would be:

> a3 <- array(c(1:9, 1:9), c(3,3,2))
> a3
, , 1

     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

, , 2

     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
Community
  • 1
  • 1
Bastiaan Quast
  • 2,802
  • 1
  • 24
  • 50

2 Answers2

4

You can use rowSums for this (or rowMeans for the average), setting the appropriate dims

# sum
rowSums(a3, dims = 2)
#      [,1] [,2] [,3]
# [1,]    2    8   14
# [2,]    4   10   16
# [3,]    6   12   18

# average
rowMeans(a3, dims = 2)
#      [,1] [,2] [,3]
# [1,]    1    4    7
# [2,]    2    5    8
# [3,]    3    6    9
user20650
  • 24,654
  • 5
  • 56
  • 91
  • Thanks a lot, these are very handy, I take it from the name of the argument that this can even be applied to e.g. dimensions 3 & 4 of an array? – Bastiaan Quast Oct 20 '16 at 12:56
  • 1
    @bquast ; yes that's right (try `ar = array(1:16, dim = c(2,2,2,2)) ; apply(ar, 1:3, sum) ; rowSums(ar, dims = 3)`). It is also faster, especially if you are having to repeat a computation many times, but the `MARGIN` argument of your `apply` solution is more versatile and I find it easier to remember – user20650 Oct 20 '16 at 15:13
2

The simplest way appears to be using apply().

> apply(a3, 1:2, sum)
     [,1] [,2] [,3]
[1,]    2    8   14
[2,]    4   10   16
[3,]    6   12   18

Where 1:2 are passed to the MARGIN argument and represent the dimensions of the input object (X) to be preserved.

Note that this also applies to higher dimensional arrays.

For mean() this would of course be:

> apply(a3, 1:2, mean)
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9

and similarly you can use min(), max(), etc.

Bastiaan Quast
  • 2,802
  • 1
  • 24
  • 50