2013-02-26 16 views
9

to pytanie jest związane z tym one, ale chcę utworzyć indeks przy użyciu unikalnej kombinacji dwóch kolumn data.frame. Więc moja struktura danych wygląda na przykład tak (dput):Utwórz indeks kombinacji kolumn data.frame w R

structure(list(avg = c(0.246985988921473, 0.481522354272779, 
0.575400762275067, 0.14651009243539, 0.489308880181752, 0.523678968337178 
), i_ID = c("H", "H", "C", "C", "H", "S"), j_ID = c("P", "P", 
"P", "P", "P", "P")), .Names = c("avg", "i_ID", "j_ID"), row.names = 7:12, class = "data.frame") 

Utworzona Indeks do powyższej struktury powinny zatem wyglądać następująco

1 
1 
2 
2 
1 
3 

w przykładowych danych kolumna j_ID zawsze ma wartość P, ale nie zawsze tak jest. Ponadto kombinacje vice versa (S-P lub P-S) powinny dawać ten sam wskaźnik.

Ktoś wie, w jaki sposób można to osiągnąć? Mogę to zrobić za pomocą wielu pętli for i-else, ale to nie jest zbyt eleganckie.

Odpowiedz

5

Funkcja interaction będzie działać poprawnie.

foo = structure(list(avg = c(0.246985988921473, 0.481522354272779, 0.575400762275067, 0.14651009243539, 0.489308880181752, 0.523678968337178), i_ID = c("H", "H", "C", "C", "H", "S"), j_ID = c("P", "P", "P", "P", "P", "P")), .Names = c("avg", "i_ID", "j_ID"), row.names = 7:12, class = "data.frame") 

foo$idx <- as.integer(interaction(foo$i_ID, foo$j_ID)) 

> foo 
     avg i_ID j_ID idx 
7 0.2469860 H P 2 
8 0.4815224 H P 2 
9 0.5754008 C P 1 
10 0.1465101 C P 1 
11 0.4893089 H P 2 
12 0.5236790 S P 3 

Ach, nie przeczytałem dość dokładnie. Nie ma chyba bardziej eleganckie rozwiązanie, ale można użyć outer funkcję i górne i dolne trójkąty:

# lets assign some test values 
x <- c('a', 'b', 'c') 
foo$idx <- c('a b', 'b a', 'b c', 'c b', 'a a', 'b a') 

mat <- outer(x, x, FUN = 'paste') # gives all possible combinations 
uppr_ok <- mat[upper.tri(mat, diag=TRUE)] 
mat_ok <- mat 
mat_ok[lower.tri(mat)] <- mat[upper.tri(mat)] 

Następnie można dopasować indeksy znalezione w mat z tych znalezionych w mat_ok.

foo$idx <- mat_ok[match(foo$idx, mat)] 

Ale ... Założę się, że to poręczne funkcja mi brakuje ...

+0

> Ponadto odwrotnie (S-P-S lub P) powinno prowadzić do tego samego indeksu. – krlmlr

+1

Nie widzę, aby to było zgodne z drugim ograniczeniem, że S-P i P-S mają ten sam indeks. –

+0

Tak, rzeczywiście działa całkiem dobrze, jednak jak wspomniał Gavin, nie daje tego samego indeksu odwrotnie. – Curlew

1

ten powinien być komentarz do @ odpowiedź Justina ale to zbyt długo :)

jeśli ciebie chciałby, aby indeksy zachowały porządek oryginału i_ID, można przypisać wyniki interaction() do zmiennej, a następnie order do levels.

x <- interaction(foo$i_ID, foo$j_ID) 
x <- factor(x, levels=levels(x)[order(unique(foo$i_ID))]) 

foo$idx <- as.integer(x) 

co daje: zespół

> foo 
     avg i_ID j_ID idx 
7 0.2469860 H P 1 
8 0.4815224 H P 1 
9 0.5754008 C P 2 
10 0.1465101 C P 2 
11 0.4893089 H P 1 
12 0.5236790 S P 3 
Powiązane problemy