1  The first complete workflow: ORA, GSEA, and plots

This chapter starts from the committed datasets/de_table.tsv file derived from the Bioconductor airway example with DESeq2. The table contains Ensembl IDs, differential-expression statistics, and adjusted p-values for dexamethasone-treated versus untreated airway smooth-muscle samples. The table is local at render time; the regeneration script and package provenance are documented in datasets/readme.md.

The example answers two related questions about the same contrast:

The thresholds are teaching choices. In a real analysis, replace them with rules defined before inspecting enrichment results.

1.1 1. Load local packages and inspect the input

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

de_table <- read.delim(
    "datasets/de_table.tsv",
    stringsAsFactors = FALSE,
    check.names = FALSE
)

stopifnot(
    identical(
        names(de_table),
        c("gene_id", "baseMean", "log2FoldChange", "lfcSE", "stat", "pvalue", "padj")
    ),
    !anyDuplicated(de_table$gene_id)
)

head(de_table)
          gene_id    baseMean log2FoldChange     lfcSE       stat       pvalue
1 ENSG00000000003 708.6021697    -0.38125389 0.1006544 -3.7877507 0.0001520173
2 ENSG00000000005   0.0000000             NA        NA         NA           NA
3 ENSG00000000419 520.2979006     0.20681272 0.1122187  1.8429438 0.0653372101
4 ENSG00000000457 237.1630368     0.03792059 0.1434447  0.2643568 0.7915049630
5 ENSG00000000460  57.9326331    -0.08816770 0.2871420 -0.3070526 0.7588033355
6 ENSG00000000938   0.3180984    -1.37823397 3.4998753 -0.3937952 0.6937322727
         padj
1 0.002383075
2          NA
3 0.358663455
4 0.996318548
5 0.996318548
6 0.996318548
summary(de_table[, c("baseMean", "log2FoldChange", "stat", "padj")])
    baseMean         log2FoldChange           stat                padj       
 Min.   :     0.00   Min.   :-5.325905   Min.   :-19.41608   Min.   :0.0000  
 1st Qu.:     0.00   1st Qu.:-0.463691   1st Qu.: -0.56367   1st Qu.:0.6952  
 Median :     0.11   Median :-0.014700   Median : -0.03119   Median :0.9963  
 Mean   :   336.15   Mean   :-0.008159   Mean   :  0.05032   Mean   :0.7853  
 3rd Qu.:    10.28   3rd Qu.: 0.381747   3rd Qu.:  0.48069   3rd Qu.:0.9963  
 Max.   :325662.66   Max.   : 9.505972   Max.   : 24.85609   Max.   :0.9999  
                     NAs    :30208       NAs    :30208       NAs    :30208   

The table uses Ensembl gene IDs and the stat column supplies a signed ranking. Keep both facts visible in an analysis script. An identifier can be syntactically valid and still be incompatible with the selected annotation database.

1.2 2. Define the universe, selected genes, and ranking

The ORA universe starts with genes having a finite DESeq2 statistic and is then restricted to Ensembl IDs present in org.Hs.eg.db. The selected list applies a fixed padj and absolute log2 fold-change rule. GSEA uses the complete finite, mapped statistic ranking, including genes that do not pass the ORA threshold.

eligible <- is.finite(de_table$stat)
candidate_universe <- de_table$gene_id[eligible]
annotation_keys <- AnnotationDbi::keys(org.Hs.eg.db, keytype = "ENSEMBL")
eligible <- eligible & de_table$gene_id %in% annotation_keys

universe <- de_table$gene_id[eligible]
selected <- de_table$gene_id[
    eligible &
        !is.na(de_table$padj) &
        de_table$padj < 0.05 &
        abs(de_table$log2FoldChange) >= 1
]

ranking <- de_table$stat[eligible]
names(ranking) <- de_table$gene_id[eligible]
ranking <- sort(ranking, decreasing = TRUE)

cat("Rows in input table:", nrow(de_table), "\n")
Rows in input table: 63677 
cat("Genes eligible for testing:", length(candidate_universe), "\n")
Genes eligible for testing: 33469 
cat("Genes mapped to org.Hs.eg.db:", length(universe), "\n")
Genes mapped to org.Hs.eg.db: 22599 
cat("Unmapped eligible genes:", length(setdiff(candidate_universe, universe)), "\n")
Unmapped eligible genes: 10870 
cat("Selected genes for ORA:", length(selected), "\n")
Selected genes for ORA: 885 
cat("Selected genes in universe:", all(selected %in% universe), "\n")
Selected genes in universe: TRUE 

