使矩阵对称

4

我有一个矩阵,理论上应该是对称的,但在我的数据中可能没有表现出对称性。我想通过使用两个比较单元格中的最大值来强制使其对称。

test_matrix <- matrix(c(0,1,2,1,0,1,1.5,1,0), nrow = 3)
test_matrix
#>     [,1] [,2] [,3]
#>[1,]    0    1  1.5
#>[2,]    1    0  1.0
#>[3,]    2    1  0.0

使用双重循环很容易实现这一点。

for(i in 1:3){
  for(j in 1:3){
    test_matrix[i, j] <- max(test_matrix[i, j], test_matrix[j, i]) 
   }
}
test_matrix
#>      [,1] [,2] [,3]
#> [1,]    0    1    2
#> [2,]    1    0    1
#> [3,]    2    1    0

但是我的矩阵大于$3x3$,而且 R 对循环的问题有很多记录。我也希望让我的代码尽可能清晰。事实上,我考虑过将此放在 code golf 上,但这是一个真正的问题,我认为其他人可能会感兴趣。 我看到过这个以及这个,但我的问题不同之处在于那些操作似乎实际上有一个对称矩阵只需要重新排序,而我有一个需要转换为对称矩阵的矩阵。

1
我之前看过这个问题,但似乎答案通常涉及机器精度或近对称矩阵。在我的情况下,应该相等的单元格可能差别很大。我认为这些答案不适用,尽管问题可能类似。 - gregmacfarlane
我基本上同意,不过如果你往下滚动,会发现BondedDust的好答案与我的相似。我也喜欢它使用pmean()(而不是pmax())的想法,这可能更好,具体取决于您的矩阵不对称的原因。(链接在此,因为早期评论现已被删除。) - Josh O'Brien
1
顺便提一下,“循环问题有充分的文献记录”这个说法:我也听说过一些历史上的原因,但在过去几年中,循环性能和行为方面已经有了相当大的改进。你有最近和可重复的指标吗?(我不是在挑刺,我真的很好奇!) - r2evans
1个回答

9
您可以使用pmax(),它返回一对向量的逐元素最大值。
pmax(test_matrix, t(test_matrix))
#      [,1] [,2] [,3]
# [1,]    0    1    2
# [2,]    1    0    1
# [3,]    2    1    0

这将适用于一对矩阵,因为:

  1. 在R中,矩阵是带有附加属性的向量;
  2. 实现pmax()的代码足够好,能够重新附加其第一个参数的属性到它返回的值上。

我以前从未见过 pmax(),但现在我看到它可以解决我曾经为之苦恼的各种问题。太好了。 - gregmacfarlane
如果矩阵很大(我的意思是真的非常大),这种方法将不会是内存高效的。在这些情况下,我更喜欢原帖作者的解决方案。 - Randy Lai
@gregmacfarlane和JoshOBrien:虽然问题中没有说明,但您可能需要包括一个检查正方形矩阵的步骤;非正方形矩阵仍然可以完成大部分您想要的操作,但不会有任何警告或错误提示。 - r2evans
@RandyLai:也许一个Rcpp解决方案会更好?尽管它的语法糖在内存方面不一定更好(虽然略微好一些),但如果我要处理足够大的矩阵(而我经常这样做),我可能会尝试迭代编译变体。当然,我认为我无法回答“在多大的情况下会成为问题”。 - r2evans
1
@r2evans。这取决于您如何使用RCpp。如果您编写一个等同于pmax(test_matrix, t(test_matrix))RCpp函数,那么根本不会有任何收益。当然,如果您在RCpp中编写一个循环来执行与OP代码相同的任务,它将更好地完成工作。 - Randy Lai

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接