web-dev-qa-db-fra.com

igraphe créant une matrice d'adjacence pondérée

J'essaie d'utiliser le package igraph pour dessiner un graphique pondéré (clairsemé). J'ai actuellement une matrice d'adjacence, mais je ne peux pas obtenir le graph.adjacency fonction pour reconnaître les poids Edge.

Considérez la matrice symétrique aléatoire suivante:

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)

Pour tracer, je dois d'abord obtenir cette matrice d'adjacence dans le format igraph approprié. Cela devrait être relativement simple avec graph.adjacency. D'après ma lecture de la documentation pour graph.adjacency , je devrais faire ce qui suit:

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

Cependant, il ne reconnaît pas les poids Edge:

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

Comment puis-je demander à igraph de reconnaître les poids Edge?

17
Scott Ritchie

Les poids sont là, weight (e/n) signifie qu'il existe un attribut Edge appelé poids, et il est numérique. Voir ?print.igraph. Mais ils ne sont pas tracés par défaut, vous devez les ajouter en tant que Edge.label.

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

graph plot screenshot

Pour le traçage, assurez-vous de lire ?igraph.plotting.

27
Gabor Csardi

La solution de @ TWL peut être facilement généralisée pour représenter la largeur des bords en fonction des poids, y compris les poids négatifs. L'astuce consiste à traduire tous les poids en additionnant la valeur du plus petit poids (plus éventuellement un décalage qui représente la largeur du poids minimum). Par exemple:

# 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

9
ddiez

Autant que j'aime igraph, j'ai trouvé le paquet qgraph plus facile à tracer des réseaux pondérés.

Avec la matrice d'adjacence, vous pouvez aussi simplement utiliser qgraph() de la bibliothèque qgraph pour le tracer. Il colorera automatiquement les bords négatifs d'une nuance de rouge et les bords positifs d'une nuance de vert.

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

qgraph est construit sur igraph, mais fait tout pour vous.

8
James Tobin

Vous pouvez extraire les poids Edge avec E(ig)$weight et les affecter à l'argument Edge.width Dans la fonction de traçage:

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

Voir le ?igraph.plotting [ lien ] pour référence.

Veuillez également noter que dans cet exemple, les poids correspondront à la largeur des bords, ils devraient donc être >= 0.

4
TWL