universe, selected, and ranking use the same Ensembl namespace after filtering against the keys available in org.Hs.eg.db. The unmapped count is reported rather than silently treated as biological absence. In a real experiment, construct the candidate universe from genes that were measurable and eligible for selection, then record the annotation coverage.

1.3 3. Run over-representation analysis

enrichGO() tests Gene Ontology terms using the selected vector. ont = "BP" restricts this example to biological process terms; use "MF", "CC", or "ALL" when that choice matches the question. The permissive pvalueCutoff = 1 and qvalueCutoff = 1 settings keep the complete result object for teaching and plotting; apply a pre-specified reporting threshold when interpreting a real study.

ora <- enrichGO(
  gene          = selected,
  universe      = universe,
  OrgDb         = org.Hs.eg.db,
  keyType       = "ENSEMBL",
  ont           = "BP",
  pAdjustMethod = "BH",
  pvalueCutoff  = 1,
  qvalueCutoff  = 1,
  minGSSize     = 10,
  maxGSSize     = 500,
  readable      = FALSE
)

ora
#
# over-representation test
#
#...@organism    Homo sapiens 
#...@ontology    BP 
#...@keytype     ENSEMBL 
#...@gene    chr [1:13902] "ENSG00000003402" "ENSG00000004799" "ENSG00000004846" ...
#...pvalues adjusted by 'BH' with cutoff < 1
#...4276 enriched terms found
'data.frame':   4276 obs. of  13 variables:
 $ ID            : chr  "GO:0003013" "GO:0001525" "GO:0007411" "GO:0030198" ...
 $ Description   : chr  "circulatory system process" "angiogenesis" "axon guidance" "extracellular matrix organization" ...
 $ GeneRatio     : chr  "56/772" "55/772" "28/772" "35/772" ...
 $ BgRatio       : chr  "486/15282" "487/15282" "169/15282" "246/15282" ...
 $ RichFactor    : num  0.115 0.113 0.166 0.142 0.165 ...
 $ FoldEnrichment: num  2.28 2.24 3.28 2.82 3.26 ...
 $ oddsRatio     : num  2.56 2.5 3.84 3.22 3.81 ...
 $ zScore        : num  6.62 6.39 6.87 6.62 6.84 ...
 $ pvalue        : num  6.25e-09 1.74e-08 2.55e-08 2.78e-08 2.91e-08 ...
 $ p.adjust      : num  2.09e-05 2.09e-05 2.09e-05 2.09e-05 2.09e-05 ...
 $ qvalue        : num  1.8e-05 1.8e-05 1.8e-05 1.8e-05 1.8e-05 ...
 $ geneID        : chr  "ENSG00000128165/ENSG00000069431/ENSG00000049759/ENSG00000145362/ENSG00000104321/ENSG00000126016/ENSG00000159167"| __truncated__ "ENSG00000133216/ENSG00000128165/ENSG00000107338/ENSG00000154734/ENSG00000161381/ENSG00000126016/ENSG00000118257"| __truncated__ "ENSG00000169750/ENSG00000133216/ENSG00000160145/ENSG00000149633/ENSG00000118257/ENSG00000145242/ENSG00000021645"| __truncated__ "ENSG00000102996/ENSG00000154734/ENSG00000081052/ENSG00000154736/ENSG00000143196/ENSG00000144810/ENSG00000135744"| __truncated__ ...
 $ Count         : int  56 55 28 35 28 35 35 52 47 43 ...
#...Citation
head(as.data.frame(ora))
                   ID                          Description GeneRatio   BgRatio
GO:0003013 GO:0003013           circulatory system process    56/772 486/15282
GO:0001525 GO:0001525                         angiogenesis    55/772 487/15282
GO:0007411 GO:0007411                        axon guidance    28/772 169/15282
GO:0030198 GO:0030198    extracellular matrix organization    35/772 246/15282
GO:0097485 GO:0097485           neuron projection guidance    28/772 170/15282
GO:0043062 GO:0043062 extracellular structure organization    35/772 247/15282
           RichFactor FoldEnrichment oddsRatio   zScore       pvalue
