2012-10-19 44 views
7

Próbuję obliczyć macierz parowania w R, która zlicza ile razy ludzie oddziałują z innymi jednostkami (więc macierz będzie zawierać liczbę N wierszy i kolumn odpowiadającą liczbie osobników). Mam ramkę danych, która zawiera listę "aktorów" i "partnerów" w osobnych kolumnach.Macierz interakcji równoległych w R

nn <- data.frame(actors=c('DOL','DOL','DOL','DOL','DOL','NOR','NOR','NOR','NIN','JOJ'),partners=c('JOJ','JOJ','NOR','NOR','NIN','NIN','DOL','JOJ','NOR','NOR')) 

Dane są takie, że kierunek oddziaływania jest nieistotne, więc każda komórka należy policzyć liczbę działa na poszczególne X Y plus liczba czasów T działa w X. W idealnym powyżej ramka danych powinna dać matrycę, która wygląda tak:

 DOL JOJ NOR NIN 
DOL 0 2 3 1 
JOJ 2 0 2 0 
NOR 3 2 0 2 
NIN 1 0 2 0 

zacząłem pisać pętlę do cyklu przez każdego osobnika w moim zbiorze i policzyć jego/jej interakcji zarówno z actor-> partnera i partnerstw> aktora. Jestem pewien, że to zadziała, ale nie jest idealne, ponieważ pełny zbiór danych jest dość duży. Czy istnieje lepszy sposób?


Aktualizacja: Dzięki za odpowiedzi! Oba rozwiązania działają świetnie! Zamieszczam moją implementację sugestii Josha, która była bardzo pomocna.

x <- with(nn, table(actors, partners)) 
y <- t(x) 

# unique individuals 
u <- unique(c(rownames(x),colnames(x))) 

m <- matrix(0,ncol=length(u),nrow=length(u),dimnames=list(u,u)) 

i1 <- as.matrix(expand.grid(rownames(x),colnames(x))) 
i2 <- as.matrix(expand.grid(rownames(y),colnames(y))) 

m[i1] <- x[i1] 
m[i2] <- m[i2] + y[i2] 

Odpowiedz

6

Baza R: table() będzie Ci co jesteś po:

x <- with(nn, table(actors, partners)) 
x + t(x) 
#  partners 
# actors DOL JOJ NIN NOR 
# DOL 0 2 1 3 
# JOJ 2 0 0 2 
# NIN 1 0 0 2 
# NOR 3 2 2 0 
+0

Schludny, więc jest to zasadniczo 'z (nn, table (aktorzy, partnerzy) + tabela (partnerzy, aktorzy))' prawda? – thelatemail

+0

Dzięki za to rozwiązanie! Zauważyłem, że to nie działa, jeśli transponowana tabela nie ma tych samych nazw wierszy i kolumn co oryginał, co może wystąpić, jeśli pewne interakcje pojawiają się tylko w jednym kierunku. Obejrzałem to, tworząc matrycę wzorcową z wszystkimi możliwymi osobami, a następnie używając indeksów do podziału tylko wiersze i kolumny, które pasowały przed dodaniem. Obliczyłem indeksy tak jak (jeden dla obu oryginalnych i przetransponowanych tabel) 'i <- as.matrix (expand.grid (rownames (x), colnames (x))) – boon

5

W dziedzinie teorii grafów, czego szukasz jest macierzą adjacency:

library(igraph) 
g <- graph.edgelist(as.matrix(nn), directed = FALSE) 
get.adjacency(g) 
#  DOL JOJ NOR NIN 
# DOL 0 2 3 1 
# JOJ 2 0 2 0 
# NOR 3 2 0 2 
# NIN 1 0 2 0 
+0

To jest idealne. Dziękuję bardzo - zaoszczędziłeś mi mnóstwo czasu! – boon

+2

+1 za podpięcie się z możliwą do wyszukania nazwą. –

+0

@ JoshO'Brien jak wybrać element z tej macierzy? – andi