| Title: | Enrichment Analysis of Chemical-Gene Interactions from the Comparative Toxicogenomics Database |
|---|---|
| Description: | Identifies chemicals significantly associated with a set of genes using data from the Comparative Toxicogenomics Database (CTD, <https://ctdbase.org>). Supports four enrichment methods through a unified interface: Over-Representation Analysis (ORA) via a hypergeometric test on stats::phyper(), Gene Set Enrichment Analysis (GSEA) via 'fgsea', the competitive gene-set test CAMERA via 'limma', and per-sample Gene Set Variation Analysis (GSVA) via 'GSVA'. Users download the CTD chemical-gene interactions file once, import it with import_CTD(), and then run enrichment_CTD() on either a gene list (ORA, GSEA) or an expression matrix (CAMERA, GSVA). This package does not bundle or redistribute CTD data. Users must download the required data files directly from <https://ctdbase.org> and comply with the CTD data licensing terms (see <https://ctdbase.org/about/legal.jsp>). |
| Authors: | Luigi Corsaro [aut, cre] (ORCID: <https://orcid.org/0000-0003-1218-230X>) |
| Maintainer: | Luigi Corsaro <[email protected]> |
| License: | Apache License 2.0 | file LICENSE |
| Version: | 0.99.11 |
| Built: | 2026-10-05 07:22:15 UTC |
| Source: | https://github.com/bioc/ctdR |
ctdR identifies chemicals significantly associated with a set of genes using data from the Comparative Toxicogenomics Database (CTD, https://ctdbase.org).
Four enrichment methods are supported through a unified interface:
Over-Representation Analysis via
phyper.
Gene Set Enrichment Analysis via
fgsea.
Competitive gene-set test accounting for
inter-gene correlation, via camera.
Per-sample Gene Set Variation Analysis via
gsva.
ORA and GSEA take a gene-level data frame. CAMERA and GSVA take
expression data, either as a numeric matrix (genes x samples) or as a
SummarizedExperiment; GSVA returns
its per-sample scores in whichever of the two it was given, so sample
annotation stays attached to the results.
Download CTD_chem_gene_ixns.csv.gz from
https://ctdbase.org/reports/CTD_chem_gene_ixns.csv.gz and
decompress it (gunzip CTD_chem_gene_ixns.csv.gz).
Import the data once:
import_CTD("path/to/CTD_chem_gene_ixns.csv")
Run enrichment analysis:
enrichment_CTD(my_genes, method = "ORA")
This package does not bundle, redistribute, or embed any data from the Comparative Toxicogenomics Database. CTD data are created and maintained by NC State University and are subject to specific licensing terms and conditions.
Users are solely responsible for:
Downloading the required data files directly from https://ctdbase.org.
Reading and accepting the CTD Terms of Service at https://ctdbase.org/about/legal.jsp before using the data.
Complying with all applicable CTD data licensing requirements, including proper citation of CTD in any publications or derived works.
By using ctdR with CTD data, you acknowledge that you have read, understood, and agreed to the CTD Terms of Service.
Maintainer: Luigi Corsaro [email protected] (ORCID)
Authors:
Luigi Corsaro [email protected] (ORCID)
Davis AP, Wiegers TC, Johnson RJ, Sciaky D, Wiegers J, Mattingly CJ (2023). "Comparative Toxicogenomics Database (CTD): update 2023." Nucleic Acids Research, 51(D1), D1257-D1262. doi:10.1093/nar/gkac833. https://ctdbase.org
import_CTD to import CTD data,
enrichment_CTD to run enrichment analysis.
Returns the cached CTD chemical gene sets as a named list, in the shape
expected by third-party Bioconductor enrichment engines — for example the
gs argument of EnrichmentBrowser::sbea(), or the input to
GSEABase::GeneSetCollection(). This lets you run the CTD gene sets
through existing infrastructure instead of, or alongside,
enrichment_CTD.
as_genesets_CTD( id_type = c("entrez", "symbol"), interaction_types = NULL, cache_dir = .ctd_cache_dir() )as_genesets_CTD( id_type = c("entrez", "symbol"), interaction_types = NULL, cache_dir = .ctd_cache_dir() )
id_type |
Either |
interaction_types |
Optional character vector of CTD interaction actions
(e.g. |
cache_dir |
Directory holding the cached CTD files. Defaults to the
ctdR user cache populated by |
ctdR builds chemical-centric gene sets: each CTD chemical
becomes a gene set of its interacting genes. enrichment_CTD
consumes these internally; this helper exposes the same gene sets so they
integrate with the wider ecosystem. Call import_CTD once first
to populate the cache.
The returned representation is deliberately a plain named list (not a bespoke
class): it is accepted directly by EnrichmentBrowser::sbea() and is a
one-line conversion away from a GeneSetCollection. ctdR does not
take a dependency on those engines — you supply them.
A named list: names are CTD ChemicalIDs, elements are
character vectors of gene identifiers (Entrez IDs or HGNC symbols).
import_CTD to populate the cache;
enrichment_CTD for the built-in enrichment interface.
# Examples write to a temporary cache, so running them cannot # disturb CTD data you have already imported. Set the same option # yourself to keep an analysis isolated from your main cache. options(ctdR.cache = tempfile()) sample_file <- system.file( "extdata", "CTD_chem_gene_ixns_sample.csv", package = "ctdR" ) import_CTD(sample_file) gene_sets <- as_genesets_CTD("entrez") length(gene_sets) gene_sets[[1]] ## Not run: # Hand the CTD gene sets to an existing engine (EnrichmentBrowser): library(EnrichmentBrowser) res <- sbea(method = "camera", se = my_se, gs = as_genesets_CTD("entrez")) gsRanking(res) ## End(Not run)# Examples write to a temporary cache, so running them cannot # disturb CTD data you have already imported. Set the same option # yourself to keep an analysis isolated from your main cache. options(ctdR.cache = tempfile()) sample_file <- system.file( "extdata", "CTD_chem_gene_ixns_sample.csv", package = "ctdR" ) import_CTD(sample_file) gene_sets <- as_genesets_CTD("entrez") length(gene_sets) gene_sets[[1]] ## Not run: # Hand the CTD gene sets to an existing engine (EnrichmentBrowser): library(EnrichmentBrowser) res <- sbea(method = "camera", se = my_se, gs = as_genesets_CTD("entrez")) gsRanking(res) ## End(Not run)
Returns a processed CTD table from the ctdR cache populated by
import_CTD, without reaching into the .rda cache files
by hand. Use this instead of load(file.path(cache_dir, "...rda")) when
you need the chemical metadata or the raw interaction table in your own code.
For the chemical gene sets (the input to enrichment engines) use
as_genesets_CTD instead.
ctd_cache(what = c("chemicals", "interactions"), cache_dir = .ctd_cache_dir())ctd_cache(what = c("chemicals", "interactions"), cache_dir = .ctd_cache_dir())
what |
Which cached table to return:
|
cache_dir |
Directory holding the cached CTD files. Defaults to the
ctdR user cache populated by |
A data frame with the requested cached table.
import_CTD to populate the cache;
as_genesets_CTD for the chemical gene sets.
# Examples write to a temporary cache, so running them cannot # disturb CTD data you have already imported. Set the same option # yourself to keep an analysis isolated from your main cache. options(ctdR.cache = tempfile()) sample_file <- system.file( "extdata", "CTD_chem_gene_ixns_sample.csv", package = "ctdR" ) import_CTD(sample_file) chem <- ctd_cache("chemicals") head(chem)# Examples write to a temporary cache, so running them cannot # disturb CTD data you have already imported. Set the same option # yourself to keep an analysis isolated from your main cache. options(ctdR.cache = tempfile()) sample_file <- system.file( "extdata", "CTD_chem_gene_ixns_sample.csv", package = "ctdR" ) import_CTD(sample_file) chem <- ctd_cache("chemicals") head(chem)
Returns the record of which CTD release produced a result: the
Report created date CTD stamps into its own file header, where
the file came from, when it was imported, and how much of it was kept.
An analysis is only reproducible if the version of the data behind it can be named. CTD is re-released continuously and its downloads are not versioned in the filename, so the release date inside the header is the only thing that identifies which snapshot a result came from. This carries it from the file all the way to the object you report on.
ctd_provenance(x) ## S3 method for class 'ctd_provenance' print(x, ...)ctd_provenance(x) ## S3 method for class 'ctd_provenance' print(x, ...)
x |
An object returned by |
... |
Ignored, present for compatibility with the generic. |
Where the record is stored depends on what the object is, because the
methods do not all return the same container. Objects that provide a
metadata() slot keep it there, which covers the
SummarizedExperiment returned by
GSVA and the DataFrame returned by importing a
CTDFile. The data frames returned by ORA, GSEA and
CAMERA, and a plain score matrix, have no such slot, so there it rides
on an attribute. Use this accessor rather than reaching for either
directly, so that code keeps working whichever method produced the
object.
The record survives subsetting, ordering, head() and the common
dplyr verbs. It does not survive merge() or
subset(), which drop attributes; retrieve it before those if you
need it afterwards.
An object of class ctd_provenance: a list with
report_created (the CTD release string, NA if the file
carried none), source, accessed, n_chemicals,
n_interactions and ctdR_version. Returns NULL,
with a warning, when x carries no record.
import_CTD, which reads the record, and
enrichment_CTD, which attaches it to its results.
# Examples write to a temporary cache, so running them cannot # disturb CTD data you have already imported. Set the same option # yourself to keep an analysis isolated from your main cache. options(ctdR.cache = tempfile()) sample_file <- system.file( "extdata", "CTD_chem_gene_ixns_sample.csv", package = "ctdR" ) import_CTD(sample_file) genes <- data.frame( EntrezID = c("7124", "3569", "7157", "672", "1956"), pvalue = c(0.001, 0.003, 0.01, 0.02, 0.05) ) # Which release is cached, before running anything: ctd_provenance() res <- enrichment_CTD(genes, method = "ORA") ctd_provenance(res)# Examples write to a temporary cache, so running them cannot # disturb CTD data you have already imported. Set the same option # yourself to keep an analysis isolated from your main cache. options(ctdR.cache = tempfile()) sample_file <- system.file( "extdata", "CTD_chem_gene_ixns_sample.csv", package = "ctdR" ) import_CTD(sample_file) genes <- data.frame( EntrezID = c("7124", "3569", "7157", "672", "1956"), pvalue = c(0.001, 0.003, 0.01, 0.02, 0.05) ) # Which release is cached, before running anything: ctd_provenance() res <- enrichment_CTD(genes, method = "ORA") ctd_provenance(res)
CTDFile is a BiocFile subclass representing a
Comparative Toxicogenomics Database (CTD) chemical-gene interactions file
(CTD_chem_gene_ixns.csv or its gzip-compressed .csv.gz form).
Pair it with import to read the file into R following
the Bioconductor BiocIO import/export convention, as an alternative to
the side-effecting import_CTD caching workflow.
In ctdR, CTD always denotes the Comparative
Toxicogenomics Database (https://ctdbase.org). The class is named
CTDFile (not CTD) to avoid confusion with unrelated software
that shares the acronym (the CRAN package CTD is a graph algorithm; the
ctd object in EWCE is a cell-type dataset).
CTDFile(resource) ## S4 method for signature 'CTDFile,ANY,ANY' import(con, format, text, ...)CTDFile(resource) ## S4 method for signature 'CTDFile,ANY,ANY' import(con, format, text, ...)
resource |
Character scalar: a local path or a URL to the CTD chemical-gene interactions file. |
con |
A |
format |
Ignored; present for compatibility with the BiocIO
|
text |
Ignored; present for compatibility with the BiocIO
|
... |
Additional arguments (currently unused). |
CTDFile() returns a CTDFile object. import() on a
CTDFile returns a DataFrame of validated
human (OrganismID 9606) CTD chemical-gene interactions.
This package does not bundle or redistribute any CTD data. The Comparative Toxicogenomics Database is maintained by NC State University and its data are subject to specific licensing terms. Users are responsible for downloading the data directly from https://ctdbase.org and for complying with the CTD Terms of Service (https://ctdbase.org/about/legal.jsp).
import_CTD for the caching workflow required before
enrichment_CTD; BiocFile for the parent
class.
sample_file <- system.file( "extdata", "CTD_chem_gene_ixns_sample.csv", package = "ctdR" ) ctd_file <- CTDFile(sample_file) ctd_file interactions <- BiocIO::import(ctd_file) head(interactions)sample_file <- system.file( "extdata", "CTD_chem_gene_ixns_sample.csv", package = "ctdR" ) ctd_file <- CTDFile(sample_file) ctd_file interactions <- BiocIO::import(ctd_file) head(interactions)
Identifies chemicals whose known gene targets are significantly enriched in a user-supplied gene list or expression matrix, using data from the Comparative Toxicogenomics Database (CTD).
Four methods are available:
Over-Representation Analysis (default). Tests whether
the overlap between your gene list and each chemical's target genes is
larger than expected by chance. Uses a hypergeometric test
computed directly on phyper.
Input: data frame with column EntrezID (character or
numeric Entrez gene IDs) and an optional numeric value column.
Gene Set Enrichment Analysis. Uses a ranked gene list
(ranked by the numeric column in the input, e.g. p-values or fold
changes) to detect chemicals whose targets cluster toward the top or
bottom of the ranking. Uses fgsea.
Competitive gene-set test accounting for
inter-gene correlation. Uses camera.
Input: a numeric expression matrix (genes x samples) or a
SummarizedExperiment, plus a
design matrix and a contrast.
Gene Set Variation Analysis (sample-level scoring).
Returns per-sample enrichment scores for each chemical, suitable for
downstream clustering or association testing.
Uses gsva.
Input: a numeric expression matrix (genes x samples) or a
SummarizedExperiment, which is
also the container the scores are returned in.
enrichment_CTD( x, method = c("ORA", "GSEA", "CAMERA", "GSVA"), design = NULL, contrast = NULL, id_type = NULL, pAdjustMethod = "BH", interaction_types = NULL, gene_id_type = c("symbol", "entrez"), universe = NULL, alpha = NULL, alpha_column = NULL, assay = NULL, ... )enrichment_CTD( x, method = c("ORA", "GSEA", "CAMERA", "GSVA"), design = NULL, contrast = NULL, id_type = NULL, pAdjustMethod = "BH", interaction_types = NULL, gene_id_type = c("symbol", "entrez"), universe = NULL, alpha = NULL, alpha_column = NULL, assay = NULL, ... )
x |
The input. Its expected type depends on
|
method |
Character. Enrichment method: |
design |
Design matrix (required when |
contrast |
Contrast specification for |
id_type |
Either |
pAdjustMethod |
Character. Multiple-testing correction applied to the
raw p-values, passed to |
interaction_types |
Character vector of CTD |
gene_id_type |
Character. Identifier type used in the |
universe |
Background gene identifiers for This is the input that decides whether an ORA result means anything. A background wider than what the experiment could detect fills the urn with genes that could never have been drawn, so the overlap looks more selective than it was and p-values come out too small. The error is anti-conservative. On the RNA-seq example bundled with this package, the fallback background returns 32 chemicals at FDR < 0.05 and the correct one returns 19. ORA is the only method that needs this argument, and the reason is
the shape of its input. A bare gene list carries no record of what
was measurable, so the background has to be supplied separately.
GSEA ranks the whole list you give it, which is already the
background; |
alpha |
Significance threshold for Every row of the table becomes the background, the selected genes
included: a hypergeometric test draws This is the safer way to run ORA, because the background is then
derived from the same object as the gene list and cannot disagree
with it. Filtering first and passing Name the column to threshold with Mutually exclusive with |
alpha_column |
Which column |
assay |
Which assay to use when |
... |
Additional arguments forwarded to the underlying engine:
|
Before calling this function you must import the CTD data once with
import_CTD. If the cached data is not found, the function
stops with an informative error message.
For "ORA", "GSEA", and "CAMERA": a data frame
of enrichment results sorted by PValueAdjusted ascending. All
three methods share the leading columns ChemicalID,
ChemicalName, Method, PValue,
PValueAdjusted; method-specific extras follow (see the
package vignette for the full per-method schema).
For "GSVA": enrichment scores with chemicals (CTD chemical
IDs) in rows and samples in columns. The container follows the input:
a matrix in returns a numeric matrix, while a
SummarizedExperiment in returns a
SummarizedExperiment whose assay holds the scores and whose
colData is carried over from the input, so sample annotation
stays attached to the results.
This package does not bundle or redistribute any CTD data. The Comparative Toxicogenomics Database is maintained by NC State University and its data are subject to specific licensing terms. Users must download the data directly from https://ctdbase.org and comply with the CTD Terms of Service (https://ctdbase.org/about/legal.jsp).
import_CTD to import and cache the CTD data;
plot_CTD to visualize results.
# Import the bundled sample data first: # Examples write to a temporary cache, so running them cannot # disturb CTD data you have already imported. Set the same option # yourself to keep an analysis isolated from your main cache. options(ctdR.cache = tempfile()) sample_file <- system.file( "extdata", "CTD_chem_gene_ixns_sample.csv", package = "ctdR" ) import_CTD(sample_file) # ORA / GSEA: prepare a gene list with Entrez IDs and a numeric value genes <- data.frame( EntrezID = c("7124", "3569", "7157", "672", "1956"), pvalue = c(0.001, 0.003, 0.01, 0.02, 0.05) ) ora_results <- enrichment_CTD(genes, method = "ORA") gsea_results <- enrichment_CTD(genes, method = "GSEA") # CAMERA / GSVA: expression data plus, for CAMERA, design + contrast. # Uses the bundled GSE311566 subset, a SummarizedExperiment # (Dex vs DMSO, female PBMCs; see inst/extdata/README.md). se <- readRDS(system.file( "extdata", "GSE311566_subset.rds", package = "ctdR" )) d <- model.matrix(~ se$group) camera_results <- enrichment_CTD(se, method = "CAMERA", design = d, contrast = 2) # GSVA: SummarizedExperiment in, SummarizedExperiment out, # so the sample annotation stays attached to the scores. gsva_scores <- enrichment_CTD(se, method = "GSVA") SummarizedExperiment::colData(gsva_scores)$group# Import the bundled sample data first: # Examples write to a temporary cache, so running them cannot # disturb CTD data you have already imported. Set the same option # yourself to keep an analysis isolated from your main cache. options(ctdR.cache = tempfile()) sample_file <- system.file( "extdata", "CTD_chem_gene_ixns_sample.csv", package = "ctdR" ) import_CTD(sample_file) # ORA / GSEA: prepare a gene list with Entrez IDs and a numeric value genes <- data.frame( EntrezID = c("7124", "3569", "7157", "672", "1956"), pvalue = c(0.001, 0.003, 0.01, 0.02, 0.05) ) ora_results <- enrichment_CTD(genes, method = "ORA") gsea_results <- enrichment_CTD(genes, method = "GSEA") # CAMERA / GSVA: expression data plus, for CAMERA, design + contrast. # Uses the bundled GSE311566 subset, a SummarizedExperiment # (Dex vs DMSO, female PBMCs; see inst/extdata/README.md). se <- readRDS(system.file( "extdata", "GSE311566_subset.rds", package = "ctdR" )) d <- model.matrix(~ se$group) camera_results <- enrichment_CTD(se, method = "CAMERA", design = d, contrast = 2) # GSVA: SummarizedExperiment in, SummarizedExperiment out, # so the sample annotation stays attached to the scores. gsva_scores <- enrichment_CTD(se, method = "GSVA") SummarizedExperiment::colData(gsva_scores)$group
Parses, filters, and caches the CTD chemical-gene interactions file so that
it can be used by enrichment_CTD. This function must be called
once before running any enrichment analysis.
The raw data file must be downloaded manually from the CTD website. The required file is CTD_chem_gene_ixns.csv.gz, available at https://ctdbase.org/reports/CTD_chem_gene_ixns.csv.gz.
import_CTD(file_path)import_CTD(file_path)
file_path |
Character. A local path or a URL to the CTD
chemical-gene interactions file ( |
Processing steps performed by import_CTD:
Reads the CSV, skipping the 27 CTD header lines.
Filters interactions to Homo sapiens only (OrganismID 9606).
For each chemical, collects the associated Entrez gene IDs.
Maps Entrez IDs to HGNC gene symbols via org.Hs.eg.db.
Saves four cached objects via BiocFileCache:
chemicals, ChemicalName_GeneEntrezIds,
ChemicalName_GeneSymbols, and ctd_interactions
(a long-format table of chemical–gene–action triples used by
enrichment_CTD(interaction_types = ...)).
The cache is managed by BiocFileCache under
tools::R_user_dir("ctdR", "cache"). To re-import (e.g. after
downloading a newer CTD release), simply call import_CTD() again —
existing cache resources are overwritten.
Filtering by interaction type (e.g., to retain only
"increases^expression" interactions) is done at enrichment time via
the interaction_types argument of enrichment_CTD,
not here — so a single import supports any combination of filters without
re-running this step.
Invisible NULL. Called for its side effect of caching the
processed data.
This package does not bundle or redistribute any CTD data. The Comparative Toxicogenomics Database is maintained by NC State University and its data are subject to specific licensing terms. Users are responsible for downloading the data directly from https://ctdbase.org and for complying with the CTD Terms of Service (https://ctdbase.org/about/legal.jsp). By using this function you acknowledge that you have read and accepted those terms.
enrichment_CTD for running enrichment analysis after
import, including the interaction_types filter.
# Examples write to a temporary cache, so running them cannot # disturb CTD data you have already imported. Set the same option # yourself to keep an analysis isolated from your main cache. options(ctdR.cache = tempfile()) sample_file <- system.file( "extdata", "CTD_chem_gene_ixns_sample.csv", package = "ctdR" ) import_CTD(sample_file)# Examples write to a temporary cache, so running them cannot # disturb CTD data you have already imported. Set the same option # yourself to keep an analysis isolated from your main cache. options(ctdR.cache = tempfile()) sample_file <- system.file( "extdata", "CTD_chem_gene_ixns_sample.csv", package = "ctdR" ) import_CTD(sample_file)
Visualizes the output of enrichment_CTD. The function
auto-detects the enrichment method from the input class and column
structure:
ORA / GSEA (data frame with Count or
NES): bar or dot plot of fold enrichment.
CAMERA (data frame with Direction and NGenes):
bar or dot plot of , colored by
direction of enrichment.
GSVA (numeric matrix chemicals x samples, or a
SummarizedExperiment wrapping
one): heatmap of per-sample enrichment scores for the top-N chemicals
selected by score variance across samples.
plot_CTD(results, type = "bar", n = 20, title = NULL)plot_CTD(results, type = "bar", n = 20, title = NULL)
results |
A data frame, a numeric matrix, or a
|
type |
Character. Plot type for tabular results:
|
n |
Integer. Number of top chemicals to display (default 20).
Selection criterion: ascending |
title |
Character. Plot title. If |
A ggplot2 object.
# Examples write to a temporary cache, so running them cannot # disturb CTD data you have already imported. Set the same option # yourself to keep an analysis isolated from your main cache. options(ctdR.cache = tempfile()) sample_file <- system.file( "extdata", "CTD_chem_gene_ixns_sample.csv", package = "ctdR" ) import_CTD(sample_file) # ORA / GSEA genes <- data.frame( EntrezID = c("7124", "3569", "7157", "672", "1956"), pvalue = c(0.001, 0.003, 0.01, 0.02, 0.05) ) ora_results <- enrichment_CTD(genes, method = "ORA") plot_CTD(ora_results, type = "bar") plot_CTD(ora_results, type = "dot") # GSVA scores: the heatmap accepts either the score matrix or the # SummarizedExperiment that enrichment_CTD() returns for an SE input. se <- readRDS(system.file( "extdata", "GSE311566_subset.rds", package = "ctdR" )) gsva_scores <- enrichment_CTD(se, method = "GSVA") plot_CTD(gsva_scores)# Examples write to a temporary cache, so running them cannot # disturb CTD data you have already imported. Set the same option # yourself to keep an analysis isolated from your main cache. options(ctdR.cache = tempfile()) sample_file <- system.file( "extdata", "CTD_chem_gene_ixns_sample.csv", package = "ctdR" ) import_CTD(sample_file) # ORA / GSEA genes <- data.frame( EntrezID = c("7124", "3569", "7157", "672", "1956"), pvalue = c(0.001, 0.003, 0.01, 0.02, 0.05) ) ora_results <- enrichment_CTD(genes, method = "ORA") plot_CTD(ora_results, type = "bar") plot_CTD(ora_results, type = "dot") # GSVA scores: the heatmap accepts either the score matrix or the # SummarizedExperiment that enrichment_CTD() returns for an SE input. se <- readRDS(system.file( "extdata", "GSE311566_subset.rds", package = "ctdR" )) gsva_scores <- enrichment_CTD(se, method = "GSVA") plot_CTD(gsva_scores)