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. #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) [[alternative HTML version deleted]]
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 %~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%
On Wed, Jul 27, 2011 at 4:06 AM, steven mosher <moshersteven at gmail.com> 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. > > > #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 the first one: matrix(c(t(A)) - c(t(S)), nrow(A), byrow = TRUE) or this version which may seem a bit more complex but has the advantage that it shows the general form of which both your questions are special cases: ix <- 2:1 aperm(array(c(aperm(A, ix)) - c(t(S)), dim(A)[ix]), ix) Now, as mentioned, the answer to second question is the same except for ix: ix <- c(2, 1, 3) aperm(array(c(aperm(Z, ix)) - c(t(Q)), dim(Z)[ix]), ix) -- Statistics & Software Consulting GKX Group, GKX Associates Inc. tel: 1-877-GKX-GROUP email: ggrothendieck at gmail.com