2013-01-14 5 views
8

Ho bisogno di accedere e assegnare singoli slot di una matrice m * n all'interno di un ciclo for. Il codice finora:Assegna valore a voci diagonali di matrice

rowCount <- 9 
similMatrix = matrix(nrow = rowCount - 1, ncol = rowCount) 
show(similMatrix) 
for(i in (rowCount - 1)){ 
    for (j in rowCount) 
    if (i == j){ 
     similMatrix[i == j] <- 0; 
    } 
} 
show(similMatrix) 

quindi se i = j il valore NA nella matrice deve essere sostituito con 0.

+0

Non sei ottenendo l'output desiderato? –

risposta

10

Ai fini della impostando gli elementi "diagonali" a zero ti è già stata data una risposta, ma mi chiedo se stavi sperando in qualcosa di più generale. Le ragioni della mancanza di successo con quel codice erano duplici: la costruzione dei tuoi indici era errata e l'indicizzazione era sbagliata. Questo sarebbe riuscito:

for(i in 1:(rowCount - 1)){ # need an expression that retruns a sequence 
    for (j in 1:rowCount)  # ditto 
    if (i == j){ 
     similMatrix[i,j] <- 0; # need to index the matrix with two element if using i,j 
    } 
} 
#---------- 
> show(similMatrix) 
    [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] 
[1,] 0 NA NA NA NA NA NA NA NA 
[2,] NA 0 NA NA NA NA NA NA NA 
[3,] NA NA 0 NA NA NA NA NA NA 
[4,] NA NA NA 0 NA NA NA NA NA 
[5,] NA NA NA NA 0 NA NA NA NA 
[6,] NA NA NA NA NA 0 NA NA NA 
[7,] NA NA NA NA NA NA 0 NA NA 
[8,] NA NA NA NA NA NA NA 0 NA 

Ma ricorrere a cicli in R è generalmente considerata l'ultima risorsa C'è un modo molto più compatto di fare la stessa operazione "loop" e generalizza (a volte per le ragioni sbagliate.) più ampiamente della semplice impostazione della diagonale.

similMatrix[ row(similMatrix) == col(similMatrix) ] <- 0 
> similMatrix 
    [,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] 
[1,] 0 NA NA NA NA NA NA NA NA 
[2,] NA 0 NA NA NA NA NA NA NA 
[3,] NA NA 0 NA NA NA NA NA NA 
[4,] NA NA NA 0 NA NA NA NA NA 
[5,] NA NA NA NA 0 NA NA NA NA 
[6,] NA NA NA NA NA 0 NA NA NA 
[7,] NA NA NA NA NA NA 0 NA NA 
[8,] NA NA NA NA NA NA NA 0 NA 

Se si volesse impostare il sotto la diagonale a zero si potrebbe utilizzare:

similMatrix[ row(similMatrix)-1 == col(similMatrix) ] <- 0 

si può evitare la generazione di riga in più e matrici Col utilizzare questo:

mind <- min(dim(similMatrix)) 
# avoid going outside dimensions if not symmetric 
similMatrix[ cbind(seq(maxd),seq(maxd)) <- 0 
+0

questo è perfetto, grazie mille! –

+1

Immagino che 'row (mat)' e 'col (mat)' genereranno due matrici, non significherebbe che stiamo triplicando il consumo di memoria di qui? Se 'mat' è successo a per essere grandi, immagino che questo possa causare problemi. – qed

+0

Giusto. Non ho visto alcun avvertimento che queste fossero grandi matrici. La "compattezza" che stavo offrendo era espressiva, ma come lei ha sottolineato, questo potrebbe non essere compatto nell'impronta di memoria. Si può immaginare usando 'similMatrix [cbind (1: (rowCount - 1), 1: (rowCount - 1)] <- 0' e immagino che si esibirà in modo superiore sia per la memoria che per la velocità. pensando che potrebbe avere un'impronta ancora più bassa che l'approccio 'mat [diag (mat)] <-0'. –

27

Si desidera che la funzione di diag<-

m <- matrix(1:12, nrow=3) 
m 
    [,1] [,2] [,3] [,4] 
[1,] 1 4 7 10 
[2,] 2 5 8 11 
[3,] 3 6 9 12 

diag(m) <- 0 
m 
    [,1] [,2] [,3] [,4] 
[1,] 0 4 7 10 
[2,] 2 0 8 11 
[3,] 3 6 0 12 
+0

Dov'è il pulsante "cancella-rispondi-e-upvote-the-altro"? – mnel

+0

grazie, funziona, ma come posso ora assegnare un valore per diciamo m [1, 2]? –