2015-01-27 11 views
5

Może być dostępna wersja tcrossprod, ale nie udało mi się jej znaleźć. Z poniższego przykładu, jak uzyskać tylko wiersze z pierwszym wystąpieniem kombinacji, jeśli zamówienie nie ma znaczenia? To znaczy. (1,2) dla mnie jest taki sam jak (2,1).R tcrossprod z unikalnymi kombinacjami

a <- c(1,2,3,4) 
b <- c(10,5,4,10) 
df<- data.frame(a,b) 

melt(tcrossprod(df$b,1/df$b)) 

> melt(tcrossprod(df$b,1/df$b)) 
    Var1 Var2 value 
1  1 1 1.00 
2  2 1 0.50 
3  3 1 0.40 
4  4 1 1.00 
5  1 2 2.00 
6  2 2 1.00 
7  3 2 0.80 
8  4 2 2.00 
9  1 3 2.50 
10 2 3 1.25 
11 3 3 1.00 
12 4 3 2.50 
13 1 4 1.00 
14 2 4 0.50 
15 3 4 0.40 
16 4 4 1.00 
+1

bit hack, ale działa: 'tt <- tcrossprod (df $ b, 1/df $ b); tt [upper.tri (tt)] <- NA; reshape2 :: melt (tt, na.rm = T); ' – user20650

+0

@ user20650 Myślę, że pierwsze wystąpienia w tabeli odpowiadają niższej trójkątnej części, należy użyć' lower.tri' zamiast 'upper.tri', i powinien dodatkowo użyć argumentu 'diag = TRUE', ponieważ chcemy również tych elementów diagonalnych. – tkmckenzie

+0

hi @tkmckenzie; wypróbuj kod - myślę, że tworzy on prawidłową kolejność i nie chcemy "diag = TRUE", ponieważ spowoduje to ustawienie przekątnych wpisów na 'NA' – user20650

Odpowiedz

4

Mając m <- melt(tcrossprod(df$b,1/df$b)), można po prostu zrobić:

subset(m,X1>X2) 

# X1 X2 value 
#2 2 1 0.5 
#3 3 1 0.4 
#4 4 1 1.0 
#7 3 2 0.8 
#8 4 2 2.0 
#12 4 3 2.5 
+0

Prawdopodobnie powinien być 'podzbiór (m, X1> = X2)' –

+0

Oczywiście, może to być X1> = X2 w razie potrzeby, aby uwzględnić elementy przekątne. Nie zrobiłem tego, ponieważ OP nic o nich nie powiedział i założyłem z jego poprzedniego pytania na ten temat (http://stackoverflow.com/q/28158426/1898580), że elementy diagonalne nie są tutaj interesujące. –

+1

Aha, nie wiedziałem, że były inne powiązane pytania, więc właśnie odłączyłem się od wyrażenia "pierwsze wystąpienie kombinacji". –