Question

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).

Was it helpful?

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

OTHER TIPS

mat<-as.matrix(read.table(text="A     B     C     D      E     F
0.74  1.19  0.01  1.21  16000  0.02
0.76  1.17  0.01  1.21  15500  0.02
0.79  1.16  0.01  1.17  15625  0.02
0.75  1.17  0.01  1.17  15600  0.02
0.80  1.19  0.01  1.19  15225  0.02
0.79  1.18  0.01  1.18  15625  0.02", header=T))


cross<-expand.grid(apply(mat,2,sum),apply(mat,2,sum))
matrix(cross[,1]-cross[,2],6)

[,1]     [,2]     [,3]     [,4]      [,5]     [,6]
[1,]     0.00    -2.43     4.57    -2.50 -93570.37     4.51
[2,]     2.43     0.00     7.00    -0.07 -93567.94     6.94
[3,]    -4.57    -7.00     0.00    -7.07 -93574.94    -0.06
[4,]     2.50     0.07     7.07     0.00 -93567.87     7.01
[5,] 93570.37 93567.94 93574.94 93567.87      0.00 93574.88
[6,]    -4.51    -6.94     0.06    -7.01 -93574.88     0.00

for second question, how about this?

EDIT - think I put the bracket in the wrong place

apply(mat,2,function(x)colSums((matrix(x,ncol(mat),ncol(mat))-mat)^2))
#             A            B           C            D          E            F
#A 0.000000e+00 9.881000e-01 3.48390e+00 1.048400e+00 1459547504 3.393100e+00
#B 9.881000e-01 0.000000e+00 8.16740e+00 2.100000e-03 1459471669 8.028000e+00
#C 3.483900e+00 8.167400e+00 0.00000e+00 8.332500e+00 1459690004 6.000000e-04
#D 1.048400e+00 2.100000e-03 8.33250e+00 0.000000e+00 1459469476 8.191700e+00
#E 1.459548e+09 1.459472e+09 1.45969e+09 1.459469e+09          0 1.459688e+09
#F 3.393100e+00 8.028000e+00 6.00000e-04 8.191700e+00 1459688132 0.000000e+00
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top