2014-01-23 167 views
13

我试图用igraph包绘制(稀疏)加权图。我目前有一个邻接矩阵,但不能让graph.adjacency函数识别边的权重。igraph创建加权邻接矩阵

考虑下面的随机对称矩阵:

m <- read.table(row.names=1, header=TRUE, text= 
"   A   B   C   D   E   F 
A 0.00000000 0.0000000 0.0000000 0.0000000 0.05119703 1.3431599 
B 0.00000000 0.0000000 -0.6088082 0.4016954 0.00000000 0.6132168 
C 0.00000000 -0.6088082 0.0000000 0.0000000 -0.63295415 0.0000000 
D 0.00000000 0.4016954 0.0000000 0.0000000 -0.29831267 0.0000000 
E 0.05119703 0.0000000 -0.6329541 -0.2983127 0.00000000 0.1562458 
F 1.34315990 0.6132168 0.0000000 0.0000000 0.15624584 0.0000000") 
m <- as.matrix(m) 

要绘制,首先我必须得到这个邻接矩阵到适当的igraph格式。这应该是相对简单的graph.adjacency。根据我的graph.adjacency文档的阅读,我应该做到以下几点:

library(igraph) 
ig <- graph.adjacency(m, mode="undirected", weighted=TRUE) 

但是,它不承认边权:

str(ig) 
# IGRAPH UNW- 6 8 -- 
# + attr: name (v/c), weight (e/n) 
# + edges (vertex names): 
# [1] A--E A--F B--C B--D B--F C--E D--E E--F 
plot(ig) 

enter image description here

如何获得igraph识别边缘权重?

+2

这似乎并不成为问题,但请注意,您在上面打印的矩阵不是对称的。 (尝试'isSymmetric(m)',然后比较'm [5,3]'和'm [3,5]'的值。) –

+0

@ JoshO'Brien,它似乎是一个简单的复制和粘贴错误,A和E列中的数字有8个小数位,而其余的有7个。除此之外它是对称的:'isSymmetric(round(m,6))== TRUE'。有趣的是,'igraph'保留了小数位数最多的版本,并且在数字末尾加上了小数点后7位的差异时加上了0。 – TWL

+2

权重在那里,'weight(e/n)'意味着有一个称为'weight'的边缘属性,它是数字。请参阅'?print.igraph'。但是它们不是默认绘制的,你需要将它们添加为'edge.label'。 –

回答

25

权重在那里,weight (e/n)意味着有一个称为weight的边缘属性,它是数字。见?print.igraph。但是它们不是默认绘制的,你需要将它们添加为edge.label。

plot(ig, edge.label=round(E(ig)$weight, 3)) 

graph plot screenshot

为绘制,请务必阅读?igraph.plotting

3

可以与E(ig)$weight提取边缘的权重,并将其分配到在绘图功能的edge.width参数:

plot(ig, edge.width=E(ig)$weight)

参见?igraph.plotting [link]以供参考。

另请注意,在本例中,权重将对应于边缘的宽度,因此它们应该是>= 0

+0

边缘权重可以是负值,AFAIK没有任何问题。 –

+0

@GaborCsardi,我并不是说边缘权重不能是负数。在我的答案中,他们应该积极地被视为**边缘宽度**。因此,我发现-1票有点仓促。尽管如此,为了避免混淆,我编辑了答案。 – TWL

+0

我明白了,对不起,误会了。 –

8

尽管我喜欢igraph,但我发现qgraph软件包更容易绘制加权网络。

使用邻接矩阵,您也可以使用qgraph库中的qgraph()来绘制它。它会自动将负边缘颜色变为红色,正边缘变成绿色。

install.packages('qgraph') 
require(qgraph) 
qgraph(m) 
qgraph(m,edge.labels=TRUE) #if you want the weights on the edges as well 

qgraph建立在igraph上,但只是为你做了一切。

+1

供参考:你**可以**在igraph有负边缘。另外,'qgraph'只是调用'igraph' AFAIK。 –

+0

我意识到qgraph调用igraph。用它来绘制加权网络更容易,因为它在后台为你做了一切。 –

+0

当然,我同意这很有用。 -1是因为你暗示igraph无法处理消极的边缘,这是错误的信息。我编辑的 –

7

@ TWL的解决方案可以很容易地推广,以表示边的宽度作为权重的函数,包括负权重。诀窍是通过将最小权重值(可选地代表最小权重宽度的偏移量)相加来转换所有权重。例如:

# reproducible example: 
set.seed(12345) 
a <- matrix(runif(5*5, min=-10, max=10), ncol=5) 
diag(a) <- 0 # remove loops. 
>a 
      [,1]  [,2]  [,3]  [,4]  [,5] 
[1,] 0.0000000 -6.6725643 -9.309291 -0.7501069 -0.9254385 
[2,] 7.5154639 0.0000000 -6.952530 -2.2371204 -3.4649518 
[3,] 5.2196466 0.1844867 0.000000 -1.9502972 9.3083065 
[4,] 7.7224913 4.5541051 -9.977268 0.0000000 4.1496375 
[5,] -0.8703808 9.7947388 -2.175933 9.0331751 0.0000000 

# create igraph object. 
g <- graph.adjacency(a, mode="undirected", weighted=TRUE) 
plot(g) 

# assign edge's width as a function of weights. 
E(g)$width <- E(g)$weight + min(E(g)$weight) + 1 # offset=1 
plot(g) 

enter image description here