GO:0003013  0.1152263       2.280944  2.560998 6.619528 6.250970e-09
GO:0001525  0.1129363       2.235613  2.499774 6.392052 1.735764e-08
GO:0007411  0.1656805       3.279701  3.835240 6.873797 2.553542e-08
GO:0030198  0.1422764       2.816410  3.218280 6.624697 2.778551e-08
GO:0097485  0.1647059       3.260408  3.807966 6.835987 2.913354e-08
GO:0043062  0.1417004       2.805007  3.202875 6.596697 3.084790e-08
               p.adjust       qvalue
GO:0003013 2.090662e-05 1.798103e-05
GO:0001525 2.090662e-05 1.798103e-05
GO:0007411 2.090662e-05 1.798103e-05
GO:0030198 2.090662e-05 1.798103e-05
GO:0097485 2.090662e-05 1.798103e-05
GO:0043062 2.090662e-05 1.798103e-05
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    geneID
GO:0003013 ENSG00000128165/ENSG00000069431/ENSG00000049759/ENSG00000145362/ENSG00000104321/ENSG00000126016/ENSG00000159167/ENSG00000166825/ENSG00000198947/ENSG00000134294/ENSG00000135744/ENSG00000170214/ENSG00000170624/ENSG00000119139/ENSG00000122679/ENSG00000150594/ENSG00000155962/ENSG00000112715/ENSG00000177674/ENSG00000176387/ENSG00000168398/ENSG00000057294/ENSG00000117152/ENSG00000171385/ENSG00000165995/ENSG00000153904/ENSG00000163485/ENSG00000017483/ENSG00000174697/ENSG00000145244/ENSG00000023909/ENSG00000103257/ENSG00000006283/ENSG00000132170/ENSG00000180914/ENSG00000175538/ENSG00000154864/ENSG00000131389/ENSG00000107562/ENSG00000100739/ENSG00000112837/ENSG00000073756/ENSG00000138074/ENSG00000185052/ENSG00000129682/ENSG00000174437/ENSG00000152779/ENSG00000092969/ENSG00000136546/ENSG00000184408/ENSG00000105711/ENSG00000132326/ENSG00000131979/ENSG00000183044/ENSG00000196517/ENSG00000160460
GO:0001525                 ENSG00000133216/ENSG00000128165/ENSG00000107338/ENSG00000154734/ENSG00000161381/ENSG00000126016/ENSG00000118257/ENSG00000166825/ENSG00000144810/ENSG00000136999/ENSG00000130066/ENSG00000102760/ENSG00000021645/ENSG00000182580/ENSG00000143878/ENSG00000179388/ENSG00000112715/ENSG00000169031/ENSG00000164619/ENSG00000165891/ENSG00000178878/ENSG00000187498/ENSG00000025708/ENSG00000153904/ENSG00000137801/ENSG00000143494/ENSG00000174697/ENSG00000126785/ENSG00000148848/ENSG00000140105/ENSG00000163513/ENSG00000113578/ENSG00000132170/ENSG00000189058/ENSG00000100292/ENSG00000117461/ENSG00000124440/ENSG00000135821/ENSG00000107731/ENSG00000123358/ENSG00000039537/ENSG00000073756/ENSG00000070193/ENSG00000173083/ENSG00000168811/ENSG00000169855/ENSG00000128917/ENSG00000092969/ENSG00000066468/ENSG00000214274/ENSG00000145423/ENSG00000170989/ENSG00000012048/ENSG00000145632/ENSG00000140545
GO:0007411                                                                                                                                                                                                                                                                                                                                                                                                                                                                 ENSG00000169750/ENSG00000133216/ENSG00000160145/ENSG00000149633/ENSG00000118257/ENSG00000145242/ENSG00000021645/ENSG00000182580/ENSG00000112715/ENSG00000125848/ENSG00000074527/ENSG00000108231/ENSG00000168621/ENSG00000107562/ENSG00000162614/ENSG00000107731/ENSG00000196155/ENSG00000116106/ENSG00000137872/ENSG00000149256/ENSG00000169855/ENSG00000221866/ENSG00000100784/ENSG00000075213/ENSG00000105711/ENSG00000128602/ENSG00000055163/ENSG00000106123
GO:0030198                                                                                                                                                                                                                                                                                                                                                 ENSG00000102996/ENSG00000154734/ENSG00000081052/ENSG00000154736/ENSG00000143196/ENSG00000144810/ENSG00000135744/ENSG00000136999/ENSG00000138316/ENSG00000102760/ENSG00000169031/ENSG00000215018/ENSG00000187498/ENSG00000166670/ENSG00000196569/ENSG00000074527/ENSG00000046653/ENSG00000168646/ENSG00000003402/ENSG00000164171/ENSG00000132170/ENSG00000116962/ENSG00000137673/ENSG00000133110/ENSG00000196739/ENSG00000162493/ENSG00000206561/ENSG00000173083/ENSG00000171819/ENSG00000100767/ENSG00000092969/ENSG00000114270/ENSG00000060718/ENSG00000108821/ENSG00000178031
GO:0097485                                                                                                                                                                                                                                                                                                                                                                                                                                                                 ENSG00000169750/ENSG00000133216/ENSG00000160145/ENSG00000149633/ENSG00000118257/ENSG00000145242/ENSG00000021645/ENSG00000182580/ENSG00000112715/ENSG00000125848/ENSG00000074527/ENSG00000108231/ENSG00000168621/ENSG00000107562/ENSG00000162614/ENSG00000107731/ENSG00000196155/ENSG00000116106/ENSG00000137872/ENSG00000149256/ENSG00000169855/ENSG00000221866/ENSG00000100784/ENSG00000075213/ENSG00000105711/ENSG00000128602/ENSG00000055163/ENSG00000106123
GO:0043062                                                                                                                                                                                                                                                                                                                                                 ENSG00000102996/ENSG00000154734/ENSG00000081052/ENSG00000154736/ENSG00000143196/ENSG00000144810/ENSG00000135744/ENSG00000136999/ENSG00000138316/ENSG00000102760/ENSG00000169031/ENSG00000215018/ENSG00000187498/ENSG00000166670/ENSG00000196569/ENSG00000074527/ENSG00000046653/ENSG00000168646/ENSG00000003402/ENSG00000164171/ENSG00000132170/ENSG00000116962/ENSG00000137673/ENSG00000133110/ENSG00000196739/ENSG00000162493/ENSG00000206561/ENSG00000173083/ENSG00000171819/ENSG00000100767/ENSG00000092969/ENSG00000114270/ENSG00000060718/ENSG00000108821/ENSG00000178031
           Count
