2015-06-15 19 views
6

Ho cercato di risolvere il seguente problema.Creazione di una matrice triangolare da un vettore che esegue operazioni sequenziali

Se ho il vettore seguente:

aux1<-c(0,0,0,4,5,0,7,0,0,10,11,12) dove i numeri rappresentano il numero della riga.

Voglio calcolare la distanza tra i diversi elementi di questo vettore che fissa il primo componente, quindi il secondo e così via.

Se l'elemento è zero, non voglio contarlo, quindi ho inserito un NA. L'uscita Voglio dovrebbe presentarsi così:

NA NA NA NA NA 
NA NA NA NA NA 
NA NA NA NA NA 
NA NA NA NA NA 
1 NA NA NA NA 
NA NA NA NA NA 
3 2 NA NA NA 
NA NA NA NA NA 
NA NA NA NA NA 
6 5 3 NA NA 
7 6 4 1 
8 7 5 2 1 

Nella prima colonna, ho la differenza tra il primo elemento diverso da zero e tutti gli altri elementi, vale a dire, Matrice [5,1] = 5-4 = 1 e matrice [12,1] = 12-4 = 8. Inoltre, Matrix [7,2] = 7-5 = 2, dove 5 è il secondo elemento nel vettore non uguale a zero. Si noti che Matrix [10,3] = 10-7 = 3, dove 7 è il terzo elemento non uguale a zero, ma il settimo elemento nel mio vettore.

Ho provato a farlo in un ciclo. Il mio codice attuale assomiglia a questo:

M=matrix(nrow=N-1, ncol=N-1)) 

for (i in 1:N-1){ 
    for (j in 1:N-1){ 
    if(j<=i) 
     next 
    else 
     if(aux1[j]>0) 
     M[j,i]=aux1[j]-aux1[i] 
     else 
     M[j,i]=0 
    } 
} 

Sfortunatamente. Non sono stato in grado di risolvere il mio problema. Qualsiasi aiuto sarebbe molto apprezzato.

risposta

1

Utilizzando sapply e ifelse:

sapply(head(vv[vv>0],-1),function(y)ifelse(vv-y>0,vv-y,NA)) 

È un ciclo su valori positivi (si dovrebbe anche togliere la ultimo elemento), quindi estrai ogni valore dal vettore originale. Ho usato ifelse per sostituire i valori negativi.

#  [,1] [,2] [,3] [,4] [,5] 
# [1,] NA NA NA NA NA 
# [2,] NA NA NA NA NA 
# [3,] NA NA NA NA NA 
# [4,] NA NA NA NA NA 
# [5,] 1 NA NA NA NA 
# [6,] NA NA NA NA NA 
# [7,] 3 2 NA NA NA 
# [8,] NA NA NA NA NA 
# [9,] NA NA NA NA NA 
# [10,] 6 5 3 NA NA 
# [11,] 7 6 4 1 NA 
# [12,] 8 7 5 2 1 
3

Si potrebbe provare qualcosa di simile al seguente (con l'aiuto di generosi @thela)

res <- outer(aux1, head(aux1[aux1 > 0], -1), `-`) 
is.na(res) <- res <= 0 
#  [,1] [,2] [,3] [,4] [,5] 
# [1,] NA NA NA NA NA 
# [2,] NA NA NA NA NA 
# [3,] NA NA NA NA NA 
# [4,] NA NA NA NA NA 
# [5,] 1 NA NA NA NA 
# [6,] NA NA NA NA NA 
# [7,] 3 2 NA NA NA 
# [8,] NA NA NA NA NA 
# [9,] NA NA NA NA NA 
# [10,] 6 5 3 NA NA 
# [11,] 7 6 4 1 NA 
# [12,] 8 7 5 2 1 
+1

Variazione sulla risposta già valida: 'out <- outer (aux1, head (aux1 [aux1> 0], - 1), \' - \ '); replace (out, out <= 0, NA) '. Dovrebbe impedire un numero di calcoli necessario per la chiamata 'esterna'. – thelatemail

+0

@thelatemail molto bello. Ho modificato di conseguenza. Mi stavo rompendo la testa su come evitare di eseguirlo su tutte le combinazioni. –