library(dplyr)
##
## Attaching package: 'dplyr'
##
## The following object is masked from 'package:stats':
##
## filter
##
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
library(igraph)
Take a toy dataset of members of organizations. Numbers are people; letters are organizations.
test <- data_frame(people = c(1, 2, 3, 4, 5, 1, 2, 3, 3, 4, 5),
orgs = c("A", "A", "A", "A", "A", "B", "B", "B", "C", "C", "C"))
Turn that data into a graph:
g <- graph.data.frame(test)
From that graph were can get an adjacency matrix:
adj <- get.adjacency(g, sparse = FALSE)
adj
## 1 2 3 4 5 A B C
## 1 0 0 0 0 0 1 1 0
## 2 0 0 0 0 0 1 1 0
## 3 0 0 0 0 0 1 1 1
## 4 0 0 0 0 0 1 0 1
## 5 0 0 0 0 0 1 0 1
## A 0 0 0 0 0 0 0 0
## B 0 0 0 0 0 0 0 0
## C 0 0 0 0 0 0 0 0
The difficulty with this adjacency matrix is that it includes both people and organizations as both rows and columns. Since this is a bipartite graph, that is not necessary. We should subset the rows so we get only people, and we should subset the columns so we get only organizations.
adj_simple <- adj[rownames(adj) %in% test$people, colnames(adj) %in% test$orgs]
adj_simple
## A B C
## 1 1 1 0
## 2 1 1 0
## 3 1 1 1
## 4 1 0 1
## 5 1 0 1
That was what we wanted. Note that we can turn this into a data frame if we want.
as.data.frame(adj_simple)
## A B C
## 1 1 1 0
## 2 1 1 0
## 3 1 1 1
## 4 1 0 1
## 5 1 0 1
This is not necessarily the most elegant solution, but it works.