Use apply on a multi-dimension array

2019-08-04 06:11发布

问题:

A normal matrix would be 2-dimension matrix. But, I can initialise:

a<-array(0,dim=c(2,3,4,5))

Which is a 2*4*5*3 matrix, or array.

Command

apply(a,c(2,3),sum)

will give a 4*5 array, contain the sum over elements in the 1st and 4th dimension.

Why it that? As far as I know, in the apply function, 1 indicates rows, 2 indicates columns, but what does 3 mean here?

We need some abstraction here.

回答1:

The easiest way to understand apply on an array is to try some examples. Here's some data modified from the last example object in the documentation:

> z <- array(1:24, dim = 2:4)
> dim(z)
[1] 2 3 4

> apply(z, 1, function(x) sum(x))
[1] 144 156
> apply(z, 2, function(x) sum(x))
[1]  84 100 116
> apply(z, 3, function(x) sum(x))
[1]  21  57  93 129

What's going on here? Well, we create a three-dimensional array z. If you use apply with MARGIN=1 you get row sums (two values because there are two rows), if you use MARGIN=2 you get column sums (three values because there are three columns), and if you use MARGIN=3 you get sums across the array's third dimension (four values because there are four levels to the third dimension of the array).

If you specify a vector for MARGIN, like c(2,3) you get the sum of the rows for each column and level of the third dimension. Note how in the above examples, the results from apply with MARGIN=1 are the row sums and with MARGIN=2 the column sums, respectively, of the matrix seen in the result below:

> apply(z, c(2,3), function(x) sum(x))
     [,1] [,2] [,3] [,4]
[1,]    3   15   27   39
[2,]    7   19   31   43
[3,]   11   23   35   47

If you specify all of the dimensions as MARGIN=c(1,2,3) you simply get the original three-dimensional object:

> all.equal(z, apply(z, c(1,2,3), function(x) sum(x)))
[1] TRUE

Best way to learn here is just to start playing around with some real matrices. Your example data aren't helpful for looking at sums because all of the array entries are zero.