richR is an R package for functional enrichment analysis and visualization. It supports Over-Representation Analysis (ORA) via hypergeometric testing, Gene Set Enrichment Analysis (GSEA), and kappa-score-based term clustering. Built-in annotation builders cover GO, KEGG, Reactome, KEGG Module, and MSigDB, and you can supply custom gene sets via GMT files or named lists.
- Enrichment:
richGO(),richKEGG(),enrich(),richGSEA(),richDAVID() - Clustering:
richCluster()groups terms by kappa similarity - 20+ visualization functions including bar, dot, lollipop, heatmap, network, volcano, circle bar, gene-dot, gene-heat, gene-bar, UpSet, and more
- dplyr support:
filter(),select(),mutate(),arrange(),group_by(),slice(),summarise()work directly on enrichment result objects - Batch analysis:
batchEnrich()runs enrichment across multiple gene lists - Comparison:
compareResult()andrichCompareDot()for multi-group comparisons
# Install from GitHub
library(devtools)
install_github("guokai8/richR")Bioconductor annotation packages are needed for building annotations:
BiocManager::install(c("org.Hs.eg.db", "GO.db")) # human GO
BiocManager::install("reactome.db") # Reactome (optional)library(richR)
# Check available species
showData()
# Build GO and KEGG annotations
hsago <- buildAnnot(species = "human", keytype = "SYMBOL", anntype = "GO")
hsako <- buildAnnot(species = "human", keytype = "SYMBOL", anntype = "KEGG")
# KEGG Module
hsakom <- buildAnnot(species = "human", keytype = "SYMBOL", anntype = "KEGGM")
# MSigDB
hsamgi <- buildMSIGDB(species = "human", keytype = "SYMBOL", anntype = "GO")# GO enrichment (ORA)
gene <- sample(unique(hsago$GeneID), 1000)
resgo <- richGO(gene, godata = hsago, ontology = "BP")
head(resgo)
# KEGG enrichment
resko <- richKEGG(gene, kodata = hsako, pvalue = 0.05)
# GSEA (requires a named numeric vector)
genelist <- rnorm(1000)
names(genelist) <- sample(unique(hsako$GeneID), 1000)
res_gsea <- richGSEA(genelist, object = hsako)
# DAVID (online)
res_david <- richDAVID(gene, keytype = "ENTREZID", species = "human")For ORA, universe = NULL uses all unique genes in the eligible annotation.
An explicit universe is intersected with those annotated genes, so unannotated
IDs do not contribute to the background:
background <- unique(hsago$GeneID)
resgo <- richGO(gene, godata = hsago, ontology = "BP", universe = background)
info <- enrichmentInfo(resgo)
info$input$effective_count
info$background$effective_count
# Object-preserving dplyr operations keep the original run's metadata snapshot.
filtered <- dplyr::filter(resgo, Pvalue < 0.05)
enrichmentInfo(filtered)$testing$tested_countORA counts each valid query ID once. Adjusted p-values cover terms with
positive query overlap before size and significance filters. With
keepRich = TRUE, fully rich terms (RichFactor == 1) can pass the lower size
cutoffs; upper size bounds and the significance cutoff still apply.
enrichmentInfo() reports input mapping, effective background, tested-family,
annotation, and provenance details. Legacy objects without recorded metadata
return available = FALSE. The snapshot describes the original analysis after
object-preserving operations such as filter() and arrange(); extracting a
data frame (for example, with result() or as.data.frame()) carries no
metadata guarantee.
GSEA accepts optional backend controls. NULL leaves each control out of the
backend call, preserving its defaults. nproc and BPPARAM cannot be supplied
together. A supplied seed restores the caller's random-number state on
success or error. Repeated seeded calls are reproducible with serial execution:
res_gsea <- richGSEA(genelist, object = hsako, eps = 0,
scoreType = "std", nproc = 1, seed = 123)padj.method is applied to p-values for the full backend-returned pathway set
before result filtering, so choosing a non-BH method can change adjusted
p-values.
parGSEA() forwards the same controls. With simplify = FALSE it returns a
GSEAResult with metadata; simplify = TRUE returns a data frame.
# Import from GMT file (MSigDB, Enrichr, etc.)
annot <- readGMT("h.all.v2023.2.Hs.symbols.gmt", species = "human")
res <- enrich(my_genes, annot)
# From a named list
my_sets <- list(
"Apoptosis" = c("TP53", "BAX", "BCL2", "CASP3"),
"Cell Cycle" = c("CDK1", "CDK2", "CCND1", "RB1")
)
annot <- buildAnnotFromList(my_sets)
res <- enrich(my_genes, annot)Named gene-set lists and batch input lists require unique, nonblank names;
duplicate names are rejected. If a GMT file contains repeated term names,
readGMT() merges their memberships in first-seen order and warns once.
# library(bioAnno)
# fromKEGG(species = "ath")
# athgo <- buildOwn(dbname = "org.ath.eg.db", anntype = "GO")
# athko <- buildOwn(dbname = "org.ath.eg.db", anntype = "KEGG")
# See https://github.com/guokai8/bioAnno for detailsrichR provides 20+ visualization functions. All accept richResult,
GSEAResult, or data.frame objects and support saving to file via
filename, width, and height arguments. Each function has a rich*
primary name and backward-compatible gg* aliases.
Classic plots that rank and display enriched terms:
# Bar plot — horizontal bars of gene count per term, colored by significance
richBar(resgo, top = 20, usePadj = FALSE)
# Dot plot — bubble plot: x = RichFactor, y = Term, size = gene count, color = -log10(p)
richDot(resko, top = 10, usePadj = FALSE)
# Lollipop — clean alternative to bar plot: x = RichFactor, color = significance
richLollipop(resko, top = 20)
# Circular bar plot — polar-coordinate bar chart of enrichment terms
richCircle(resko, top = 15)Two-axis continuous plots for exploring enrichment structure:
# Scatter — enrichment funnel plot (MA-plot analogy for enrichment)
# x = log10(pathway size), y = log2(fold enrichment), color = -log10(p)
# Small pathways (left) can have extreme FE by chance; large pathways
# (right) with high FE are the most robust findings
richScatter(resgo, top = 50, label.top = 5)
richScatter(resko, usePadj = FALSE)
# Volcano — enrichment volcano plot
# x = effect size (log2 FE for ORA, NES for GSEA)
# y = -log10(p), color = effect (diverging gradient), size = -log10(p)
# Labels auto-adjusted via ggrepel; works for both ORA and GSEA
richVolcano(resgo) # ORA: x = log2(Fold Enrichment)
richVolcano(res_gsea) # GSEA: x = NES
richVolcano(resgo, label.top = 10, short = TRUE) # customize labels
# Term similarity scatter — MDS projection of gene-set overlap (Jaccard)
# Functionally related terms cluster together in 2D space
richTermSim(resko, top = 20)Show which genes drive the enrichment:
# Gene-term dot plot — color by fold change (if provided) or -log10(p)
richGeneDot(resgo, fc = my_foldchanges)
richGeneDot(resgo) # no fc: color by -log10(Pvalue)
# Gene-term heatmap — pheatmap-style tile plot with borders
# Missing gene-term combinations shown as grey; supports fold-change coloring
richGeneHeat(resgo, fc = my_foldchanges)
richGeneHeat(resgo, na.fill = "grey90", border.color = "grey40")
# Gene bar plot — bars per term with gene labels aligned inside
richGeneBar(resgo, top = 10)# NES bar plot — up/down color-coded by enrichment direction
richNES(res_gsea, top = 20)
# Running enrichment score curve (classic GSEA plot)
richGSEAcurve(object = hsako, gseaRes = res_gsea)
richGSEAcurve(object = hsako, gseaRes = res_gsea, pathways = "hsa04110")
# ECDF step plot — cumulative rank distribution of gene sets
richECDF(res_gsea)# Gene-concept network — bipartite graph of terms and their genes
richNetplot(resko, top = 20)
# Term similarity network — edges weighted by gene-set overlap (kappa)
richNetwork(resgo, top = 20, weightcut = 0.01)
# Combined network map — overlay multiple enrichment results
richNetmap(list(resgo, resko), top = 50)# Kappa-based clustering of enrichment terms
resc <- richCluster(resgo)
richClusterDot(resc)
# Multi-group comparison
resko1 <- richKEGG(gene1, kodata = hsako)
resko2 <- richKEGG(gene2, kodata = hsako)
res_cmp <- compareResult(list(S1 = resko1, S2 = resko2))
richCompareDot(res_cmp)
# Comparison heatmap across multiple analyses
richHeatmap(list(GO = resgo, KEGG = resko), top = 50)gene_lists <- list(
"Treatment A" = sample(unique(hsako$GeneID), 500),
"Treatment B" = sample(unique(hsako$GeneID), 400),
"Control" = sample(unique(hsako$GeneID), 600)
)
richUpset(gene_lists)
richUpset(gene_lists,
mycol = c("dodgerblue", "goldenrod1", "seagreen3"),
order.by = "degree", nintersects = 20)| Function | Plot type | x-axis | y-axis | Color | Size |
|---|---|---|---|---|---|
richBar |
Bar | Gene count | Term | -log10(p) | — |
richDot |
Bubble | RichFactor | Term | -log10(p) | Gene count |
richLollipop |
Lollipop | RichFactor | Term | -log10(p) | — |
richCircle |
Circular bar | Gene count | Term (polar) | -log10(p) | — |
richScatter |
Funnel/MA | log10(Pathway Size) | log2(Fold Enrichment) | -log10(p) | — |
richVolcano |
Volcano | Effect (log2 FE / NES) | -log10(p) | Effect | -log10(p) |
richTermSim |
MDS scatter | Dim 1 | Dim 2 | -log10(p) | Gene count |
richNES |
Bar (GSEA) | NES | Term | Up/Down | — |
richECDF |
Step | NES rank | Cumulative fraction | — | — |
richGeneDot |
Dot matrix | Gene | Term | FC / -log10(p) | — |
richGeneHeat |
Heatmap | Gene | Term | FC / presence | — |
richGeneBar |
Stacked bar | RichFactor | Term | Gene labels | — |
richNetplot |
Network | — | — | — | — |
richNetwork |
Network | — | — | -log10(p) | Gene count |
richUpset |
UpSet | Intersection | Set size | Group | — |
# Extract result table and detail table
result(resgo)
detail(resgo)
# Get genes for specific terms
getGenes(resgo, term = "GO:0006955")
# dplyr verbs work directly
library(dplyr)
resgo %>% filter(Padj < 0.01) %>% head()
resgo %>% select(Term, Pvalue, Padj)
resgo %>% arrange(Pvalue) %>% head(10)
# Batch enrichment across multiple gene lists
gene_lists <- list(GroupA = gene1, GroupB = gene2)
batch_res <- batchEnrich(gene_lists, annot = hsago)All plotting functions use the rich* prefix as the primary name.
Old gg* names are kept as backward-compatible aliases:
| Primary name | Aliases |
|---|---|
richBar |
ggbar |
richDot |
ggdot |
richLollipop |
gglollipop, ggLollipop |
richGeneDot |
gggenedot, ggGeneDot |
richGeneHeat |
gggeneheat, ggGeneHeat |
richGeneBar |
gggenebar, ggGeneBar |
richCircle |
ggcircbar, ggCircBar |
richVolcano |
ggvolcano, ggVolcano |
richNES |
ggNES, ggnes |
richScatter |
ggscatter, ggScatter |
richECDF |
ggecdf, ggECDF |
richTermSim |
ggtermsim, ggTermSim |
richNetplot |
ggnetplot |
richNetwork |
ggnetwork |
richNetmap |
ggnetmap |
richUpset |
ggupset |
richHeatmap |
ggheatmap |
richClusterDot |
ggcluster |
richCompareDot |
comparedot |
richGSEAplot |
ggGSEA |
richGSEAcurve |
plotGSEA |
If you use richR in your research, please cite:
Guo K and Hur J (2020). richR: Enrichment analysis for functional genomics.
R package version 0.1.2. https://github.com/guokai8/richR
DOI: 10.5281/zenodo.3675760
For questions or bug reports please contact guokai8@gmail.com or open an issue on GitHub.
