2013-08-10 25 views
18

Ho una matrice in R che dovrebbe essere simmetrica, tuttavia, a causa della precisione della macchina, la matrice non è mai simmetrica (i valori differiscono di circa 10^-16). Dal momento che so che la matrice è simmetrica che ho fatto questo finora per aggirare il problema:Creazione di una matrice simmetrica in R

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

Esiste un migliore comando di una riga per questo?

risposta

9

La soluzione è davvero necessaria se i valori differiscono solo di molto?

Qualcuno ha sottolineato che la mia risposta precedente era sbagliata. Mi piacciono alcune delle altre migliori, ma dal momento che non riesco a cancellare questo uno (accettata da un utente che ha lasciato), ecco l'ennesima soluzione che utilizza il pacchetto micEcon:

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

Questo non funziona. '> s = matrice (c (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16), nrow = 4) > s [riga (s)> col (s)] <- s [riga (i) 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

o solo' s <- 0.5 * (s + t (s)) '. Mi piace il tuo approccio migliore dal momento che prendere la media presuppone che ogni lato triangolare sia ugualmente corretto (o sbagliato). Mentre altre soluzioni ne scelgono arbitrariamente una. – flodel

10

è possibile forzare la matrice di essere simmetrica utilizzando forceSymmetric funzione Matrix pacchetto 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

molto buono! Ciò funzionerà anche quando la matrice non contiene numeri, ma simboli. considera qualcosa come s <-matrix (LETTERS [1:25], 5) –

Problemi correlati