假设我在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)
但有没有办法让边缘的厚度与特定配对发生的频率成正比?
答案 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)
答案 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)
答案 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-edge或here 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)