1

I have two matrices: x

A B C
2 3 4
3 4 5

and y

D E
1 2
3 2

How can I subtract the combination of elements within columns? Giving me the following result:

AD AE BD BE CD CE
1  0  2  1  3  2
0  1  1  2  2  3

I have tried applying outer, but can't make it work with matrices. Would vectorizing a function be a solution? I have tried the code below, but it doesn't seem to work.

vecfun= Vectorize(fun)
fun=function(a,b)(a-b)
outer(x,y, vecfun)

Thanks in advance for any advice.

Karl
  • 67
  • 4
  • possible duplicate of [Subtract every column from each other column in a R data.table](http://stackoverflow.com/questions/16919998/subtract-every-column-from-each-other-column-in-a-r-data-table) – Metrics Aug 17 '13 at 17:38
  • 1
    @Karl, Thomas' solution is both faster and memory efficient. I think you should accept that as the answer. – Arun Aug 18 '13 at 09:11
  • 1
    I agree that this might be a duplicate of the same process, however, this post has a much less convoluted question which allows a straightforward explanation, especially easier for beginners. Something I strongly recommend to people posting questions on StackOverflow: Simplify your questions and use small example matrices, so people with similar questions can quickly make sense of it. – Karl Aug 18 '13 at 19:56

2 Answers2

3

This doesn't use outer, but gets your intended result:

> do.call(cbind,lapply(1:ncol(x),function(i) x[,i]-y))
     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    0    2    1    3    2
[2,]    0    1    1    2    2    3
Thomas
  • 43,637
  • 12
  • 109
  • 140
3

Here's another way without loops/*apply family (assuming your matrices are x and y):

x[ , rep(seq_len(ncol(x)), each=ncol(y))] - y[, rep(seq_len(ncol(y)), ncol(x))]

     [,1] [,2] [,3] [,4] [,5] [,6]
[1,]    1    0    2    1    3    2
[2,]    0    1    1    2    2    3

I'm not sure if it'll be faster, yet. But I thought it is an interesting approach. Also this would take twice the memory of your resulting matrix during computation.

Arun
  • 116,683
  • 26
  • 284
  • 387