2015-06-15 7 views
6

Ich habe versucht, das folgende Problem zu lösen.Erstellen Sie eine Dreiecksmatrix aus einem Vektor mit sequentiellen Operationen

Angenommen, ich habe folgenden vector:

aux1<-c(0,0,0,4,5,0,7,0,0,10,11,12) wobei die Zahlen die Anzahl der Zeile repräsentieren.

Ich möchte den Abstand zwischen den differents Elemente dieses Vektors, der die erste Komponente, dann die zweite und so weiter festlegt, berechnen.

Wenn das Element Null ist, möchte ich es nicht zählen, also stelle ich stattdessen eine NA. Der Ausgang I sollte wie folgt aussehen wollen:

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 

In der ersten Spalte, ich habe den Unterschied zwischen dem ersten Element von Null verschieden und alle anderen Elemente, dh Matrix [5,1] = 5-4 = 1 und Matrix [12,1] = 12-4 = 8. Außerdem ist Matrix [7,2] = 7-5 = 2, wobei 5 das zweite Element im Vektor ungleich Null ist. Beachten Sie, dass Matrix [10,3] = 10-7 = 3 ist, wobei 7 das dritte Element ungleich Null ist, aber das siebte Element in meinem Vektor.

Ich habe versucht, dies in einer Schleife zu tun. Mein aktueller Code sieht so aus:

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 
    } 
} 

Leider. Ich konnte mein Problem nicht lösen. Jede Hilfe würde sehr geschätzt werden.

Antwort

1

Mit sapply und ifelse:

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

Sie Schleife über die positiven Werte (Sie sollten auch das entfernen letztes Element), dann extrahieren Sie jeden Wert aus dem ursprünglichen Vektor. Ich habe ifelse verwendet, um negative Werte zu ersetzen.

#  [,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

Man könnte so etwas wie versuchen die folgenden (mit großzügigen Hilfe von @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

Variation auf Ihrer bereits feine Antwort: 'out <- Außen (aux1, Kopf (aux1 [aux1> 0], - 1), \' - \ '); ersetzen (out, out <= 0, NA) '. Sollte verhindern, dass so viele Berechnungen im "äußeren" Aufruf stattfinden müssen. – thelatemail

+0

@thelatemail sehr nett. Ich habe es entsprechend geändert. Ich habe mir den Kopf gebrochen, wie ich es vermeiden kann, über alle Kombinationen hinweg zu laufen. –

Verwandte Themen