Igraph, создающий взвешенную матрицу смежности
Я пытаюсь использовать пакет igraph
для рисования (разреженного) взвешенного графика. В настоящее время я имею матрицу смежности, но не могу получить функцию graph.adjacency
для распознавания весов ребер.
Рассмотрим следующую случайную симметричную матрицу:
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 для распознавания весов края?
Ответы
Ответ 1
Весы там, weight (e/n)
означает, что есть атрибут edge, называемый весом, и он является числовым. См. ?print.igraph
. Но они по умолчанию не построены, вам нужно добавить их как edge.label.
plot(ig, edge.label=round(E(ig)$weight, 3))
![graph plot screenshot]()
Для печати убедитесь, что вы прочитали ?igraph.plotting
.
Ответ 2
@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 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]()
Ответ 3
Насколько мне нравится 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, но просто делает все для вас.
Ответ 4
Вы можете извлечь вес края с помощью E(ig)$weight
и назначить их аргументу edge.width
в функции построения графика:
plot(ig, edge.width=E(ig)$weight)
См. ссылку ?igraph.plotting
[ для справки.
Также обратите внимание, что в этом примере веса будут соответствовать ширине краев, поэтому они должны быть >= 0
.