Analyse d’enrichissement de jeux de gènes et de voies en R avec clusterProfiler
Transformez une liste de gènes différentiellement exprimés en les voies biologiques qui la sous-tendent — analyse de surreprésentation et GSEA, interprétées et visualisées
Un guide pratique de l’analyse d’enrichissement fonctionnel en R avec clusterProfiler. Partez d’un résultat d’expression différentielle DESeq2 et retrouvez les voies biologiques qui le sous-tendent de deux façons : l’analyse de surreprésentation (ORA) sur votre liste restreinte de gènes significatifs avec enrichGO, et l’analyse d’enrichissement de jeux de gènes (GSEA) sur la liste de gènes classée complète avec gseGO. Comprenez quand utiliser l’une ou l’autre, lisez le GeneRatio, le NES et les p-value ajustées en langage clair, et visualisez le résultat avec des diagrammes à points et le graphique du score cumulé GSEA. Sur le jeu de données airway.
Date de publication
29 juin 2026
Modifié
7 juillet 2026
AstucePoints clés
Après l’expression différentielle, vous avez des centaines de gènes — bien trop pour les lire un par un. L’analyse d’enrichissement pose une meilleure question : quelles voies biologiques se sont déplacées en groupe ?
Deux méthodes complémentaires. L’ORA (analyse de surreprésentation) teste si votre liste restreinte de gènes significatifs est anormalement riche en gènes d’une voie. La GSEA (analyse d’enrichissement de jeux de gènes) utilise tous les gènes, classés, et demande si les gènes d’une voie se regroupent en haut ou en bas.
L’ORA a besoin d’un seuil (votre liste padj < 0.05) et ne donne aucune direction ; la GSEA n’a besoin d’aucun seuil et donne un score signé (NES) — à la hausse ou à la baisse. L’accord entre elles rend un résultat convaincant.
clusterProfiler exécute les deux sur de nombreuses bases de données. Cette leçon couvre GO Biological Process, MSigDB Hallmark et Reactome — toutes à partir d’annotations locales, si bien que toute l’analyse est reproductible hors ligne (KEGG est la seule exception — il lui faut une API web).
Lisez GeneRatio + p.adjust pour l’ORA, NES (signe = direction) + p.adjust pour la GSEA, et visualisez avec un diagramme à points et le graphique du score cumulé GSEA.
Introduction
L’expression différentielle (la leçon DESeq2) vous laisse avec une longue liste de gènes significatifs. La parcourir gène par gène est sans espoir et passe à côté de l’essentiel : la biologie se joue dans les voies, pas dans les gènes isolés. L’analyse d’enrichissement transforme la liste de gènes en une liste bien plus courte de programmes biologiques — réponse immunitaire, cycle cellulaire, organisation de la matrice extracellulaire — qui se sont déplacés ensemble.
Il existe deux stratégies standard, qui répondent à des questions légèrement différentes, d’où l’intérêt d’exécuter les deux. Ce guide utilise clusterProfiler, la boîte à outils R standard pour les deux, sur les gènes différentiellement exprimés de l’expérience airway (cellules musculaires lisses des voies respiratoires traitées à la dexaméthasone vs non traitées).
Partir d’un résultat DESeq2
L’enrichissement prend un résultat d’expression différentielle en entrée. Nous le reconstruisons ici pour que la leçon soit autonome — c’est le même flux de travail que la leçon DESeq2, condensé.
sum(res$padj <0.05, na.rm =TRUE) # significant at 5% FDR
[1] 4000
Environ quatre mille gènes sont significatifs — bien trop pour les interpréter directement. C’est exactement à cela que sert l’analyse d’enrichissement.
ORA vs GSEA — deux façons de poser la question
Les deux méthodes prennent des entrées différentes et répondent à des questions différentes. Exécutez les deux : l’accord entre elles (et entre les bases de données) est ce qui rend un résultat d’enrichissement fiable.
ORA (surreprésentation)
GSEA (enrichissement de jeux de gènes)
Entrée
votre liste restreinte de gènes significatifs (une liste oui/non)
tous les gènes, classés selon une statistique
Question
Une voie est-elle surreprésentée dans ma liste de hits, plus que par hasard ?
Les gènes d’une voie se regroupent-ils en haut ou en bas du classement ?
Seuil
en a besoin d’un (filtre padj / fold-change)
aucun — utilise chaque gène
Direction
non (juste « enrichi »)
oui — un score signé (à la hausse ou à la baisse)
Optimal pour
une liste de hits forte et nette
des déplacements faibles mais coordonnés de nombreux gènes ensemble
En bref : l’ORA demande « cette voie est-elle dans ma liste de hits ? » ; la GSEA demande « cette voie se déplace-t-elle de façon cohérente sur toute l’expérience, même à travers de nombreux petits changements ? »
NoteComment elles se calculent (maths optionnelles)
L’ORA utilise un test hypergéométrique (équivalent au test exact de Fisher). Avec un univers de \(N\) gènes, \(K\) dans la voie, \(n\) gènes dans votre liste restreinte et \(k\) de ceux-ci dans la voie, la p-value est la probabilité de voir au moins\(k\) chevauchements par hasard : \[P(X \ge k) = \sum_{i=k}^{\min(n,K)} \frac{\binom{K}{i}\binom{N-K}{n-i}}{\binom{N}{n}}\]
La GSEA parcourt la liste de gènes classée en tenant un score d’enrichissement cumulé : il monte à chaque membre de la voie (pondéré par la métrique de classement du gène) et descend à chaque non-membre. Le score d’enrichissement (ES) est l’écart maximal de ce score cumulé par rapport à zéro ; le NES le normalise selon la taille du jeu de gènes pour que les jeux soient comparables, et son signe donne la direction. La significativité provient de la permutation des étiquettes de gènes un grand nombre de fois. Les deux méthodes appliquent ensuite la correction de Benjamini–Hochberg sur tous les jeux de gènes testés.
Analyse de surreprésentation (ORA)
L’ORA teste votre liste restreinte de gènes significatifs pour chaque terme GO. Deux entrées : la liste de gènes (gènes significatifs) et l’univers (tous les gènes que vous avez testés) — l’univers compte, car « enrichi » signifie « plus qu’attendu compte tenu de ce qui aurait pu être détecté ».
Description GeneRatio p.adjust
GO:0001525 angiogenesis 197/3382 8.126049e-13
GO:0030198 extracellular matrix organization 130/3382 1.869361e-10
GO:0043062 extracellular structure organization 130/3382 1.869361e-10
GO:0045229 external encapsulating structure organization 130/3382 1.927672e-10
GO:0003013 circulatory system process 191/3382 3.447507e-10
GO:0003012 muscle system process 148/3382 7.136804e-10
GO:0030335 positive regulation of cell migration 188/3382 1.325191e-09
GO:2000147 positive regulation of cell motility 192/3382 3.042036e-09
Lisez le résultat : GeneRatio est la fraction de vos gènes significatifs annotés qui tombent dans le terme ; p.adjust est sa significativité corrigée par FDR. Les termes enrichis sont des programmes de remodelage tissulaire et vasculaires — angiogenèse, motilité et migration cellulaires, processus des systèmes circulatoire et musculaire, et organisation de la matrice extracellulaire — une biologie cohérente pour du muscle lisse des voies respiratoires traité aux glucocorticoïdes, pas une liste aléatoire. Cette cohérence est le contrôle de bon sens.
Visualiser l’ORA — le diagramme à points
Le diagramme à points est la figure d’enrichissement standard : une ligne par terme, le ratio de gènes en abscisse, la taille des points = le nombre de gènes, la couleur = la p-value ajustée.
library(enrichplot)dotplot(ego, showCategory =12) + ggplot2::ggtitle("ORA — GO biological process")
Le diagramme à points montre quels termes sont enrichis ; un réseau gènes-concepts montre les gènes qui les sous-tendent et quels termes ils partagent — utile pour repérer une poignée de gènes qui pilotent plusieurs voies à la fois.
cnetplot(ego, showCategory =5)
Analyse d’enrichissement de jeux de gènes (GSEA)
La GSEA n’a besoin d’aucun seuil. Au lieu d’une liste restreinte, vous lui donnez chaque gène, classé selon une statistique — ici la statistique de Wald stat de DESeq2, qui porte à la fois la direction et l’intensité du changement. La GSEA demande alors si les gènes de chaque voie dérivent vers le haut (à la hausse) ou le bas (à la baisse) de ce classement.
Description NES
GO:0046324 regulation of D-glucose import 2.217309
GO:0046323 D-glucose import 2.208967
GO:0031069 hair follicle morphogenesis -2.179956
GO:0048730 epidermis morphogenesis -2.166981
GO:0010827 regulation of D-glucose transmembrane transport 2.103370
GO:1904659 D-glucose transmembrane transport 2.099115
GO:0008645 hexose transmembrane transport 2.083159
GO:0003382 epithelial cell morphogenesis 2.066909
p.adjust
GO:0046324 0.0005099558
GO:0046323 0.0001763789
GO:0031069 0.0010133368
GO:0048730 0.0012759375
GO:0010827 0.0009633465
GO:1904659 0.0006022138
GO:0008645 0.0005099558
GO:0003382 0.0033167697
Lisez le NES (score d’enrichissement normalisé) : sa magnitude est l’intensité, son signe la direction — positif = à la hausse dans les cellules traitées, négatif = à la baisse. Les mouvements les plus forts sont des programmes métaboliques et de transport qui évoluent à la hausse (import/transport du glucose) face à des programmes de morphogenèse épidermique et des follicules pileux qui évoluent à la baisse — une image signée et cohérente que l’ORA fondée sur un seuil ne peut pas vous donner.
Visualiser la GSEA — le graphique du score cumulé
La figure emblématique de la GSEA montre le score d’enrichissement cumulé au fur et à mesure que vous descendez la liste classée, avec les gènes de la voie marqués par des traits. Un pic près du sommet = une voie enrichie parmi les gènes surexprimés.
top_id <- gdf$ID[which.max(gdf$NES)] # the most up-regulated setgseaplot2(gse, geneSetID = top_id, title = gdf$Description[gdf$ID == top_id])
Au-delà de GO — les collections Hallmark et Reactome
GO est un vocabulaire, rarement le seul que vous voulez. Deux collections soigneusement constituées offrent des vues complémentaires de la même liste classée, et toutes deux s’exécutent à partir de packages d’annotation locaux — sans API web — ce qui les garde reproductibles :
MSigDB Hallmark — 50 jeux de gènes délibérément grossiers, chacun un programme biologique bien défini : la vue « ce qui a bougé, à grands traits ».
Reactome — des milliers de voies détaillées aux noms cliniques (cascades de signalisation, métabolisme) : la vue « nommez-le comme le ferait un biologiste ».
Exécuter la GSEA sur ces collections repose sur la même machinerie de liste classée que gseGO — seule la source du jeu de gènes change.
Voies Hallmark (GSEA)
Les jeux Hallmark sont indexés par symbole de gène, donc nous réétiquetons la liste classée des identifiants Ensembl vers les symboles, puis nous la passons à la fonction générique GSEA() avec Hallmark comme table de jeux de gènes.
Une trentaine de jeux Hallmark passent FDR < 0.25. Les mouvements les plus forts et les plus significatifs sont des programmes métaboliques et de signalisation qui montent — HALLMARK_ADIPOGENESIS, HALLMARK_TNFA_SIGNALING_VIA_NFKB, HALLMARK_ANDROGEN_RESPONSE, HALLMARK_OXIDATIVE_PHOSPHORYLATION — aux côtés de HALLMARK_P53_PATHWAY qui descend à la baisse (NES négatif). Cela colle à la biologie : la dexaméthasone est un glucocorticoïde, et un aperçu grossier de 50 jeux devrait faire ressortir exactement ces signatures métaboliques et anti-inflammatoires.
Un diagramme à points montre le même résultat d’un coup d’œil, réparti par direction :
Le diagramme à points répartit les jeux par direction — activés (NES positif, à la hausse dans les cellules traitées) d’un côté, réprimés de l’autre — avec la taille des points donnant le nombre de gènes du leading edge et la couleur la p-value ajustée. Lire les deux panneaux côte à côte est la façon la plus rapide de voir quels programmes sont montés et lesquels sont descendus.
Voies Reactome (GSEA)
Reactome est indexé par identifiants Entrez, donc nous réétiquetons la liste classée une fois de plus, puis nous exécutons la GSEA sur les voies Reactome avec gsePathway().
Les voies de Reactome sont plus fines, donc il renvoie bien plus de hits — ici près de deux cents à FDR < 0.25. Les voies de tête sont cliniquement lisibles et biologiquement pertinentes pour les cellules musculaires lisses des voies respiratoires : contraction musculaire et des muscles lisses, transduction du signal et dégranulation des neutrophiles qui montent, face à l’aminoacylation cytosolique des ARNt qui descend. C’est le niveau de détail que vous citeriez dans les résultats d’un article.
Le même diagramme à points réparti, maintenant sur les voies Reactome — activées versus réprimées, côte à côte :
Une collection grossière peut placer un programme sans rapport près du sommet par hasard, et aucune voie unique n’est jamais toute l’histoire. Faites confiance au résultat qui apparaît de façon constante — à travers GO, Hallmark et Reactome, et dans la direction que prédit la biologie. Trois vocabulaires qui s’accordent, voilà ce qui rend un résultat d’enrichissement convaincant.
Problèmes fréquents
L’ORA ne trouve rien, la GSEA trouve beaucoup (ou inversement). Elles répondent à des questions différentes, donc c’est normal. L’ORA a besoin d’une liste restreinte forte et nette ; la GSEA détecte des déplacements faibles mais coordonnés qui ne passent jamais un seuil par gène. Le désaccord est une information, pas un bug — rapportez les deux.
« No gene can be mapped » / résultat vide. Le keyType doit correspondre à vos identifiants de gènes. airway utilise des identifiants Ensembl, donc keyType = "ENSEMBL". Si vos gènes sont des symboles, utilisez "SYMBOL", s’ils sont Entrez utilisez "ENTREZID" — ou convertissez d’abord avec bitr().
Vous avez oublié l’univers dans l’ORA. Sans universe = (tous les gènes testés), enrichGO compare votre liste au génome entier, gonflant la significativité. Passez toujours les gènes qui auraient pu être détectés dans votre expérience.
Questions fréquentes
NoteQuelle est la différence entre l’ORA et la GSEA ?
L’ORA teste une liste restreinte de gènes significatifs (un seuil oui/non) pour la surreprésentation d’une voie à l’aide d’un test hypergéométrique — sans direction. La GSEA utilise tous les gènes classés selon une statistique et demande si une voie se regroupe en haut ou en bas, donnant un NES signé (à la hausse ou à la baisse) et sans besoin d’un seuil. Utilisez les deux ; l’accord est convaincant.
NoteComment faire une analyse de voies KEGG en R ?
Cette leçon exécute déjà Reactome (gsePathway) et MSigDB Hallmark (GSEA + msigdbr) ci-dessus — tous deux à partir d’annotations locales, entièrement hors ligne. KEGG suit le même flux de travail (enrichKEGG() / gseKEGG()) avec un hic : les fonctions KEGG ont besoin d’identifiants Entrez (convertissez avec bitr()) et interrogent l’API web KEGG au moment de l’exécution, donc elles nécessitent une connexion internet — ce qui explique pourquoi cette leçon reproductible hors ligne n’exécute pas de cellule KEGG en direct. Pour l’ORA sur une liste restreinte, ReactomePA::enrichPathway() est l’équivalent de surreprésentation de la GSEA gsePathway() montrée ci-dessus.
NoteQuel type d’identifiant de gène dois-je utiliser ?
Faites correspondre keyType à vos données. DESeq2 sur airway donne des identifiants Ensembl (keyType = "ENSEMBL"). De nombreux outils attendent des identifiants Entrez (KEGG, MSigDB), et les gens lisent les symboles. Convertissez entre eux avec clusterProfiler::bitr() ou AnnotationDbi::mapIds(), et définissez readable = TRUE pour que les résultats montrent les symboles.
NoteQue signifie le NES (score d’enrichissement normalisé) ?
C’est le score d’enrichissement GSEA normalisé selon la taille du jeu de gènes pour que les jeux soient comparables. Sa magnitude est l’intensité de l’enrichissement ; son signe est la direction — positif signifie que la voie est enrichie parmi les gènes surexprimés, négatif parmi les sous-exprimés. Filtrez sur p.adjust < 0.05, puis classez par NES.
NoteDois-je fixer une graine aléatoire pour la GSEA ?
Oui. La GSEA estime la significativité par permutation, donc les résultats varient légèrement d’une exécution à l’autre. Appelez set.seed() avant gseGO()/GSEA() pour un résultat reproductible — sinon les p-value (et parfois les termes limites) changent entre les exécutions.
Testez vos connaissances
ImportantÀ votre tour : exécutez l’ORA séparément sur les gènes surexprimés et sous-exprimés
L’ORA sur toute la liste significative mélange gènes induits et réprimés. Séparez-les : exécutez enrichGO sur les gènes avec log2FoldChange > 0 puis de nouveau sur ceux avec log2FoldChange < 0, et comparez les termes de tête. Quels programmes biologiques sont induits par la dexaméthasone versus réprimés ?
AstuceIndice
Construisez deux vecteurs de gènes à partir de res — rownames(subset(res, padj < 0.05 & log2FoldChange > 0)) et la version < 0 — et appelez enrichGO sur chacun, en gardant le même universe.
Séparer par direction est souvent plus informatif qu’une seule liste combinée — cela vous dit ce qui est monté à la hausse versus à la baisse, ce qui est exactement la direction que la GSEA vous donne gratuitement.
NoteVérification rapide : quelle méthode nécessite un seuil de signification ?
A. La GSEA — elle ne regarde que les gènes significatifs. B. L’ORA — elle teste une liste restreinte définie par un seuil padj/fold-change. C. Aucune — les deux utilisent tous les gènes.
AstuceAfficher la réponse
B. L’ORA teste une liste restreinte que vous définissez avec un seuil (p. ex. padj < 0.05). La GSEA utilise la liste de gènes classée complète et n’a besoin d’aucun seuil — c’est son principal avantage pour détecter de petits déplacements coordonnés.
Conclusion
Vous avez transformé un résultat d’expression différentielle de quatre mille gènes en une courte liste de voies biologiques, de deux façons complémentaires : l’ORA (enrichGO) a testé la liste restreinte de gènes significatifs et fait ressortir les programmes de matrice extracellulaire, d’angiogenèse et musculaires ; la GSEA (gseGO) a utilisé la liste classée complète pour donner une image signée de ce qui est monté versus descendu. Vous avez ensuite exécuté la même GSEA à travers trois vocabulaires — GO, MSigDB Hallmark et Reactome — tous hors ligne, et vu les signatures du muscle lisse des voies respiratoires et des glucocorticoïdes se répéter d’un vocabulaire à l’autre. Les règles pratiques : passez toujours l’univers à l’ORA, classez selon une statistique signée (la statistique de Wald stat) pour la GSEA, fixez une graine aléatoire, faites correspondre le keyType à vos identifiants (ou convertissez avec bitr()), et lisez GeneRatio/NES + p.adjust — puis faites confiance aux résultats qui s’accordent entre méthodes et bases de données.
Autres bases de données : cette leçon exécute la GSEA sur GO, MSigDB Hallmark et Reactome ; KEGG suit le même schéma (enrichKEGG/gseKEGG) mais nécessite une API web — voir la FAQ.
Cette page vous a-t-elle été utile ?
Merci pour votre retour !
Recevez les nouvelles leçons R & Python par e-mail
Pratique, reproductible, sans spam. Désinscription à tout moment.
Double opt-in. Nous ne partageons jamais votre e-mail.
Cette leçon est reproductible : chaque tableau et chaque figure a été produit par le code montré — copiez n’importe quel bloc et exécutez-le pour les reproduire. The runtime is the judge.
Références
Wu, T., Hu, E., Xu, S., et al. (2021). clusterProfiler 4.0: A universal enrichment tool for interpreting omics data. The Innovation, 2(3), 100141.
Subramanian, A., Tamayo, P., Mootha, V. K., et al. (2005). Gene set enrichment analysis: A knowledge-based approach for interpreting genome-wide expression profiles. PNAS, 102(43), 15545–15550.
Yu, G., Wang, L.-G., Han, Y., & He, Q.-Y. (2012). clusterProfiler: an R package for comparing biological themes among gene clusters. OMICS, 16(5), 284–287.
Korotkevich, G., Sukhov, V., Sergushichev, A. (2021). Fast gene set enrichment analysis (the fgsea engine). bioRxiv.
@online{2026,
author = {},
title = {Analyse d’enrichissement de jeux de gènes et de voies en R
avec clusterProfiler},
date = {2026-06-29},
url = {https://www.datanovia.com/learn/bioinformatics/bulk-rna-seq/gene-set-enrichment-analysis},
langid = {fr}
}