Search code examples
rmatrixcombinationsapplysymmetric

R get all combinations for columns and perform a function on them returning a Symmetric matrix?


I have a matrix mat that looks like:

      A     B     C     D      E     F
1  0.74  1.19  0.01  1.21  16000  0.02
2  0.76  1.17  0.01  1.21  15500  0.02
3  0.79  1.16  0.01  1.17  15625  0.02
4  0.75  1.17  0.01  1.17  15600  0.02
5  0.80  1.19  0.01  1.19  15225  0.02
6  0.79  1.18  0.01  1.18  15625  0.02

And I want to build a Symmetric matrix from this by applying the function Sum(Col1-Col2). The end result will look something like this:

    A     B     C     D      E     F
A   0
B         0
C               0
D                     0
E                            0
F                                  0

Such that the blank spaces represent the sum of difference. i.e. [1,2] = Sum(A-B).

I have investigated methods such as:

combs<-combn(names(mat),2)
val<-apply(combs,2,function(x) mat[[x[1]]]-mat[[x[2]]])

But it doesn't give me a nice symmetric matrix.

Anyone have any ideas?

Thanks.

EDIT - Thanks to Troy the above works. But how about if I want to compute Sum((Col1-Col2)^2) in that Sum(((A_1,A_2,..,A_n)-(B_1,B_2,..,B_n))^2) (so can't sum A and B initially and then subtract otherwise the answer will be off).


Solution

  • This seems valid, too:

    outer(colSums(mat), colSums(mat), `-`)  #I used Troy's `mat`
    #         A        B        C        D         E        F
    #A     0.00    -2.43     4.57    -2.50 -93570.37     4.51
    #B     2.43     0.00     7.00    -0.07 -93567.94     6.94
    #C    -4.57    -7.00     0.00    -7.07 -93574.94    -0.06
    #D     2.50     0.07     7.07     0.00 -93567.87     7.01
    #E 93570.37 93567.94 93574.94 93567.87      0.00 93574.88
    #F    -4.51    -6.94     0.06    -7.01 -93574.88     0.00
    

    EDIT to match edited question:

    n = seq_len(ncol(mat))
    ff = function(a, b) sum((mat[,a] - mat[,b]) ^ 2)
    outer(n, n, Vectorize(ff))
    #             [,1]         [,2]        [,3]         [,4]       [,5]         [,6]
    #[1,] 0.000000e+00 9.881000e-01 3.48390e+00 1.048400e+00 1459547504 3.393100e+00
    #[2,] 9.881000e-01 0.000000e+00 8.16740e+00 2.100000e-03 1459471669 8.028000e+00
    #[3,] 3.483900e+00 8.167400e+00 0.00000e+00 8.332500e+00 1459690004 6.000000e-04
    #[4,] 1.048400e+00 2.100000e-03 8.33250e+00 0.000000e+00 1459469476 8.191700e+00
    #[5,] 1.459548e+09 1.459472e+09 1.45969e+09 1.459469e+09          0 1.459688e+09
    #[6,] 3.393100e+00 8.028000e+00 6.00000e-04 8.191700e+00 1459688132 0.000000e+00