Gene Set Enrichment Analysis · MSigDB Hallmark H

GSEA Teaching Manual: HALLMARK_G2M_CHECKPOINT as an Example

First compute a running ES by hand with 10 genes, then look at a full-scale enrichment plot of 5,000 genes, and finally learn how to read NES, FDR and the leading edge.

What GSEA asksDoes a group of genes (a gene set) lean, as a whole, toward the top or the bottom of a genome-wide ranked list?
How it is computedWalk down the list: add to a running score at each member, subtract at each non-member. The point farthest from 0 is the ES.
How to read itThe sign of NES gives the direction, FDR gives the confidence, and the leading-edge genes are what you validate next.
01 · Concept

GSEA and ORA: names, method and differences

GSEA stands for Gene Set Enrichment Analysis. ORA stands for Over-Representation Analysis; what people usually call "GO / KEGG enrichment analysis" is most often ORA.

ORA (for example a hypergeometric test on GO or KEGG terms) first cuts a DEG list with thresholds such as padj < 0.05 and |log2FC| > 1, then asks whether pathway members are over-represented in that list. GSEA uses no threshold. It ranks all genes by a differential metric and asks whether the gene set as a whole drifts toward one end of the ranked list.

How ORA is computed

ORA asks: are genes from a given pathway more common in the significant-gene list than random sampling would predict? It uses a hypergeometric test (equivalent to a one-sided Fisher's exact test) on this 2×2 table.

In pathwayNot in pathwayTotal
Significant (DEG)kn − kn
Not significantK − kN − K − n + kN − n
TotalKN − KN

N is the number of background genes (the universe), K the number of genes in the pathway, n the number of DEGs, and k the overlap. The p-value is the probability of drawing at least k pathway members when n genes are drawn at random from N:

p = Σi=kmin(n,K) C(K, i) · C(N−K, n−i) / C(N, n)

Typical reports show GeneRatio = k/n and BgRatio = K/N. A GeneRatio clearly above the BgRatio means the pathway is over-represented among the DEGs.

Four limitations of ORA: (1) results depend on the threshold, and a different cutoff can change them; (2) every gene below the threshold is treated as unchanged, and the size of log2FC is ignored; (3) the background should be the genes actually detected in the experiment, since using the whole genome makes p-values too small; (4) it assumes genes are independent, yet genes in one pathway are often co-regulated.

Side-by-side comparison

ORA (Over-Representation Analysis, threshold-based)GSEA (Gene Set Enrichment Analysis, rank-based)
InputA DEG list (discrete)A genome-wide ranked list L (continuous)
ThresholdRequired; results are sensitive to itNone
Good at catchingA few genes with large changesMany genes with small but consistent changes
DirectionUp and down usually run separatelyThe sign of NES gives the direction
Statistical testHypergeometric / Fisher's exact testRunning-sum ES with a permutation test
CostFast and simpleNeeds a permutation test and the full expression data
Common toolsclusterProfiler enrichGO / enrichKEGG, DAVID, g:Profiler, EnrichrGSEA desktop, fgsea, clusterProfiler gseGO

The Hallmark collection (MSigDB Collection H) distils thousands of overlapping MSigDB gene sets into 50 well-defined, minimally overlapping sets, each representing a specific biological state or process. Running these 50 first keeps the multiple-testing burden small and the results focused.

02 · Standard workflow

The standard GSEA workflow

  1. Prepare expression data and groupsAn RNA-seq count matrix or a microarray expression matrix, plus two phenotype labels (for example Tumor vs Normal). The GSEA desktop app uses .gct and .cls files.
  2. Compute a ranking metric ri to build the ranked list LCommon choices are Signal-to-Noise (the desktop default), a t statistic, the DESeq2 Wald stat, or sign(log2FC) × −log10(p). log2FC alone is not recommended because it ignores variance. Sort the list by r from high to low; collapse duplicate gene symbols first.
  3. Load gene sets (.gmt)For example the human Hallmark file h.all.v2024.1.Hs.symbols.gmt (the version number depends on when you download it). Usually only gene sets with 15–500 members present in the data are kept.
  4. Walk the list to get the running ES and the ESMembers (hits) add a score weighted by |ri|p; non-members (misses) subtract an equal share. The standard weighting is p = 1 (weighted).
  5. Permutation test to build a null distributionRepeat 1,000 times. With ≥ 7 samples per group use phenotype permutation (shuffle sample labels, which keeps gene–gene correlation); with fewer samples, or with Preranked, use gene_set permutation.
  6. Normalize and correct: NES, nominal p, FDR qNES divides by the mean of same-sign null ES values to remove the effect of gene set size; FDR evaluates all gene sets together.
  7. Leading-edge analysisFind the core subset of genes that pushes the ES to its peak.
  8. Interpret and validateFilter by NES / FDR, check the shape of the plot, then pick leading-edge genes for qPCR, Western blots or functional experiments.
03 · Example gene set

Example gene set: HALLMARK_G2M_CHECKPOINT

This set has 200 genes. It represents the checkpoint and division machinery between the end of DNA replication and the start of mitosis: the cyclin B–CDK1 complex, PLK1 and AURKA that drive entry into mitosis, CHEK1 that brakes the cycle on DNA damage, the CDC25 phosphatases that activate CDK1 by dephosphorylation, and the spindle assembly checkpoint genes BUB1, MAD2L1 and CDC20.

ScenarioExpected NESBiological reading
Tumor vs normal tissuePositive (+)Cells proliferate actively, many enter M phase, and mitosis genes go up as a group
CDK4/6 inhibitor vs DMSONegative (−)Cells arrest in G1 and cannot reach G2/M, so these genes go down as a group
Treatment unrelated to the cell cycle≈ 0, not significantMembers are scattered over the list with no collective shift
Note: G2M_CHECKPOINT partly overlaps E2F_TARGETS and MITOTIC_SPINDLE, and the three often appear together. Treat them as one “proliferation” story, not three independent findings.
04 · Worked example, N = 10

A ten-gene example: computing the ES step by step

Scenario: tumor vs normal tissue. The 10 genes below are already sorted by the ranking metric ri from high to low. Only 3 of them belong to the G2M set: PLK1, CDK1 and CHEK1 (marked green). The other 7 are non-members (hypoxia, glycolysis, extracellular matrix and metabolism genes).

N = 10  NH = 3  NR = Σg∈S|rg|p = |2.0| + |1.0| + |−0.2| = 3.2 (p = 1)
Hit: Phit = |ri|p / NR   Miss: Pmiss = 1 / (N − NH) = 1/7 ≈ 0.1429
ES = the running ES value farthest from 0 over the whole walk (sign kept)
Weight p:

← Swipe the plot sideways →

RankGeneIn S?riThis stepRunning ES

Click any row to add the gene to the set or remove it; the plot and numbers update at once. “Reset” goes back to PLK1 / CDK1 / CHEK1.

Exact fractions for p = 1

RankGeneriAdd / subtractRunning ES (fraction)Decimal
1VEGFAMiss+2.5−1/7−1/7−0.1429
2PLK1Hit+2.0+2.0/3.2 = +5/8−1/7 + 5/8 = 27/56+0.4821
3LDHAMiss+1.5−1/719/56+0.3393
4CDK1Hit+1.0+1.0/3.2 = +5/1673/112 (peak)+0.6518
5SLC2A1Miss+0.5−1/757/112+0.5089
6CHEK1Hit−0.2+|−0.2|/3.2 = +1/1657/112 + 7/112 = 4/7+0.5714
7COL1A1Miss−0.8−1/73/7+0.4286
8CD36Miss−1.2−1/72/7+0.2857
9ALBMiss−1.8−1/71/7+0.1429
10PPARGMiss−2.4−1/700.0000

Why it always ends at 0: the hits add up to (2.0 + 1.0 + 0.2) / 3.2 = 1, and the misses subtract 7 × 1/7 = 1. The difference must be 0.

Result: ES = +73/112 ≈ +0.6518, with the peak at rank 4 (CDK1). A positive value means G2M members lean toward the top of the list, i.e. they are up in the tumor.

Leading edge: for positive enrichment, take the members from rank 1 up to the peak: PLK1 and CDK1. CHEK1 is a member, but it sits after the peak and has r = −0.2, so it does not contribute to the ES and is not in the leading edge.

Try it: switch p to 0 and every hit adds 1/3. CHEK1’s contribution grows from 0.0625 to 0.333, the peak moves to rank 6, and the ES gets smaller (4/7 ≈ 0.5714). Weighting lets members with large changes dominate the score, while p = 0 only looks at positions.
05 · Enrichment plot, N = 5,000

A full-scale enrichment plot

Scale the same rules up to 5,000 genes and 200 G2M members and you get the three-panel plot familiar from GSEA papers. The data below are simulated for three scenarios. The statistics are computed live in your browser from 1,000 gene-set permutations. Move the pointer over the plot to see the values at each position.

ES
–
NES
–
Nominal p
–
Peak / trough (rank)
–
Leading-edge genes
–

← Swipe the plot sideways →

Permutation null: where the observed ES falls

Reading the three panels

PanelShowsWhat to look for
Top: running ES curveThe cumulative score from left to rightA peak on the left above 0 means positive enrichment; a trough on the right below 0 means negative enrichment. The sharper the peak and the closer to the edge, the more tightly the members cluster at one end.
Middle: barcodeEach line is the position of one member geneDense on the left means up, dense on the right means down, evenly spread means no shift. The green shading is the leading-edge range.
Bottom: ranking metricri for all genesAbove 0 on the left means higher in the treatment group; below 0 on the right means higher in the control. The zero crossing divides up from down.
06 · Interpretation

Interpretation

Statistical thresholds

MeasureMeaningCommon threshold
ESThe running ES value farthest from 0Not compared directly (depends on gene set size)
NESES ÷ mean of same-sign permutation ES; comparable across gene sets|NES| > 1.5 is strong (rule of thumb); the sign gives the direction
Nominal pPermutation p value for one gene set, not corrected for multiple testingFor reference only
FDR qEstimated false-positive fraction from the NES null of all gene sets< 0.25 exploratory (GSEA’s own recommendation); < 0.05 for rigorous publication
FWER pThe most conservative family-wise error rate< 0.05 means a very solid result

Four common curve shapes

Interpretation checklist

Example sentence for a paper: “GSEA showed significant enrichment of HALLMARK_G2M_CHECKPOINT in tumors (NES = 2.41, FDR q < 0.001), with leading-edge genes including CDK1, PLK1, AURKA and CCNB2, suggesting active G2/M transition in tumor cells.” Replace the numbers with your own results.
07 · Code

In practice: R (fgsea + msigdbr)

# DESeq2 results in res (Tumor vs Normal), with a gene symbol column `symbol` added
library(msigdbr); library(fgsea); library(dplyr)

# From msigdbr 10 the full data live in a separate package, msigdbdf; install it once
h  <- msigdbr(species = "Homo sapiens", collection = "H")   # older versions: category = "H"
pw <- split(h$gene_symbol, h$gs_name)

rk <- res |> as.data.frame() |> filter(!is.na(stat), !is.na(symbol)) |>
      group_by(symbol) |> summarise(stat = mean(stat))      # collapse duplicate genes
ranks <- sort(setNames(rk$stat, rk$symbol), decreasing = TRUE)

set.seed(42)
fg <- fgsea(pw, ranks, minSize = 15, maxSize = 500)
fg |> arrange(padj) |> select(pathway, NES, padj, size) |> head(10)

plotEnrichment(pw[["HALLMARK_G2M_CHECKPOINT"]], ranks) +
  ggplot2::labs(title = "HALLMARK_G2M_CHECKPOINT")
fg$leadingEdge[[which(fg$pathway == "HALLMARK_G2M_CHECKPOINT")]]

fgsea’s padj is a Benjamini–Hochberg adjusted p value. It is computed differently from the FDR q of the GSEA desktop app but serves the same purpose. In the desktop app, suggested settings are: Permutations 1000, Enrichment statistic weighted, Metric Signal2Noise, Max/Min size 500/15.

08 · Pitfalls

Common misconceptions

TopicMisconceptionCorrect statement
Definition of ESES = argmax |Phit − Pmiss|argmax returns a position. The ES is the running ES value farthest from 0, with its sign kept; the position is the rank of the peak (or trough).
NESES divided by the mean of all permutation ES valuesDivide by the mean of same-sign permutation ES values: positive nulls for a positive ES, negative nulls (in absolute value) for a negative ES.
FDRGSEA’s FDR is Benjamini–HochbergThe original GSEA FDR is estimated directly from the NES null distribution of all gene sets, not by BH. BH is what fgsea and clusterProfiler use.
Leading edgeEvery member of the gene set is in the leading edgeOnly members before the peak (positive enrichment) or after the trough (negative enrichment) are. CHEK1 in section 4 is not.
Number of HallmarksSome entries are duplicated or share a codeThere are 50 Hallmark sets, none duplicated, all named HALLMARK_…; for example HALLMARK_PEROXISOME and HALLMARK_SPERMATOGENESIS are two different sets.