# One row per connection: who worked with whom, and on how many projects.
edges <- data.frame(
from = c("Alice","Alice","Alice","Bob","Bob","Carol",
"Eve","Eve","Eve","Frank","Frank","Grace",
"Ivan","Ivan","Ivan","Ivan","Dan"),
to = c("Bob","Carol","Dan","Carol","Dan","Dan",
"Frank","Grace","Heidi","Grace","Heidi","Heidi",
"Carol","Dan","Eve","Grace","Eve"),
projects = c(5, 4, 3, 4, 2, 5, 5, 4, 3, 5, 3, 4, 2, 2, 3, 2, 2)
)
# One row per entity, with an attribute (their team).
nodes <- data.frame(
name = c("Alice","Bob","Carol","Dan","Eve","Frank","Grace","Heidi","Ivan"),
team = c("Design","Design","Design","Design",
"Data","Data","Data","Data","Ops")
)Visualisation et analyse de réseaux en R
Construire un graphe à partir d’un data frame, puis le tracer et l’analyser — dispositions, centralité, communauté et interactivité
Apprenez la visualisation et l’analyse de réseaux en R de bout en bout. Transformez un data frame d’arêtes/nœuds en graphe avec graph_from_data_frame() d’igraph, choisissez une disposition, dimensionnez les nœuds selon le degré et colorez par communauté avec cluster_louvain(). Puis analysez et manipulez-le avec tidygraph — activez les tables de nœuds/arêtes avec activate(), modifiez-les avec les verbes dplyr, et classez les nœuds avec le menu centrality_* — tracez-le en qualité publication avec ggraph, et rendez-le explorable avec visNetwork.
- Transformer une liste d’arêtes (un data frame de connexions) en graphe avec
igraph::graph_from_data_frame(). - Le tracer rapidement, puis changer de disposition (
fr,circle,kk) pour modifier l’agencement du réseau. - Styliser avec du sens : dimensionner les nœuds selon le degré, les colorer par communauté avec
cluster_louvain(), et régler la largeur des arêtes selon le poids. - Dessiner le même graphe en qualité publication avec
ggraph, puis le rendre interactif (glisser + zoomer) avecvisNetwork/networkD3. - Analyser et manipuler le graphe avec
tidygraph:activate()les tables de nœuds/arêtes, les modifier avec les verbesdplyr, et classer les nœuds avec le menucentrality_*(intermédiarité, proximité, PageRank…). - Chaque figure statique est produite à partir de vrai code R copiable — vous n’avez besoin que d’
igraph,tidygraphetggraph.
Un graphe de réseau répond à une question qu’un tableau ne pourra jamais poser : qui est connecté à qui, et comment ces connexions se regroupent-elles ? Liens sociaux, citations, interactions géniques, dépendances de paquets, transactions — tout ce qui possède des entités et des relations est un réseau, et le dessiner transforme une longue liste d’arêtes en une image lisible d’un coup d’œil.
Cet article est la recette pratique. Nous construirons un petit réseau à partir de zéro — un réseau de collaboration de neuf coéquipiers — et le mènerons d’un data frame jusqu’à une figure stylisée et interprétable, et enfin jusqu’à un widget interactif. (Si votre « réseau » est une matrice de corrélation, c’est un cas particulier avec son propre raccourci en deux lignes — voyez l’article jumeau Graphe de réseau de corrélation en R ; celui-ci est la recette générale pour n’importe quelle liste d’arêtes.)
Le vocabulaire, en un paragraphe
Un graphe (employé indifféremment avec réseau) est constitué de nœuds (aussi appelés sommets — les entités, ici des personnes) et d’arêtes (les connexions entre eux — ici, « ont travaillé ensemble »). Une arête peut porter un poids (une magnitude, par exemple le nombre de projets partagés) et un graphe peut être orienté (les arêtes ont une direction, comme « A suit B ») ou non orienté (le lien est mutuel, comme une co-signature). Deux résumés font l’essentiel du travail d’interprétation : le degré d’un nœud est simplement le nombre d’arêtes qui le touchent (un indice grossier de popularité/activité), et une communauté est un groupe de nœuds plus densément connectés entre eux qu’au reste du graphe. Voilà tout le vocabulaire — tout ce qui suit n’est que ces cinq mots en code.
Construire un graphe à partir d’un data frame
Le point de départ le plus courant dans la pratique est une liste d’arêtes : une ligne par connexion, avec une colonne from et une colonne to, plus d’éventuels attributs d’arête. Vous pouvez ajouter en option une liste de nœuds : une ligne par entité avec ses attributs. Nous définirons les deux directement dans le code pour que l’exemple soit entièrement autonome (aucun téléchargement, aucune donnée externe) :
graph_from_data_frame() d’igraph assemble tout cela en un objet graphe. Il lit les deux premières colonnes d’edges comme les extrémités, conserve les colonnes restantes (projects) comme attributs d’arête, et met en correspondance vertices par la première colonne du nœud (name), attachant le reste (team) comme attributs de nœud. Nous fixons directed = FALSE car « travailler ensemble » est mutuel :
library(igraph)
g <- graph_from_data_frame(edges, vertices = nodes, directed = FALSE)
gIGRAPH 51e583d UN-- 9 17 --
+ attr: name (v/c), team (v/c), projects (e/n)
+ edges from 51e583d (vertex names):
[1] Alice--Bob Alice--Carol Alice--Dan Bob --Carol Bob --Dan
[6] Carol--Dan Eve --Frank Eve --Grace Eve --Heidi Frank--Grace
[11] Frank--Heidi Grace--Heidi Carol--Ivan Dan --Ivan Eve --Ivan
[16] Grace--Ivan Dan --Eve
Lisez l’en-tête : UN-- 9 17 désigne un graphe Undirected (non orienté), Named (nommé) avec 9 nœuds et 17 arêtes, et attr: confirme que name/team vivent sur les nœuds et projects sur les arêtes. Le graphe est l’unique objet sur lequel opèrent toutes les fonctions ci-dessous.
Le tracer — le premier coup d’œil rapide
igraph fournit une méthode plot() en R de base, si bien qu’une seule ligne donne un premier aperçu. Les valeurs par défaut sont sobres, mais c’est le moyen le plus rapide de vérifier que les données se sont bien assemblées :
set.seed(123)
plot(g, layout = layout_with_fr,
vertex.color = "#3a86d4", vertex.frame.color = "white",
vertex.label.color = "black", vertex.label.family = "sans",
edge.color = "grey75")
Deux regroupements sont déjà visibles — les personnes de l’équipe Design d’un côté, celles de l’équipe Data de l’autre, avec quelques membres qui font le pont. Une habitude essentielle : set.seed() avant de tracer. La plupart des dispositions sont aléatoires, donc sans graine fixe le même graphe aboutit à un agencement différent à chaque exécution ; la graine rend la figure reproductible.
Changer l’agencement avec les dispositions
Une disposition est l’algorithme qui décide où chaque nœud se place — elle ne change rien aux données, seulement leur façon d’être dessinées. igraph en propose une douzaine ; trois couvrent la plupart des besoins :
layout_with_fr(Fruchterman–Reingold) — une disposition dirigée par les forces : elle traite les arêtes comme des ressorts, de sorte que les nœuds connectés s’attirent et que tout le reste se repousse. C’est le choix par défaut sensé, car les regroupements émergent naturellement. (layout_with_kk, Kamada–Kawai, est un modèle à ressorts similaire, souvent plus net sur les petits graphes.)layout_in_circle— chaque nœud sur un anneau, dans l’ordre d’entrée. Neutre et épuré ; utile pour comparer les motifs d’arêtes sans que la disposition « prenne parti ».layout_on_grid,layout_as_star,layout_as_tree— des agencements réguliers pour les grilles, les structures en étoile et les hiérarchies.
Voici la disposition en cercle sur le même graphe — mêmes nœuds, mêmes arêtes, géométrie différente :
set.seed(123)
plot(g, layout = layout_in_circle,
vertex.color = "#3a86d4", vertex.frame.color = "white",
vertex.label.color = "black", vertex.label.family = "sans",
edge.color = "grey75")
La règle empirique : optez pour fr/kk quand vous voulez voir la structure (qui se regroupe avec qui), et pour un cercle/une grille quand vous voulez une référence neutre qui n’en impose aucune.
Styliser avec du sens : degré et communauté
Une bonne figure de réseau encode l’information dans les marques, pas seulement dans les positions. Deux encodages font le gros du travail.
Dimensionner les nœuds selon le degré. Le degré d’un nœud — le nombre d’arêtes qui le touchent — se calcule avec degree(). Le faire correspondre à la taille des nœuds rend les personnes bien connectées littéralement plus grandes :
deg <- degree(g)
degAlice Bob Carol Dan Eve Frank Grace Heidi Ivan
3 3 4 5 5 3 4 3 4
Dan et Eve sont en tête avec 5 — ce sont les collaborateurs les plus actifs. (Le degré est la mesure de centralité la plus simple — une famille de scores mesurant « quelle est l’importance de ce nœud ». Un cousin utile est betweenness(), qui compte combien de fois un nœud se trouve sur le plus court chemin entre d’autres ; il repère les ponts — ici Dan, Eve et Ivan — les personnes qui maintiennent ensemble des groupes autrement séparés.)
Colorer les nœuds par communauté. Un algorithme de détection de communautés partitionne le graphe en groupes densément connectés. cluster_louvain() est un choix rapide et standard : il maximise la modularité — un score allant d’environ −0.5 à 1 qui mesure combien il y a davantage de liens intra-groupe que ce qu’on attendrait par hasard (plus il est élevé, plus la partition est nette) :
set.seed(123)
comm <- cluster_louvain(g)
commIGRAPH clustering multi level, groups: 2, mod: 0.32
+ groups:
$`1`
[1] "Alice" "Bob" "Carol" "Dan" "Ivan"
$`2`
[1] "Eve" "Frank" "Grace" "Heidi"
modularity(comm)[1] 0.316609
Il trouve deux communautés avec une modularité d’environ 0.32 — une partition solide qui retrouve les équipes Design et Data à partir de la seule structure des liens, sans jamais regarder la colonne team (Ivan, l’unique membre Ops, est affecté à la communauté qui maximise la modularité — ici le côté Design, auquel il est aussi étroitement lié qu’au côté Data). Mettez maintenant les deux encodages sur un même graphique : taille selon le degré, couleur selon la communauté, et largeur des arêtes selon le poids projects :
V(g)$community <- membership(comm)
palette <- c("#3a86d4", "#e4572e") # azure, orange
set.seed(123)
plot(g,
layout = layout_with_fr,
vertex.size = degree(g) * 4 + 8, # size ~ degree
vertex.color = palette[V(g)$community], # colour ~ community
vertex.frame.color = "white",
vertex.label.color = "black", vertex.label.family = "sans",
edge.width = E(g)$projects * 0.6, # width ~ weight
edge.color = "grey75")
legend("bottomleft", legend = c("Community 1", "Community 2"),
col = palette, pch = 19, bty = "n")
Maintenant la figure dit quelque chose : les deux équipes sont en aplats de couleur, les plus gros nœuds sont les personnes les plus actives, et les arêtes les plus épaisses sont les relations de travail les plus fortes. C’est tout l’intérêt de styliser par les données plutôt que par la décoration.
La voie ggraph — qualité publication
igraph::plot() est parfait pour un coup d’œil rapide, mais pour une figure assortie au reste d’un rapport ggplot2, tournez-vous vers ggraph, le moteur de grammaire des graphiques pour les réseaux, associé à tidygraph, qui représente le graphe sous forme de deux tables bien rangées (nœuds et arêtes) que vous pouvez mutate().
Le flux de travail reflète ggplot2 : convertir le graphe, calculer les colonnes de nœuds avec les verbes tidygraph (centrality_degree(), group_louvain()), puis construire le graphique à partir des géométries d’arête et de nœud. geom_edge_link() dessine les arêtes, geom_node_point() les nœuds, et geom_node_text(repel = TRUE) les étiquettes sans chevauchement :
library(tidygraph)
library(ggraph)
tg <- as_tbl_graph(g) |>
mutate(degree = centrality_degree(),
community = as.factor(group_louvain()))
set.seed(123)
ggraph(tg, layout = "fr") +
geom_edge_link(aes(width = projects), colour = "grey75", alpha = 0.6) +
geom_node_point(aes(size = degree, colour = community)) +
geom_node_text(aes(label = name), repel = TRUE, size = 3.3) +
scale_edge_width(range = c(0.3, 2)) +
scale_size(range = c(3, 9)) +
scale_colour_manual(values = c("#3a86d4", "#e4572e")) +
labs(edge_width = "Projects", size = "Degree", colour = "Community") +
theme_graph(base_family = "sans")
Même information que le graphique en R de base, mais désormais chaque canal est une véritable échelle ggplot2 avec une légende, theme_graph() donne l’allure épurée propre aux réseaux, et vous pouvez superposer, facetter et enregistrer le tout exactement comme n’importe quel autre ggplot. Pour une figure statique destinée à la publication, c’est la voie à privilégier.
Analyser et manipuler avec tidygraph
Dessiner n’est que la moitié du travail ; l’autre moitié consiste à poser des questions au graphe — qui est central, quels nœuds forment des groupes, que se passe-t-il si je modifie le réseau. C’est là que tidygraph prend tout son sens : il représente le graphe sous forme de deux tables bien rangées (une pour les nœuds, une pour les arêtes) et vous laisse travailler chacune avec les verbes dplyr que vous connaissez déjà. Convertissez l’objet igraph que nous avons construit avec as_tbl_graph() — ou construisez-en un directement à partir de deux data frames avec tbl_graph(nodes = , edges = ) ; as_tbl_graph() convertit aussi d’autres objets (une matrix d’adjacence, des objets igraph/network, et des arbres hclust/dendrogram, entre autres) :
library(tidygraph)
library(dplyr)
tg <- as_tbl_graph(g)
tg# A tbl_graph: 9 nodes and 17 edges
#
# An undirected simple graph with 1 component
#
# Node Data: 9 × 3 (active)
name team community
<chr> <chr> <membrshp>
1 Alice Design 1
2 Bob Design 1
3 Carol Design 1
4 Dan Design 1
5 Eve Data 2
6 Frank Data 2
7 Grace Data 2
8 Heidi Data 2
9 Ivan Ops 1
#
# Edge Data: 17 × 3
from to projects
<int> <int> <dbl>
1 1 2 5
2 1 3 4
3 1 4 3
# ℹ 14 more rows
L’affichage montre les deux tables et marque l’une comme active (« Node Data (active) »). C’est la table active que les verbes suivants modifient — voilà toute l’idée du flux de travail tidygraph.
Manipuler les nœuds et les arêtes
activate() change la table active ; ensuite mutate(), rename(), arrange() et filter() se comportent exactement comme sur un data frame. Ici, nous ajoutons une colonne de degré aux nœuds, puis passons aux arêtes pour renommer le poids et trier les liens les plus forts en premier :
tg <- tg |>
activate(nodes) |>
mutate(degree = centrality_degree()) |> # add a node column
activate(edges) |>
rename(weight = projects) |> # projects -> weight
arrange(desc(weight)) # strongest ties first
tg# A tbl_graph: 9 nodes and 17 edges
#
# An undirected simple graph with 1 component
#
# Edge Data: 17 × 3 (active)
from to weight
<int> <int> <dbl>
1 1 2 5
2 3 4 5
3 5 6 5
4 6 7 5
5 1 3 4
6 2 3 4
7 5 7 4
8 7 8 4
9 1 4 3
10 5 8 3
11 6 8 3
12 5 9 3
13 2 4 2
14 3 9 2
15 4 9 2
16 7 9 2
17 4 5 2
#
# Node Data: 9 × 4
name team community degree
<chr> <chr> <membrshp> <dbl>
1 Alice Design 1 3
2 Bob Design 1 3
3 Carol Design 1 4
# ℹ 6 more rows
Un comportement à retenir : filtrer la table des nœuds supprime aussi chaque arête qui touchait un nœud retiré, de sorte que activate(nodes) |> filter(...) laisse toujours un sous-graphe cohérent — vous ne vous retrouvez jamais avec une arête pointant vers un nœud que vous avez supprimé.
La détection de communautés, plus d’algorithmes
cluster_louvain() plus haut était un algorithme de détection de communautés ; tidygraph expose une famille group_* qui vous permet de comparer côte à côte les partitions du même graphe :
set.seed(123)
tg |>
activate(nodes) |>
mutate(
louvain = group_louvain(),
infomap = group_infomap(),
edge_between = group_edge_betweenness()
) |>
as_tibble() |>
select(name, louvain, infomap, edge_between)# A tibble: 9 × 4
name louvain infomap edge_between
<chr> <int> <int> <int>
1 Alice 1 1 1
2 Bob 1 1 1
3 Carol 1 1 1
4 Dan 1 1 1
5 Eve 2 1 2
6 Frank 2 1 2
7 Grace 2 1 2
8 Heidi 2 1 2
9 Ivan 1 1 1
Des algorithmes différents peuvent partitionner le même graphe différemment. Ici, group_louvain() et group_edge_betweenness() s’accordent sur la même partition en deux, tandis que group_infomap() — qui minimise la longueur de description d’une marche aléatoire — trouve trop peu de signal sur un graphe de cette petite taille et ne rapporte qu’une seule communauté. Quand plusieurs algorithmes s’accordent, vous pouvez faire confiance à la partition ; quand ils divergent (comme infomap ici), la structure de communautés mérite un examen plus attentif. Essayez-en quelques-uns et gardez la partition qui correspond le mieux à ce que vous savez déjà des données.
Le rendre interactif
Une figure statique est idéale pour un article ou une diapositive. Pour l’exploration — survoler pour lire les étiquettes, écarter les nœuds en les glissant, zoomer dans un regroupement dense — vous voulez un widget interactif. Deux paquets dominent, et tous deux consomment les mêmes data frames de nœuds/arêtes que vous avez déjà.
visNetwork enveloppe la bibliothèque vis.js et est le plus accessible. Il attend un data frame de nœuds avec une colonne id et un data frame d’arêtes avec from/to ; une colonne group colore les nœuds et les met en légende automatiquement, et une colonne value sur les arêtes ajuste leur largeur. visIgraphLayout() réutilise n’importe quelle disposition igraph, de sorte que l’image interactive correspond à votre image statique :
library(visNetwork)
vis_nodes <- data.frame(id = nodes$name, label = nodes$name, group = nodes$team)
vis_edges <- data.frame(from = edges$from, to = edges$to, value = edges$projects)
visNetwork(vis_nodes, vis_edges, width = "100%") |>
visIgraphLayout(layout = "layout_with_fr") |>
visEdges(color = list(color = "grey")) |>
visOptions(highlightNearest = TRUE, nodesIdSelection = TRUE)Sortie : un graphe vivant que vous pouvez glisser et zoomer, avec les neuf personnes colorées par équipe ; highlightNearest = TRUE estompe tout sauf un nœud et ses voisins quand vous cliquez dessus, et la liste déroulante (nodesIdSelection) saute vers n’importe quelle personne — idéal pour décortiquer un réseau chargé.
networkD3 effectue le rendu avec D3.js et donne le familier graphe rebondissant dirigé par les forces. Son seul piège : forceNetwork() indexe les liens par position, et le décompte commence à 0, vous convertissez donc vos noms en identifiants entiers avec match(...) - 1 :
library(networkD3)
# forceNetwork needs 0-based integer ids for Source/Target
d3_links <- data.frame(
source = match(edges$from, nodes$name) - 1,
target = match(edges$to, nodes$name) - 1,
value = edges$projects
)
d3_nodes <- data.frame(name = nodes$name, group = nodes$team,
size = degree(g))
forceNetwork(Links = d3_links, Nodes = d3_nodes,
Source = "source", Target = "target", Value = "value",
NodeID = "name", Group = "group", Nodesize = "size",
zoom = TRUE, opacity = 0.9, fontSize = 14)Sortie : un graphe D3 dirigé par les forces où les nœuds dérivent vers leurs regroupements, sont colorés par équipe et dimensionnés selon le degré, et peuvent être glissés et zoomés. Oubliez le - 1 et vous tracerez silencieusement le mauvais graphe (ou obtiendrez une erreur de dépassement de plage) — l’erreur networkD3 la plus courante.
Tous deux sont des htmlwidgets : ils sont interactifs en HTML, dans le Viewer de RStudio et dans Shiny, et se dégradent en une capture statique dans un PDF ou un article. Choisissez visNetwork pour l’interaction intégrée la plus riche, networkD3 pour l’allure D3 classique.
Quelle fonction pour quelle tâche
Une carte rapide des paquets et des fonctions qui portent ce flux de travail :
| Tâche | Paquet · fonction | Notes |
|---|---|---|
| Construire un graphe à partir d’un data frame d’arêtes/nœuds | igraph::graph_from_data_frame() |
les deux premières colonnes = les extrémités ; directed= fixe le type |
| Un graphique statique rapide | igraph::plot() |
méthode en R de base ; définissez un layout_* et set.seed() |
| Choisir un agencement | layout_with_fr · layout_with_kk · layout_in_circle |
dirigé par les forces pour la structure ; cercle/grille pour une vue neutre |
| Évaluer l’importance d’un nœud | degree() · betweenness() |
degré = connexions ; intermédiarité = ponts |
| Le menu complet de la centralité | tidygraph::centrality_*() |
centrality_closeness/pagerank/eigen/hub/authority() — plus de dix mesures |
| Manipuler nœuds/arêtes | tidygraph::activate() + verbes dplyr |
mutate()/rename()/filter()/arrange() sur la table active |
| Détecter les communautés | cluster_louvain() · modularity() · group_infomap() |
maximise la modularité ; aussi group_edge_betweenness(), cluster_walktrap() |
| Figure statique en qualité publication | tidygraph + ggraph |
geom_node_point() / geom_edge_link() / theme_graph() |
| Interactif (glisser + zoomer) | visNetwork · networkD3 |
htmlwidgets ; mêmes data frames de nœuds/arêtes |
Quand un graphe de réseau — et quand non
Un diagramme nœud–lien est le bon outil quand les relations sont l’histoire et que le graphe est de petite à moyenne taille (jusqu’à quelques centaines de nœuds). Au-delà, il devient une « pelote de laine », et une heatmap de matrice d’adjacence ou une vue agrégée se lit mieux. Et si votre « réseau » est en réalité une matrice de corrélation — les variables comme nœuds, les corrélations comme arêtes — vous n’avez pas du tout besoin de construire un graphe à la main ; le paquet corrr le dessine en deux lignes, ce que couvre l’article jumeau Graphe de réseau de corrélation en R. Cet article est la recette générale ; celui-là est le raccourci spécifique à la corrélation.
Foire aux questions
Placez vos connexions dans un data frame avec une colonne from et une colonne to (plus d’éventuels attributs d’arête comme un poids), puis appelez igraph::graph_from_data_frame(edges, vertices = nodes, directed = FALSE). Les deux premières colonnes sont lues comme les extrémités des arêtes, les colonnes restantes deviennent des attributs d’arête, et le data frame vertices optionnel attache les attributs de nœud en mettant en correspondance sa première colonne. Le résultat est un objet graphe que vous tracez avec plot() ou ggraph().
Le degré d’un nœud est le nombre d’arêtes qui lui sont connectées — une mesure simple de l’activité ou de la bonne connexion d’une entité. Calculez-le avec degree(g) sur un objet igraph ; faites-le correspondre à la taille des nœuds (vertex.size = degree(g)) pour que les nœuds les plus connectés soient dessinés les plus grands. Pour une mesure de « pont » qui repère les nœuds maintenant ensemble des groupes séparés, utilisez plutôt betweenness(g).
Exécutez un algorithme de détection de communautés comme cluster_louvain(g), qui partitionne le graphe en groupes densément connectés en maximisant la modularité. Récupérez membership(comm) pour obtenir le numéro de groupe de chaque nœud et servez-vous-en pour définir la couleur — vertex.color = palette[membership(comm)] en igraph de base, ou mutate(community = as.factor(group_louvain())) puis aes(colour = community) dans ggraph. modularity(comm) indique à quel point la partition est nette.
Utilisez le plot() intégré d’igraph pour un coup d’œil rapide et pour toute l’analyse (degré, centralité, communautés). Utilisez ggraph (avec tidygraph) quand vous voulez une figure en qualité publication assortie à un rapport ggplot2 — de véritables échelles, des légendes, des thèmes, du facettage et des couches. Ils sont complémentaires : igraph fait les mathématiques du graphe, ggraph fait le dessin soigné, et tous deux acceptent le même objet graphe.
Convertissez le graphe avec as_tbl_graph() (ou construisez-le avec tbl_graph(nodes =, edges =)), qui le stocke sous forme de deux tables bien rangées — nœuds et arêtes. Utilisez activate(nodes) ou activate(edges) pour choisir la table sur laquelle vous travaillez, puis modifiez-la avec les verbes dplyr habituels : mutate() pour ajouter des colonnes, rename(), arrange() et filter() (filtrer les nœuds supprime aussi leurs arêtes incidentes). Pour l’analyse, appliquez mutate() à la table des nœuds avec le menu centrality_* — centrality_degree(), centrality_betweenness(), centrality_closeness(), centrality_pagerank(), centrality_eigen() — et détectez des groupes avec la famille group_* (group_louvain(), group_infomap(), group_edge_betweenness()).
Choisissez celle qui correspond à votre question. Le degré (centrality_degree()) compte les connexions directes — un score d’activité rapide. L’intermédiarité (centrality_betweenness()) repère les ponts situés sur les plus courts chemins entre les autres — retirez-les et le réseau se fragmente. La proximité (centrality_closeness()) récompense les nœuds capables d’atteindre tout le monde en peu d’étapes. Le PageRank et le vecteur propre (centrality_pagerank(), centrality_eigen()) récompensent le fait d’être lié par d’autres nœuds importants, et pas seulement d’avoir beaucoup de liens. Dans le doute, calculez-en plusieurs et comparez les classements.
Utilisez visNetwork ou networkD3. Donnez à visNetwork(nodes, edges) un data frame de nœuds avec une colonne id et un data frame d’arêtes avec from/to, et vous obtenez un widget que l’on peut glisser et zoomer (ajoutez visIgraphLayout() pour réutiliser une disposition igraph). networkD3::forceNetwork() donne le graphe de forces D3 classique mais nécessite des identifiants entiers commençant à 0, convertissez donc les noms avec match(...) - 1. Tous deux sont des htmlwidgets, donc ils sont interactifs en HTML et Shiny et se rabattent sur une image statique dans un PDF.
Pour aller plus loin
- Graphe de réseau de corrélation en R — le cas particulier de la matrice de corrélation, en deux lignes avec
corrr. · ggplot2 en R — la grammaire des graphiques qu’étendggraph. · Visualisation de données.

Demandez à Prova « transforme mon data frame de liste d’arêtes en réseau igraph, colore-le par communauté, et donne-moi le code ggraph » — collez vos propres données et elle répond avec du code que vous pouvez exécuter. The runtime is the judge. Demander à Prova →
Citation
@online{kassambara2026,
author = {Kassambara, Alboukadel},
title = {Visualisation et analyse de réseaux en R},
date = {2026-07-14},
url = {https://www.datanovia.com/blog/network-visualization-in-r},
langid = {fr}
}