从组成员资格数据创建加权图

时间:2014-03-27 17:50:16

标签: r igraph

假设我在R中有一个数据集,表明组内的个人。这是一个例子:

grp <- c(1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5)
ind <- c("A", "C", "D", "B", "C", "D", "E", "A", "D", "E", "B", "F", "E", "A", "F")
data.frame(grp, ind)

所以,数据看起来像这样:

   grp ind
1    1   A
2    1   C
3    1   D
4    2   B
5    2   C
6    2   D
7    2   E
8    3   A
9    3   D
10   3   E
11   4   B
12   4   F
13   4   E
14   5   A
15   5   F

因此,组1由个体(A,C,D)组成,组2由个体(B,C,D,E)组成,等等。我想创建一个网络图,显示个人如何相互联系。在一个组中,所有个体都通过边连接。边缘的厚度应该反映两个人彼此连接的频率。

使用:

pairs <- do.call(rbind, sapply(split(ind, grp), function(x) t(combn(x,2))))

我可以获得一个包含所有成对边的矩阵,我可以使用igraph包进行绘图:

library(igraph)
plot(graph.edgelist(pairs, directed=FALSE), edge.curved=FALSE)

network

但有没有办法让边缘的厚度与特定配对发生的频率成正比?

4 个答案:

答案 0 :(得分:3)

@ hrbrmstr的解决方案构建第二个图以获得边权重。您也可以通过操作pairs

预先执行此操作
# Count unique edge pairs
library(plyr)
weighted <- ddply(data.frame(pairs), .(X1, X2), count)

# Plot
library(igraph)
g <- graph.edgelist(as.matrix(weighted[,1:2]), directed=FALSE)
plot(g, edge.curved=FALSE, edge.width=weighted$freq*3)

enter image description here

答案 1 :(得分:2)

可能会收紧一点,但是......

library(igraph)

grp <- c(1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5)
ind <- c("A", "C", "D", "B", "C", "D", "E", "A", "D", "E", "B", "F", "E", "A", "F")

pairs <- do.call(rbind, sapply(split(ind, grp), function(x) t(combn(x,2))))

g <- graph.edgelist(pairs, directed=FALSE)

m <- get.adjacency(g) # get the adjacency matrix

net <- graph.adjacency(m,
                       mode="undirected",
                       weighted=TRUE,
                       diag=FALSE)

print(E(net)$weight) # just for kicks
## [1] 1 2 1 1 2 1 1 1 2 2 1 1

set.seed(1492) # ensures consistent layout every run

plot.igraph(net, 
            vertex.label=V(net)$name,
            layout=layout.fruchterman.reingold,
            edge.color="black",
            edge.width=E(net)$weight*3)

plot

答案 2 :(得分:1)

library(igraph)
grp <- c(1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5)
ind <- c("A", "C", "D", "B", "C", "D", "E", "A", "D", "E", "B", "F", "E", "A", "F")
data.frame(grp, ind)

pairs <- do.call(rbind, sapply(split(ind, grp), function(x) t(combn(x,2))))
g = graph.data.frame(pairs, directed=FALSE)

E(g)$weight = c(1, grp)
plot.igraph(g, edge.width=E(g)$weight)

我不确定我是否正确加重,但我希望您发现我的代码有用。 您可以找到更多有用的示例代码here on weight-edgehere on weight-node

答案 3 :(得分:1)

这是一个创建二分图的解决方案,然后将其投射给个人。

g <- graph.edgelist(cbind(grp, ind), directed=FALSE)
V(g)$type <- V(g)$name %in% grp 
ind_g <- bipartite.projection(g)[[1]]
E(ind_g)$width <- E(ind_g)$weight * 3
plot(ind_g)

graph plot