2015-06-15 24 views
6

Próbuję rozwiązać następujący problem.Tworzenie trójkątnej matrycy z wektora wykonującego sekwencyjne operacje

Załóżmy, że mają następujący wektor:

aux1<-c(0,0,0,4,5,0,7,0,0,10,11,12) gdzie liczby oznaczają numer rzędu.

Chcę obliczyć odległość między różnymi elementami tego wektora, ustalając pierwszy komponent, a następnie drugi i tak dalej.

Jeśli element ma wartość zero, nie chcę go liczyć, dlatego zamiast niego wstawiam NA. Wyjście chcę powinna wyglądać następująco:

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 

W pierwszej kolumnie, mam różnicę pomiędzy pierwszym elementem różny od zera i wszystkich innych elementów, czyli Matrix [5,1] = 5-4 = 1 i Matryca [12,1] = 12-4 = 8. Również Matrix [7,2] = 7-5 = 2, gdzie 5 to drugi element w wektorze nie równy zeru. Zauważ, że Matryca [10,3] = 10-7 = 3, gdzie 7 to trzeci element nie równy zeru, ale siódmy element w moim wektorze.

Próbowałem to zrobić w pętli. Mój obecny kod wygląda następująco:

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

Niestety. Nie byłem w stanie rozwiązać mojego problemu. Każda pomoc będzie bardzo ceniona.

Odpowiedz

1

Korzystanie sapply i ifelse:

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

można pętli nad pozytywnymi wartościami (należy również usunąć ostatni element), a następnie wyodrębniasz każdą wartość z oryginalnego wektora. Użyłem ifelse, aby zastąpić wartości ujemne.

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

Można spróbować coś jak następuje (z hojnej pomocy @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

Wariacja na już drobnym odpowiedź: 'out <- zewnętrzna (AUX1, głowica (AUX1 [AUX1> 0], - 1), \' - \ '); zamień (out, out <= 0, NA) ". Powinien uniemożliwić przeprowadzenie tak dużej liczby obliczeń w wywołaniu "zewnętrznym". – thelatemail

+0

@ poczta bardzo miła. Zmodyfikowałem odpowiednio. Łamałem sobie głowę, jak uniknąć uruchamiania go we wszystkich kombinacjach. –