GO:0003013    56
GO:0001525    55
GO:0007411    28
GO:0030198    35
GO:0097485    28
GO:0043062    35

The output is an enrichResult. Its @result slot can be converted to a data frame, but retain ora itself: the object carries the gene-to-term information needed by downstream plots.

enrichGO() accepts the Ensembl input but uses an Entrez-backed annotation internally when that is memory-efficient; the returned object preserves the original input key type (ENSEMBL). Readable symbols can be added for inspection without changing the test. Let setReadable() use the key type recorded on the result object:

ora_readable <- setReadable(ora, OrgDb = org.Hs.eg.db)
head(as.data.frame(ora_readable)[, c("ID", "Description", "GeneRatio", "p.adjust", "geneID")])
                   ID                          Description GeneRatio
GO:0003013 GO:0003013           circulatory system process    56/772
GO:0001525 GO:0001525                         angiogenesis    55/772
GO:0007411 GO:0007411                        axon guidance    28/772
GO:0030198 GO:0030198    extracellular matrix organization    35/772
GO:0097485 GO:0097485           neuron projection guidance    28/772
GO:0043062 GO:0043062 extracellular structure organization    35/772
               p.adjust
GO:0003013 2.090662e-05
GO:0001525 2.090662e-05
GO:0007411 2.090662e-05
GO:0030198 2.090662e-05
GO:0097485 2.090662e-05
GO:0043062 2.090662e-05
                                                                                                                                                                                                                                                                                                                                                              geneID
