I had a similar problem. Frank's solution worked for me, but I wanted to come up with a more general solution. Frank's solution requires group member's to be ordered. Also, if you create a very large matrix (as I did), lapply
leave a lot of cache in the memory that cannot be cleaned with garbage collection (gc()
).
Required packages: igraph
and data.table
(not necessary, but it is faster).
library(igraph)
library(Matrix)
library(data.table)
hoodid <- c(1:10)
cityid <- c(1, 1, 1, 2, 2, 3, 3, 3, 3, 3)
df <- data.frame(hoodid, cityid)
df
# hoodid cityid
# 1 1 1
# 2 2 1
# 3 3 1
# 4 4 2
# 5 5 2
# 6 6 3
# 7 7 3
# 8 8 3
# 9 9 3
# 10 10 3
city_list = unique(df$cityid)
edges = list()
for (i in 1:length(city_list)) {
edges[[i]] = data.table(t(combn(df[df$cityid == city_list[i], 'hoodid'], 2)))
}
edges = rbindlist(edges)
g = graph_from_edgelist(as.matrix(edges), directed = F)
g = get.adjacency(g)
g
# 10 x 10 sparse Matrix of class "dgCMatrix"
#
# [1,] . 1 1 . . . . . . .
# [2,] 1 . 1 . . . . . . .
# [3,] 1 1 . . . . . . . .
# [4,] . . . . 1 . . . . .
# [5,] . . . 1 . . . . . .
# [6,] . . . . . . 1 1 1 1
# [7,] . . . . . 1 . 1 1 1
# [8,] . . . . . 1 1 . 1 1
# [9,] . . . . . 1 1 1 . 1
# [10,] . . . . . 1 1 1 1 .
Without data.table
library(igraph)
library(Matrix)
hoodid <- c(1:10)
cityid <- c(1, 1, 1, 2, 2, 3, 3, 3, 3, 3)
df <- data.frame(hoodid, cityid)
df
# hoodid cityid
# 1 1 1
# 2 2 1
# 3 3 1
# 4 4 2
# 5 5 2
# 6 6 3
# 7 7 3
# 8 8 3
# 9 9 3
# 10 10 3
edges = data.frame(matrix(ncol = 2, nrow = 0))
for (i in unique(df$cityid)) {
edges = rbind(edges, t(combn(df[df$cityid == i, 'hoodid'], 2)))
}
g = graph_from_edgelist(as.matrix(edges), directed = F)
g = get.adjacency(g)
g
# 10 x 10 sparse Matrix of class "dgCMatrix"
#
# [1,] . 1 1 . . . . . . .
# [2,] 1 . 1 . . . . . . .
# [3,] 1 1 . . . . . . . .
# [4,] . . . . 1 . . . . .
# [5,] . . . 1 . . . . . .
# [6,] . . . . . . 1 1 1 1
# [7,] . . . . . 1 . 1 1 1
# [8,] . . . . . 1 1 . 1 1
# [9,] . . . . . 1 1 1 . 1
# [10,] . . . . . 1 1 1 1 .