I am trying to compute a pairwise matrix in R that counts the number of times individuals interact with other individuals (so the matrix will include N number of rows and columns corresponding to number of individuals). I have a dataframe that lists "actors" and "partners" in separate columns.
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'))
The data are such that direction of the interaction is irrelevant, so each cell should count the number of times individual X acts on Y plus the number of times Y acts on X. Ideally, the data frame above should give a matrix that looks like this:
DOL JOJ NOR NIN
DOL 0 2 3 1
JOJ 2 0 2 0
NOR 3 2 0 2
NIN 1 0 2 0
I started writing a loop to cycle through each individual in my dataset and to count his/her interactions both from actor->partner and partner->actor. I'm sure this would work, but is not ideal as the full dataset is quite large. Is there a better way?
Update: Thanks for the responses! Both solutions work great! I'm posting my implementation of Josh's suggestion, which was very helpful.
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]
Base R's table()
will get you what you're after:
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
In the field of graph theory, what you are looking for is an adjacency matrix:
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With