GO:0003013 ADM2/ABCC9/NEDD4L/ANK2/TRPA1/AMOT/STC1/ANPEP/DMD/SLC38A2/AGT/ADRA1B/SGCD/TJP2/RAMP3/ADRA2A/CLIC2/VEGFA/AGTRAP/HSD11B2/BDKRB2/PKP2/RGS4/KCND3/CACNB2/DDAH1/ADORA1/SLC38A5/LEP/CORIN/GCLM/SLC7A5/CACNA1G/PPARG/OXTR/KCNE3/PIEZO2/SLC6A6/CXCL12/BDKRB1/TBX18/PTGS2/SLC5A6/SLC24A3/FGF13/ATP2A2/SLC16A12/TGFB2/SCN7A/KCND2/SCN1B/PER2/GCH1/ABAT/SLC6A9/SPTBN4
GO:0001525                                 EPHB2/ADM2/SHB/ADAMTS1/PLXDC1/AMOT/NRP2/ANPEP/COL8A1/CCN3/SAT1/RGCC/NRXN3/EPHB3/RHOB/EGR3/VEGFA/COL4A3/BMPER/E2F7/APOLD1/COL4A1/TYMP/DDAH1/THBS1/VASH2/LEP/RHOJ/ADAM12/WARS1/TGFBR2/FGF1/PPARG/APOD/HMOX1/PIK3R3/HIF3A/GLUL/UNC5B/NR4A1/C6/PTGS2/FGF10/HPSE/IL12A/ROBO1/DLL4/TGFB2/FGFR2/ANG/SFRP2/S1PR1/BRCA1/PLK2/MFGE8
GO:0007411                                                                                                                                                                               RAC3/EPHB2/KALRN/KIAA1755/NRP2/EPHA5/NRXN3/EPHB3/VEGFA/FLRT3/NTN4/LGI1/GDNF/CXCL12/NEXN/UNC5B/PLEKHG4/EPHA4/SEMA6D/TENM4/ROBO1/PLXNA4/RPS6KA5/SEMA3A/SCN1B/SMO/CYFIP2/EPHB6
GO:0030198                                                                                                                             MMP15/ADAMTS1/COL4A4/ADAMTS5/DPT/COL8A1/AGT/CCN3/ADAMTS14/RGCC/COL4A3/COL28A1/COL4A1/MMP10/LAMA2/NTN4/GPM6B/AXIN2/CFLAR/ITGA2/PPARG/NID1/MMP7/POSTN/COL27A1/PDPN/COLQ/HPSE/ANGPTL7/PAPLN/TGFB2/COL7A1/COL11A1/COL1A1/ADAMTSL1
GO:0097485                                                                                                                                                                               RAC3/EPHB2/KALRN/KIAA1755/NRP2/EPHA5/NRXN3/EPHB3/VEGFA/FLRT3/NTN4/LGI1/GDNF/CXCL12/NEXN/UNC5B/PLEKHG4/EPHA4/SEMA6D/TENM4/ROBO1/PLXNA4/RPS6KA5/SEMA3A/SCN1B/SMO/CYFIP2/EPHB6
GO:0043062                                                                                                                             MMP15/ADAMTS1/COL4A4/ADAMTS5/DPT/COL8A1/AGT/CCN3/ADAMTS14/RGCC/COL4A3/COL28A1/COL4A1/MMP10/LAMA2/NTN4/GPM6B/AXIN2/CFLAR/ITGA2/PPARG/NID1/MMP7/POSTN/COL27A1/PDPN/COLQ/HPSE/ANGPTL7/PAPLN/TGFB2/COL7A1/COL11A1/COL1A1/ADAMTSL1

1.4 4. Visualize the ORA result

A dot plot is a compact first view. Dot size is the number of selected genes in a term, and colour represents the adjusted significance used by the plotting method. A network plot is useful for seeing shared genes among a small number of terms.

p_ora_dot <- dotplot(ora, showCategory = 10) +
  ggtitle("ORA: selected genes and biological processes")
p_ora_dot

p_ora_network <- cnetplot(
  ora,
  showCategory = 3,
  foldChange = ranking,
  categorySize = "pvalue"
)
p_ora_network

cnetplot() is intentionally limited to three terms here. Showing every term usually produces a dense graph that is harder to read than the dot plot.

1.5 5. Run GSEA on the complete ranking

GSEA does not use selected as its input. It uses the complete named ranking, so genes below the ORA threshold still contribute. The minGSSize and maxGSSize settings keep this first local example reasonably quick while excluding extremely small or very broad terms.

NoteSize filter is on the overlap, not the raw gene set

minGSSize and maxGSSize constrain the size of each gene set after intersecting with the genes present in your ranking (names(geneList)). A database gene set with 3 000 annotated members is therefore not dropped just because 3 000 > maxGSSize = 500; it is retained if only 400 of its members appear in the ranked list. Full rationale and tuning tables are in Tuning minGSSize and maxGSSize.

