2015-04-23 9 views
6

Ho un vettore come questo in R:Inserisci numero sopra la diagonale in matrice R

vec1 <- c(14000,12000,8000) 

Sto cercando di creare una matrice in cui 14000 è il mio diagonale principale, 1200 è uno al di sopra della diagonale, 8000 due sopra la diagonale.

ho familiarità con fare questo in Python/NumPy ma non può capirlo in R (o almeno un modo efficace per farlo). Idealmente uscita sarebbe così:

14000 12000 8000 
    0 14000 12000 
    0  0 14000 
+0

(muto) one-liner 't (sapply (1: 3 , funzione (x) c (rep (0, x - 1), la testa (vec1, 4 - x)))) '' – rawr

risposta

6

Prova

m1 <- t(matrix(vec1, nrow=5, ncol=3))[,1:3] 
m1[lower.tri(m1)] <- 0 
m1 
#  [,1] [,2] [,3] 
#[1,] 14000 12000 8000 
#[2,]  0 14000 12000 
#[3,]  0  0 14000 

o utilizzare toeplitz

toeplitz(vec1)*upper.tri(diag(seq_along(vec1)), diag=TRUE) 
#  [,1] [,2] [,3] 
#[1,] 14000 12000 8000 
#[2,]  0 14000 12000 
#[3,]  0  0 14000 

o di una modifica suggerita da @ David Arenburg

m <- toeplitz(vec1) 
m[lower.tri(m)] <- 0 
+0

@DavidArenburg Ho pensato di utilizzare la route 'lower.tri (m)', ma ho optato per una sola riga. – akrun

+0

@DavidArenburg Grazie per i commenti. Ho aggiunto l'opzione suggerita da te .. – akrun

+0

La tua risposta è migliore della mia; scala bene. Mi piace particolarmente 'toeplitz()'. +1 –

1

In questo caso semplice è possibile assegnare le porzioni triangolari diagonali e alte separatamente in questo modo:

m <- matrix(0, nrow=3, ncol=3) 

diag(m) <- 14000 

m[upper.tri(m)] <- c(12000, 8000, 12000) 

Tuttavia, come David Arenburg sottolineato, questo è un più approccio manuale e quindi non scala bene. Per un approccio più automatizzato e scalabile, raccomando la soluzione di akrun utilizzando toeplitz() e lower.tri().

Terrò questa risposta qui per completezza nel caso specifico, ma penso che Akrun sia la soluzione generale migliore.

+0

diag (m) <- 14000' e 'm [upper.tri (m)] < - c (12000, 8000, 12000) 's mi sembra molto manuale. Come faresti con un vettore casuale. –