2013-08-10 4 views
18

У меня есть матрица в R, которая должна быть симметричной, однако из-за точности машины матрица никогда не симметрична (значения отличаются примерно на 10^-16). Так как я знаю, что матрица симметрична я делал это до сих пор, чтобы обойти эту проблему:Создание симметричной матрицы в R

s.diag = diag(s) 
s[lower.tri(s,diag=T)] = 0 
s = s + t(s) + diag(s.diag,S) 

Есть ли лучшая команда одна строка для этого?

ответ

9

Это обходное решение действительно необходимо, если значения только сильно отличаются друг от друга?

Кто-то указал, что мой предыдущий ответ был неправильным. Мне нравятся некоторые из тех, что лучше, но так как я не могу удалить этот (принят пользователем, который оставил), вот еще одно решение, используя micEcon пакет:

symMatrix(s[upper.tri(s, TRUE)], nrow=nrow(s), byrow=TRUE) 
+0

Это не работает. '> s = матрица (c (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16), nrow = 4) > s [строка (s)> col (s)] <- s [строка (ы) s [, 1] [, 2] [, 3] [, 4] [1,] 1 5 9 13 [2,] 5 6 10 14 [3,] 9 13 11 15 [4,] 10 14 15 16 ' –

5
s<-matrix(1:25,5) 
pmean <- function(x,y) (x+y)/2 
s[] <- pmean(s, matrix(s, nrow(s), byrow=TRUE)) 
s 
#------- 
    [,1] [,2] [,3] [,4] [,5] 
[1,] 1 4 7 10 13 
[2,] 4 7 10 13 16 
[3,] 7 10 13 16 19 
[4,] 10 13 16 19 22 
[5,] 13 16 19 22 25 
+1

или просто' s <- 0.5 * (s + t (s)) '. Мне нравится ваш подход лучше, так как принятие среднего означает, что каждая треугольная сторона одинаково правильна (или ошибочна). В то время как другие решения произвольно выбирают один. – flodel

10

Вы можете заставить матрица симметричной с использованием forceSymmetric функции в Matrix пакета в R:

library(Matrix) 
x<-Matrix(rnorm(9), 3) 
> x 
3 x 3 Matrix of class "dgeMatrix" 
      [,1]  [,2]  [,3] 
[1,] -1.3484514 -0.4460452 -0.2828216 
[2,] 0.7076883 -1.0411563 0.4324291 
[3,] -0.4108909 -0.3292247 -0.3076071 

A <- forceSymmetric(x) 
> A 
3 x 3 Matrix of class "dsyMatrix" 
      [,1]  [,2]  [,3] 
[1,] -1.3484514 -0.4460452 -0.2828216 
[2,] -0.4460452 -1.0411563 0.4324291 
[3,] -0.2828216 0.4324291 -0.3076071 
39
s<-matrix(1:25,5) 
s[lower.tri(s)] = t(s)[lower.tri(s)] 
+0

очень хорошо! Это также будет работать, когда матрица не содержит цифр, а символов. рассмотрим что-то вроде s <-matrix (ПИСЬМА [1:25], 5) –