Site icon Ampersand Tutorials

GO and KEGG Enrichment Analysis: From Gene List to Biology

Quick answer: Enrichment analysis asks a simple question about a long gene list: are genes with a shared function appearing more often than chance would produce? You bring a gene list, a set of gene sets (Gene Ontology terms, KEGG and Reactome pathways), and a background universe; the method counts the overlap and tests it. Two families dominate: over-representation analysis (ORA), which needs you to pick a cutoff and a background, and gene set enrichment analysis (GSEA), which ranks all genes and tests whether a set’s members cluster at one end of that ranking. Both are easy to run and easy to misread, because a significant term is a hypothesis about annotation, not proof of a mechanism.

A companion to the bulk RNA-seq analysis guide and the genome annotation guide: differential expression gives you the list, enrichment gives the list a biological reading.

The four inputs you must choose deliberately

Almost every enrichment argument is really an argument about inputs:

ORA, mechanically

ORA is a contingency table. Take a term with 40 genes, 300 genes in your list, and 60 of the term’s genes in your list, and ask how likely that overlap is when drawing 300 genes from a universe of 20,000. The test is hypergeometric, and the output is a p-value per term, corrected across all terms tested.

Its two knobs are what make it fragile. Lower the significance cutoff to 1.5-fold and the list doubles; run ORA on that list and different terms appear. Change the background from all annotated genes to expressed genes only and a whole class of terms gains or loses significance. So an ORA result is only interpretable alongside the cutoff and background stated with it.

GSEA, and why it exists

GSEA stops picking a cutoff. Rank every gene by its test statistic, then walk down that ranking and ask whether a term’s genes cluster near the top or bottom more than expected. The output is an enrichment score, a normalized version, and a false discovery rate. Because nothing is thresholded, a term that is coherent but made of individually weak changes can be detected — which is exactly the case ORA loses.

The trade is interpretability. GSEA reports a set and a direction, not a gene count, so “which genes drove this?” requires looking at the leading edge. That is a real cost, and the reason many papers report both.

ORAGSEA
InputA thresholded gene listAll genes, ranked
Catches weak coordinated shiftsNoYes
Sensitive to an arbitrary cutoffYes, stronglyNo
Needs a background universeYesImplicitly, through the ranking
Typical useQuick reading of a differential expression listConfirming a coherent programme across many genes

GO is three ontologies and a hierarchy

Beginners treat “GO analysis” as one test; it is three, and you must choose which. A gene can be significant for a Biological Process while nothing shows in Molecular Function, and reporting only one of them without saying so is a silent bias.

The hierarchy adds a second trap. GO terms nest: “immune response” sits above “innate immune response” and “adaptive immune response”, so a term and its child both being significant is usually one finding, not two. Tools that report the full table hand you a list dominated by related parents and children. The fixes are term-simplification steps (which drop redundant terms in favour of their most specific members) and semantic similarity clustering.

The gene-length and study bias nobody mentions

Two biases are built into the reference annotations themselves and are worth knowing before interpreting any table:

Neither invalidates enrichment analysis, but both mean the honest claim is “genes with function X are over-represented in this list” rather than “function X is the mechanism”.

Running it

The R clusterProfiler ecosystem is the practical standard for reproducible analysis, with g:Profiler, Enrichr and DAVID as web alternatives for a quick look:

library(clusterProfiler)
library(org.Hs.eg.db)

# ORA against GO Biological Process, with an explicit universe
ego <- enrichGO(gene          = sig_entrez,
                universe      = expressed_entrez,   # expressed genes ONLY
                OrgDb         = org.Hs.eg.db,
                ont           = "BP",
                keyType       = "ENTREZID",
                pAdjustMethod = "BH",
                pvalueCutoff  = 0.05,
                qvalueCutoff  = 0.05)
simplify(ego, cutoff = 0.7, by = "p.adjust", select_fun = min)

# GSEA on the full ranked list, no cutoff needed
gse <- gseGO(geneList     = ranked_entrez,
             OrgDb        = org.Hs.eg.db,
             ont          = "BP",
             keyType      = "ENTREZID",
             minGSSize    = 10, maxGSSize = 500, pvalueCutoff = 0.05)

The two details that separate a defensible run from a reportable accident are visible in that code: universe is set explicitly to the expressed genes, and the result is simplified before it is shown. Both are one line and both change the output.

How to read and report a result table

A useful result table has the term, the gene ratio (how many of the term’s genes are in your list), the count, the corrected p-value, and the direction. Report in this order:

Point 5 is the one that gets skipped, and it is the one that matters. A term reported without its member genes is an assertion nobody can check; a term reported with them is an observation someone can follow up.

Common failure modes

Key takeaways

Challenge

Re-run one enrichment analysis you have already seen — or any published one — three times: once with a genome background, once with an expressed-gene background, and once simplified. Then write down which terms survived all three and which appeared only in the least careful run. The difference between those two lists is a precise measure of how much of a typical enrichment table is artefact of choices rather than biology.

Need help interpreting an enrichment analysis for a dissertation or manuscript? Ampersand Academy offers one-to-one mentoring in bioinformatics and data analysis — part of Mahadhi, a development and digital marketing company.

FAQ

What is the difference between GO and KEGG enrichment analysis?

GO describes gene function as three ontologies (biological process, molecular function, cellular component), while KEGG describes pathways. GO is broader and better annotated for non-model organisms; KEGG is more mechanistic but narrower and more human-centric.

What is the background gene set and why does it matter?

The background is every gene that could have appeared in your list. In RNA-seq that is the expressed genes, not the whole genome. Using the genome as background inflates significance and is the most common error in published enrichment analyses.

Should I use over-representation analysis or GSEA?

Use ORA for a quick reading of a thresholded list, and GSEA when you expect coherent but individually weak changes that a cutoff would discard. Many studies report both, because they answer slightly different questions.

Why do I get so many significant GO terms?

Because GO terms nest. A term and all its children can be significant for one underlying finding, and thousands of terms are tested at once. Simplify the result and correct for multiple testing before reading it.

Do I need to correct for multiple testing in enrichment analysis?

Yes. Hundreds or thousands of gene sets are tested, so a raw p-value cutoff of 0.05 produces a large number of false positives. Use a Benjamini-Hochberg style correction and report the adjusted value.

Can enrichment analysis tell me the mechanism behind my result?

No. It tells you which annotated gene sets appear more often than chance in your list, which is a hypothesis. Gene length and annotation bias mean the underlying cause still has to be tested experimentally.

Which tool should a beginner use for enrichment analysis?

clusterProfiler in R is the reproducible standard and handles GO, KEGG, GSEA and simplification in one place. Web tools such as g:Profiler and Enrichr are fine for a fast look but are harder to document in a methods section.

Exit mobile version