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

有帮助吗?

解决方案

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

其他提示

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
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top