Setting cutoffs to 1 retains the tested terms so that the plotting example remains informative even when few terms meet a conventional significance threshold.

set.seed(1)
gsea <- gseGO(
  geneList      = ranking,
  OrgDb         = org.Hs.eg.db,
  keyType       = "ENSEMBL",
  ont           = "BP",
  minGSSize     = 100,
  maxGSSize     = 300,
  pAdjustMethod = "BH",
  pvalueCutoff  = 1,
  eps           = 0,
  verbose       = FALSE
)

gsea
#
# Gene Set Enrichment Analysis
#
#...@organism    Homo sapiens 
#...@setType     BP 
#...@keytype     ENSEMBL 
#...@geneList    Named num [1:22599] 24.9 24.7 24.3 24.2 23.7 ...
 - attr(*, "names")= chr [1:22599] "ENSG00000152583" "ENSG00000165995" "ENSG00000120129" "ENSG00000101347" ...
#...nPerm    1000 
#...pvalues adjusted by 'BH' with cutoff < 1
#...854 enriched terms found
'data.frame':   854 obs. of  12 variables:
 $ ID             : chr  "GO:0044272" "GO:0001764" "GO:0007266" "GO:0008360" ...
 $ Description    : chr  "sulfur compound biosynthetic process" "neuron migration" "Rho protein signal transduction" "regulation of cell shape" ...
 $ setSize        : int  111 103 131 117 180 139 141 247 112 222 ...
 $ enrichmentScore: num  0.548 -0.52 0.533 0.534 0.508 ...
 $ NES            : num  1.74 -1.73 1.72 1.71 1.71 ...
 $ pvalue         : num  2.31e-04 7.05e-05 5.27e-05 5.05e-04 7.55e-05 ...
 $ p.adjust       : num  0.01235 0.00921 0.009 0.01874 0.00921 ...
 $ qvalue         : num  0.00243 0.00181 0.00177 0.00369 0.00181 ...
 $ rank           : int  3477 2768 3077 1863 2798 1915 2765 3486 2494 2581 ...
 $ leading_edge   : chr  "tags=35%, list=15%, signal=30%" "tags=32%, list=12%, signal=28%" "tags=36%, list=14%, signal=31%" "tags=24%, list=8%, signal=22%" ...
 $ core_enrichment: chr  "ENSG00000154930/ENSG00000151726/ENSG00000099998/ENSG00000160200/ENSG00000023909/ENSG00000128309/ENSG00000165996"| __truncated__ "ENSG00000099250/ENSG00000165323/ENSG00000136848/ENSG00000173406/ENSG00000189056/ENSG00000075275/ENSG00000171943"| __truncated__ "ENSG00000162493/ENSG00000172403/ENSG00000163171/ENSG00000134318/ENSG00000137962/ENSG00000132155/ENSG00000164050"| __truncated__ "ENSG00000139132/ENSG00000162493/ENSG00000163171/ENSG00000186575/ENSG00000164050/ENSG00000206190/ENSG00000071127"| __truncated__ ...
 $ log2err        : num  0.519 0.538 0.557 0.477 0.538 ...
#...Citation
head(as.data.frame(gsea))
                   ID                           Description setSize
GO:0044272 GO:0044272  sulfur compound biosynthetic process     111
GO:0001764 GO:0001764                      neuron migration     103
GO:0007266 GO:0007266       Rho protein signal transduction     131
GO:0008360 GO:0008360              regulation of cell shape     117
GO:0010810 GO:0010810 regulation of cell-substrate adhesion     180
GO:0090596 GO:0090596           sensory organ morphogenesis     139
           enrichmentScore       NES       pvalue    p.adjust      qvalue rank
GO:0044272       0.5479396  1.742013 2.313734e-04 0.012349553 0.002429672 3477
GO:0001764      -0.5199957 -1.734625 7.052150e-05 0.009207581 0.001811515 2768
GO:0007266       0.5330403  1.715300 5.269053e-05 0.008999543 0.001770585 3077
GO:0008360       0.5339027  1.712340 5.046989e-04 0.018739690 0.003686878 1863
GO:0010810       0.5079134  1.710410 7.547198e-05 0.009207581 0.001811515 2798
GO:0090596      -0.4830453 -1.708138 1.480924e-04 0.010539242 0.002073508 1915
                             leading_edge
