[R] Elegant way to subtract matrix from array
Erich Neuwirth
erich.neuwirth at univie.ac.at
Wed Jul 27 12:47:53 CEST 2011
A-kronecker(rep(1,10),S)
kronecker(m1,m2) creates a "tiled" matrix
each element of m1 in replaced by m2 multiplied with the element of m1
m1 = (1 2)
(3 4)
m2 = (11 12)
(13 14)
kronecker(m1,m2) therefore is
1 * (11 12) 2 * (11 12)
(13 14) (13 14)
3 * (11 12) 3 * (11 12)
(13 14) (13 14)
11 13 22 26
12 14 24 28
33 39 44 52
36 42 48 56
If m1 has 1 everywhere, the tiles are all identical.
On 7/27/2011 11:31 AM, steven mosher wrote:
> Cool,
>
> I looked at sweep but didnt consider it as I thought it was restricted to
> certain functions.
> So thanks for that solution.
>
> yes the data is very large and the future work will increase 10 fold,
>
> as for the matrix one I'm not too keen on replicating the smaller matrix,
> I've had one guy using the package who has hit the memory limits.. I have
> one more thing to try
>
> Thanks!
>
> Steve
>
> On Wed, Jul 27, 2011 at 1:42 AM, Gavin Simpson <gavin.simpson at ucl.ac.uk>wrote:
>
>> On Wed, 2011-07-27 at 01:06 -0700, steven mosher wrote:
>>> there are really two related problems here
>>>
>>> I have a 2D matrix
>>>
>>>
>>> A <- matrix(1:100,nrow=20,ncol =5)
>>>
>>>
>>> S <- matrix(1:10,nrow=2,ncol =5)
>>>
>>>
>>> #I want to subtract S from A. so that S would be subtracted from the
>>> first 2 rows of
>>>
>>> #A, then the next two rows and so on.
>>
>> For this one, I have used the following trick to replication a matrix
>>
>> do.call(rbind, rep(list(mat), N)
>>
>> where we convert the matrix, `mat`, to a list and repeat that list `N`
>> times, and arrange for the resulting list to be rbind-ed. For your
>> example matrices, the following does what you want:
>>
>> A - do.call(rbind, rep(list(S), nrow(A)/nrow(S)))
>>
>> Whether this is useful will depend on the dimension of A and S - from
>> your posts on R-Bloggers, I can well imagine you are dealing with large
>> matrices.
>>
>>> #I have a the same problem with a 3D array
>>>
>>> # where I want to subtract Q for every layer (1-10) in Z
>>>
>>> # I thought I solved this one with array(mapply("-",Z,Q),dim=dim(Z))
>>>
>>> # but got the wrong answers
>>>
>>>
>>> Z <- array(1:100,dim=c(2,5,10))
>>>
>>> Q <- matrix(1:10,nrow=2,ncol =5)
>>
>> For this one, consider the often overlooked function `sweep()`:
>>
>> sweep(Z, c(1,2), Q, "-")
>>
>> does what you wanted. c(1,2) is the `MARGIN` argument over the
>> dimensions that Q will be swept from.
>>
>> HTH
>>
>> G
>>
>> --
>> %~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%
>> Dr. Gavin Simpson [t] +44 (0)20 7679 0522
>> ECRC, UCL Geography, [f] +44 (0)20 7679 0565
>> Pearson Building, [e] gavin.simpsonATNOSPAMucl.ac.uk
>> Gower Street, London [w] http://www.ucl.ac.uk/~ucfagls/
>> UK. WC1E 6BT. [w] http://www.freshwaters.org.uk
>> %~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%
>>
>>
>
> [[alternative HTML version deleted]]
>
> ______________________________________________
> R-help at r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide http://www.R-project.org/posting-guide.html
> and provide commented, minimal, self-contained, reproducible code.
>
More information about the R-help
mailing list