Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Margin argument within the apply function in R

This question is more about the MARGIN argument within the apply function than anything. Let's say that I want to multiply the following matrix by the following vector so that I multiply the first matrix element by the first vector element, second by second, and so on. I use the following code:

matrix <- matrix(1:10)
vector <- c(10:19)
t(apply(matrix,2,'*',vector))

which returns a very clean result:

      [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
[1,]   10   22   36   52   70   90  112  136  162   190

but if I change MARGIN = 2, I get this result:

matrix <- matrix(1:10)
vector <- c(10:19)
t(apply(matrix,1,'*',vector))

       [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
 [1,]   10   11   12   13   14   15   16   17   18    19
 [2,]   20   22   24   26   28   30   32   34   36    38
 [3,]   30   33   36   39   42   45   48   51   54    57
 [4,]   40   44   48   52   56   60   64   68   72    76
 [5,]   50   55   60   65   70   75   80   85   90    95
 [6,]   60   66   72   78   84   90   96  102  108   114
 [7,]   70   77   84   91   98  105  112  119  126   133
 [8,]   80   88   96  104  112  120  128  136  144   152
 [9,]   90   99  108  117  126  135  144  153  162   171
[10,]  100  110  120  130  140  150  160  170  180   190

I suppose that if MARGIN = 1, the first matrix row will be multiplied by every vector element, then the second matrix row, etc., while MARGIN = 2 just multiplies the first matrix row by the first vector element?

Could somebody explain to me exactly what the difference is?

like image 502
Adam Avatar asked Nov 01 '22 00:11

Adam


1 Answers

The margins of the apply functions can be explained in dimensions: 1 = rows and 2 = columns.

When you set MARGIN = 1 you are saying to R to multiply each row of your matrix with the vector named vector. Because of vectorization even if you original result is a row of just one element you'll get 10 elements.

The reason of that is, using the words of Norman Matloff in the excellent book "The art of R programming":

When applying an operation to two vectors that requires them to be the same length, R automatically recycles, or repeats, the shorter one, until it is long enough to match the longer one

There was days ago a quite similar discussions about vectorization and the behavior of the == function, you can find it here.

Back to your problem let us consider not the whole apply function but just one iteration of it, say the first element of the matrix multiplied with the vector. We have:

 matrix[1]
[1] 1
 vector
 [1] 10 11 12 13 14 15 16 17 18 19
 matrix[1] * vector
 [1] 10 11 12 13 14 15 16 17 18 19

as stated in the book I have cited, R takes the shorter vector (in this case the matrix[1]) and multiplies with vector but because vector is longer, R takes the shorter and recycles it "n" times as soon the longer one, in this case 10 times.

Of course we were only in one case. apply functions does this step for every row, which are ten. As a result we obtain a matrix of 10 x 10.

like image 56
SabDeM Avatar answered Nov 15 '22 05:11

SabDeM