GO:0044272 tags=35%, list=15%, signal=30%
GO:0001764 tags=32%, list=12%, signal=28%
GO:0007266 tags=36%, list=14%, signal=31%
GO:0008360  tags=24%, list=8%, signal=22%
GO:0010810 tags=32%, list=12%, signal=28%
GO:0090596  tags=27%, list=8%, signal=25%
                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           core_enrichment
GO:0044272                                                                                                                                                                                                                                                                                                                 ENSG00000154930/ENSG00000151726/ENSG00000099998/ENSG00000160200/ENSG00000023909/ENSG00000128309/ENSG00000165996/ENSG00000066322/ENSG00000182551/ENSG00000117479/ENSG00000206527/ENSG00000038274/ENSG00000004799/ENSG00000103150/ENSG00000135917/ENSG00000106688/ENSG00000150768/ENSG00000012660/ENSG00000100714/ENSG00000116761/ENSG00000105607/ENSG00000076555/ENSG00000129596/ENSG00000198682/ENSG00000168291/ENSG00000168906/ENSG00000068120/ENSG00000131069/ENSG00000146085/ENSG00000119689/ENSG00000007933/ENSG00000063854/ENSG00000010932/ENSG00000131473/ENSG00000125779/ENSG00000170522/ENSG00000099810/ENSG00000169710/ENSG00000075239
GO:0001764                                                                                                                                                                                                                                                                                                                                                                                                                 ENSG00000099250/ENSG00000165323/ENSG00000136848/ENSG00000173406/ENSG00000189056/ENSG00000075275/ENSG00000171943/ENSG00000138182/ENSG00000138443/ENSG00000162631/ENSG00000067141/ENSG00000081189/ENSG00000196576/ENSG00000054282/ENSG00000173376/ENSG00000108175/ENSG00000112137/ENSG00000112139/ENSG00000131584/ENSG00000148219/ENSG00000070808/ENSG00000080824/ENSG00000131711/ENSG00000110492/ENSG00000112715/ENSG00000129682/ENSG00000075213/ENSG00000168542/ENSG00000167552/ENSG00000152580/ENSG00000116584/ENSG00000106484/ENSG00000107562
GO:0007266                                                                                                                                                                                 ENSG00000162493/ENSG00000172403/ENSG00000163171/ENSG00000134318/ENSG00000137962/ENSG00000132155/ENSG00000164050/ENSG00000143878/ENSG00000107104/ENSG00000214944/ENSG00000067900/ENSG00000065320/ENSG00000073712/ENSG00000017797/ENSG00000110906/ENSG00000173706/ENSG00000151491/ENSG00000170776/ENSG00000198121/ENSG00000141522/ENSG00000143322/ENSG00000133121/ENSG00000136238/ENSG00000188906/ENSG00000146535/ENSG00000172757/ENSG00000147251/ENSG00000196914/ENSG00000158985/ENSG00000076928/ENSG00000175220/ENSG00000119326/ENSG00000109079/ENSG00000005884/ENSG00000102606/ENSG00000131037/ENSG00000197256/ENSG00000039523/ENSG00000123159/ENSG00000111348/ENSG00000104880/ENSG00000140945/ENSG00000144891/ENSG00000158769/ENSG00000067560/ENSG00000177105/ENSG00000181104
GO:0008360                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 ENSG00000139132/ENSG00000162493/ENSG00000163171/ENSG00000186575/ENSG00000164050/ENSG00000206190/ENSG00000071127/ENSG00000073712/ENSG00000169750/ENSG00000133026/ENSG00000151491/ENSG00000120899/ENSG00000198121/ENSG00000112276/ENSG00000162458/ENSG00000167657/ENSG00000157827/ENSG00000008853/ENSG00000197702/ENSG00000136238/ENSG00000135046/ENSG00000172757/ENSG00000158985/ENSG00000140416/ENSG00000167193/ENSG00000122545/ENSG00000138771/ENSG00000100345
GO:0010810 ENSG00000162493/ENSG00000168309/ENSG00000046653/ENSG00000173517/ENSG00000179820/ENSG00000134318/ENSG00000111859/ENSG00000139567/ENSG00000186575/ENSG00000035403/ENSG00000079691/ENSG00000189058/ENSG00000107104/ENSG00000206560/ENSG00000174804/ENSG00000165996/ENSG00000213853/ENSG00000152377/ENSG00000067900/ENSG00000137801/ENSG00000147459/ENSG00000073712/ENSG00000126458/ENSG00000169750/ENSG00000130402/ENSG00000137076/ENSG00000108861/ENSG00000184009/ENSG00000120899/ENSG00000096968/ENSG00000167657/ENSG00000173083/ENSG00000136238/ENSG00000196924/ENSG00000172757/ENSG00000184371/ENSG00000104332/ENSG00000110880/ENSG00000119185/ENSG00000149177/ENSG00000057294/ENSG00000167193/ENSG00000173402/ENSG00000132669/ENSG00000111846/ENSG00000152818/ENSG00000112679/ENSG00000169499/ENSG00000102606/ENSG00000051382/ENSG00000127603/ENSG00000197122/ENSG00000074054/ENSG00000117228/ENSG00000140945/ENSG00000106366/ENSG00000109743/ENSG00000006210
GO:0090596                                                                                                                                                                                                                                                                                                                                                 ENSG00000198707/ENSG00000134376/ENSG00000138443/ENSG00000154096/ENSG00000073711/ENSG00000100625/ENSG00000119608/ENSG00000198719/ENSG00000128272/ENSG00000196591/ENSG00000003137/ENSG00000146555/ENSG00000188501/ENSG00000114251/ENSG00000151617/ENSG00000137203/ENSG00000095397/ENSG00000135111/ENSG00000177732/ENSG00000187634/ENSG00000066468/ENSG00000112320/ENSG00000110400/ENSG00000106571/ENSG00000117122/ENSG00000164920/ENSG00000137273/ENSG00000178764/ENSG00000130635/ENSG00000113140/ENSG00000112715/ENSG00000125398/ENSG00000184254/ENSG00000133216/ENSG00000112837/ENSG00000105989/ENSG00000124766
             log2err
