这是一个看似简单的问题,但我无法想出答案。这是最简单的情况:
考虑以下矩阵:
friendMatrix <- matrix(c(1,1,0,0,0,
1,1,1,0,0,
0,1,1,0,0,
0,0,0,1,1,
0,0,0,1,1),nrow=5)
看起来像这样
[,1] [,2] [,3] [,4] [,5]
[1,] 1 1 0 0 0
[2,] 1 1 1 0 0
[3,] 0 1 1 0 0
[4,] 0 0 0 1 1
[5,] 0 0 0 1 1
我想要做的是使用此矩阵来识别朋友组,其中1表示友谊。组是基于组内的任何连接而形成的,而不仅仅是第一级的连接(即,1是2的朋友,2是3的朋友,但不是1,但它们都在同一组中)。如果一行只与自身相关联,那么它就是它自己的组。我想在这些组中创建一个指示成员资格的数据框(使用行号作为ID)(一个数字可以作为ID,我只是用字母来避免混淆)。对于此示例,将是以下内容:
row group
1 A
2 A
3 A
4 B
5 B
我已经考虑了一些聚类算法,但这似乎有些过分,因为这些组定义明确且很明显。
答案 0 :(得分:4)
使用igraph
创建图表并通过对结果图表的连接组件进行分组来创建集群:
library(igraph)
g1 <- graph.adjacency( friendMatrix )
cl <- clusters(g1)$mem
## Display the clusters in a data.frame as OP excpeted
data.frame(row=seq_along(cl),group=LETTERS[cl])
row group
1 1 A
2 2 A
3 3 A
4 4 B
5 5 B
答案 1 :(得分:3)
从几年前开始调整my answer to a similar question,您可以使用 RBGL 包来识别&#34;连接的组件&#34;你在追求:
library(RBGL)
m <- which(friendMatrix==1, arr.ind=TRUE)
g <- ftM2graphNEL(m)
cc <- connectedComp(g)
names(cc) <- LETTERS[seq_along(cc)]
ld <- lapply(seq_along(cc),
function(i) data.frame(row = cc[[i]], group = names(cc)[i]))
do.call(rbind, ld)
# row group
# 1 1 A
# 2 2 A
# 3 3 A
# 4 4 B
# 5 5 B
替代方案,基于 igraph 的解决方案,see here。
答案 2 :(得分:3)
这是另一种选择:
library(igraph)
g <- graph.adjacency(friendMatrix, "undirected")
(group <- clusters(g)$membership)
# [1] 1 1 1 2 2
V(g)$color <- group + 1
plot(g)
答案 3 :(得分:2)
以下内容使您能够可视化关系网络,仍在研究如何提取组。
require(networkD3)
require(reshape2)
melted <- melt(friendMatrix)
relationships <- subset(melted, value == 1)
relationships
# Var1 Var2 value
# 1 1 1 1
# 2 2 1 1
# 6 1 2 1
# 7 2 2 1
# 8 3 2 1
# 12 2 3 1
# 13 3 3 1
# 19 4 4 1
# 20 5 4 1
# 24 4 5 1
# 25 5 5 1
simpleNetwork(relationships)