GO:0044272 0.5188481
GO:0001764 0.5384341
GO:0007266 0.5573322
GO:0008360 0.4772708
GO:0010810 0.5384341
GO:0090596 0.5188481

The result is a gseaResult. Its NES and enrichmentScore describe direction and magnitude relative to the ranked list; the adjusted p-value controls for testing many terms. Inspect both effect direction and statistical evidence rather than sorting only by a single column.

1.6 6. Visualize the GSEA result

The dot plot gives a profile-level overview. gseaplot2() shows the running enrichment score, the locations of genes in the selected set, and the ranked statistic for one term.

p_gsea_dot <- dotplot(gsea, showCategory = 10) +
  ggtitle("GSEA: biological processes across the full ranking")
p_gsea_dot

if (nrow(as.data.frame(gsea)) > 0) {
  gseaplot2(gsea, geneSetID = 1, title = gsea$Description[1])
}

The x-axis of a GSEA curve is the position in the ranked list, not a gene identifier. A term enriched at the top has a positive direction for this signed ranking; a term enriched at the bottom has a negative direction.

1.7 7. Compare the two questions and save results

ORA and GSEA can both be useful, but they are not duplicate tests. ORA asks whether a thresholded set has more members of a term than expected under the universe. GSEA asks whether term members accumulate toward one end of the complete ranking. Report which input and background were used for each result.

# These files are optional outputs; the result objects remain the analysis record.
write.csv(de_table, "de-table-used.csv", row.names = FALSE)
write.csv(as.data.frame(ora_readable), "ora-go-bp-results.csv", row.names = FALSE)
write.csv(as.data.frame(gsea), "gsea-go-bp-results.csv", row.names = FALSE)
saveRDS(
    list(
        input = de_table,
        universe = universe,
        selected = selected,
        ranking = ranking,
        ora = ora,
        gsea = gsea
    ),
    "enrichment-objects.rds"
)

For a short report, start with the two dot plots and one GSEA curve. For a detailed report, include the ID type, universe construction, threshold, ontology, package versions, and the complete result tables.

Offline boundary. This chapter uses data shipped with R/Bioconductor packages. org.Hs.eg.db is a local annotation package, and the example does not query KEGG, Enrichr, g:Profiler, or another remote service. A real study should record the annotation package version because local annotations change over time.

1.8 Next steps