Introduction

This vignette provides basic steps for interacting with RaMP-DB (Relational database of Metabolomic Pathways). RaMP-DB pulls aggregates annotations from HMDB, LIPID MAPS®, WikiPathways, Reactome, CheBI, PFOCR, RefMet, and the Rhea reaction database. The resource represents >250,000 metabolites, ~34,000 genes/proteins, >122,000 pathways, and > 66,000 reactions. Annotations include biological pathways, chemical classes and structures (for metabolites only), ontologies (metabolites only), and enzyme-metabolite relationships based on chemical reactions. The RaMP-DB R package supports queries and enrichment analyses for biochemical pathways, reactions, ontologies and chemical properties (chemical classes and chemical reactions).

Installation instructions can be found here. Once the R package is installed and loaded, the user has access to all versions of RaMP-DB within your local file cache and in our remote repository. To see a list of available versions, users can call the function listAvailableRaMPDbVersions().
Questions can be asked through the Issues tab in GitHub or by sending an email to NCATSRaMP@nih.gov.

Getting Started

The first step in using RaMP-DB is to initialize the RaMP-DB database object. The user can specify a specific version of the database to use and if not specified, the the most recent version of the database will be used. Initialization of the RaMP-DB object only needs to be performed once per R session and the object can then be passed on to RaMP-DB functions. If this object is not passed, the functions will initialize a new RaMP-DB instance every time they are called and this will take longer. We thus recommend creating the object once in the beginning and using it throughout.

Here’s how to do it:

# Load the library
library(RaMP)

# Load some other libraries that are useful for this vignette in displaying the data
if(!require("DT")) install.packages("DT")
library(DT) # for prettier tables in vignette
if(!require("dplyr")) install.packages("dplyr")
library(dplyr)
if(!require("magrittr")) install.packages("magrittr")
library(magrittr)

# List available RaMP-DB versions
listAvailableRaMPDbVersions()
## [1] "Locally available versions of RaMP SQLite DB, currently on your computer:"
## [1] "3.0.7" "2.6.5" "2.5.4" "2.3.1"
## [1] "Available remote RaMP SQLite DB versions for download:"
## [1] "3.0.7" "3.0.6" "2.5.4" "2.5.0" "2.4.3" "2.4.2" "2.4.0" "2.3.2" "2.3.1"
## [1] "The following RaMP Database versions are available for download:"
## [1] "3.0.6" "2.5.0" "2.4.3" "2.4.2" "2.4.0" "2.3.2"
## [1] "Use the command db <- RaMP(<new_version_number>) to download the specified version."
# Load a local RaMP-DB database or download the latest database version from the repository.
# If the version is not specified, the latest local version will be used.
# If there are no local databases cached, then the latest remote version will be downloaded.
rampDB <- RaMP()
# rampDB <- RaMP(branch="ramp3.0")

Preparing your input for RaMP-DB

Note that it is always preferable to utilize IDs rather then common names for metabolites. When entering IDs, prepend each ID with the database of origin followed by a colon, for example kegg:C02712, hmdb:HMDB04824, etc.. It is possible to input IDs using multiple different sources. RaMP-DB currently supports the following ID types:

  metabprefixes <- getPrefixesFromAnalytes("metabolite", db=rampDB)
  geneprefixes <- getPrefixesFromAnalytes("gene", db=rampDB)

  datatable(rbind(metabprefixes, geneprefixes))

Manually input analytes

Uesrs can create a vector of analytes (genes and metabolites) to query and then feed that into RaMP query or analysis functions. Here is an example:

# Create vector of analytes:
input_genes_mets <- c("ensembl:ENSG00000135679", "hmdb:HMDB0000064","hmdb:HMDB0000148", "ensembl:ENSG00000141510")
# Retrieve pathways containing these analytes:
mypathways <- getPathwayFromAnalyte(input_genes_mets, db=rampDB)
## [1] "Starting getPathwayFromAnalyte()"
## [1] "finished getPathwayFromAnalyte()"
## [1] "Found 2542 associated pathways."
datatable(mypathways)

Input analytes from external annotation file

Users can input external data sources of analytes using the function createRaMPInput(). This function will take as input a data.frame, .csv, or .xlsx. Each column includes IDs and is named by the corresponding ID type (e.g., kegg, hmdb, etc.). Only columns with ID sources existing in RaMP-DB (see above on preparing your input for RaMP-DB using the function getPrefixesFromAnalytes()) will be processed. An example input file can be found here.

Here’s an example of how to do this using the example input file:

# Retrieve the file path and name of the example data
dir   <- system.file("extdata", package="RaMP", mustWork=TRUE)
exInput <- file.path(dir, "ExampleRaMPInput.csv")

# Load in the data into RaMP-DB
exData <- createRaMPInput(filePath = exInput, db=rampDB)

# Now use this input to query pathways corresponding to those analytes
testids <- getPathwayFromAnalyte(analytes = exData, db=rampDB)

datatable(testids)

Exploring biological pathways and performing multi-omic pathway enrichment

Users can retrieve analytes from input pathways, retrieve pathways from input analytes, as well as perform multi-omic pathway enrichment. Importantly, RaMP-DB does not explicitly distinguish between genes and proteins when it comes to pathways.

Retrieve analytes from user input pathway(s)

Analytes belonging to a pathway can readily be retrieved by either inputting the exact pathway name or part of a pathway name for a fuzzy search. By default, the function getAnalyteFromPathway() returns both proteins/genes and metabolites involved. This can be modified with the parameter “analyteType”.

Here is an example:

myanalytes <- getAnalyteFromPathway(pathway="Sphingolipid metabolism", db=rampDB)
## [1] "fired!"
## [1] "Timing .."
##    user  system elapsed 
##   0.642   0.440   1.171
dim(myanalytes)
## [1] 297   7
datatable(head(myanalytes))
myanalytes <- getAnalyteFromPathway(pathway="Sphingolipid", db=rampDB, match = "fuzzy")
## [1] "fired!"
## [1] "Timing .."
##    user  system elapsed 
##   0.786   0.447   1.264
dim(myanalytes)
## [1] 3295    7
datatable(myanalytes)

To retrieve information from multiple pathways, simply input a vector of pathway names:

myanalytes <- getAnalyteFromPathway(pathway=c("Wnt Signaling Pathway", 
                                              "sphingolipid metabolism"), db=rampDB)

Retrieve pathways from user-input analyte(s)

It is oftentimes useful to get a sense of what pathways are represented in a dataset. This is particularly true for metabolomics where coverage of metabolites varies depending on what platform is used. In other cases, one may be interested in exploring one or several metabolites to see what pathways they are are presented in. By default, pathways with < 5 or > 150 analytes will not be returned. See the getPathwayFromAnalyte() documentation to change those defaults.

In this example, we will search for pathways that involve the two genes MDM2 and TP53, and the two metabolites glutamate and creatine. Note we are using their IDs for queries which is recommended (rather than using names).

mypathways <- getPathwayFromAnalyte(c("ensembl:ENSG00000135679", "hmdb:HMDB0000064","hmdb:HMDB0000148", "ensembl:ENSG00000141510"), db=rampDB)
## [1] "Starting getPathwayFromAnalyte()"
## [1] "finished getPathwayFromAnalyte()"
## [1] "Found 2542 associated pathways."
datatable(mypathways)

Each row returns a pathway attributed to each input analytes. To retrieve the number of unique pathways returned for all or each analyte, try the following:

print(paste("Number of Unique Pathways Returned for All Analytes:", 
            length(unique(mypathways$pathwayId))))
## [1] "Number of Unique Pathways Returned for All Analytes: 2353"
lapply(unique(mypathways$commonName), function(x) {
        (paste("Number of Unique Pathways Returned for",x,":",
                length(unique(mypathways[which(mypathways$commonName==x),]$pathwayId))))})
## [[1]]
## [1] "Number of Unique Pathways Returned for TP53 : 906"
## 
## [[2]]
## [1] "Number of Unique Pathways Returned for L-glutamate : 232"
## 
## [[3]]
## [1] "Number of Unique Pathways Returned for MDM2 : 1282"
## 
## [[4]]
## [1] "Number of Unique Pathways Returned for Creatine : 122"

Perform multi-omic pathway enrichment analyses

RaMP-DB performs pathway enrichment analysis using Fisher’s tests with the function runEnrichPathways().

Using the pathwaydfids data frame from our previous step, we can now run Fisher’s Exact test to identify pathways that are enriched for our analytes of interest:

myanalytes <- c("hmdb:HMDB0000033","hmdb:HMDB0000052","hmdb:HMDB0000094",
  "hmdb:HMDB0000161","hmdb:HMDB0000168","hmdb:HMDB0000191","hmdb:HMDB0000201",
  "chemspider:10026", "hmdb:HMDB0006059", "Chemspider:6405", "CAS:5657-19-2",
  "hmdb:HMDB0002511", "chemspider:20171375", "CAS:133-32-4", "CAS:5746-90-7",
  "CAS:477251-67-5", "hmdb:HMDB0000695", "chebi:15934", "CAS:838-07-3",
  "hmdb:HMDBP00789", "hmdb:HMDBP00283", "hmdb:HMDBP00284", "hmdb:HMDBP00850")

pathways.enriched <- runEnrichPathways(analytes = myanalytes , 
  db=rampDB)

Next, we can filter the pathways based on desired statistical significance cutoffs. For this example we will be using an FDR p-value cutoff of 0.05.

#Returning Fisher Pathways and P-Values
filtered.pathways.enriched <- filterEnrichResults(enrichResults=pathways.enriched, 
    pValType = 'holm', pValCutoff=0.05)
## [1] "Filtering Fisher Results..."

Because RaMP-DB combines pathways from multiple sources, pathways may be represented more than once (e.g., the TCA cycle is represented in many databases). Further, due to the hierarchical nature of pathways and because Fisher’s testing assumes pathways are independent, subpathways and their parent pathways may appear in a list.

To help group together pathways that represent same or similar biological processes, we have implemented a clustering algorithm that groups pathways together if they share analytes in common.

clusters <- findCluster(filtered.pathways.enriched,
  percAnalyteOverlap = 0.2, percPathwayOverlap = 0.2, db=rampDB)
## [1] "Clustering pathways..."
## [1] "Finished clustering pathways..."
datatable(clusters$fishresults %>% mutate_if(is.numeric, ~ round(., 8)),
  rownames = FALSE
)

See the findCluster() function documentation for a description of input parameters. We suggest trying different values of perc_analyte_overlap and perc_pathway_overlap to obtain meaningful clusters.

To plot pathway results with clusters, use the function plotPathwayResults() as follows:

plotPathwayResults(pathwaysSig=clusters,  interactive = TRUE, db=rampDB)
## The input pathway result has already been clustered. Defaulting to existing clustering.

Ontologies

RaMP-DB contains ontology annotations for metabolites, obtained from HMDB, which include the following categories: Biofluid and excreta, Organ and components, Subcellular location, Industrial applications, Source (e.g. plant/animal/microbial), Health Condition, Tissue and substructures.

Retrieve metabolites from user-input ontologies

The function getMetaFromOnto() retrieves metabolites that are associated with user-input ontology(ies).

ontologies.of.interest <- "Urine"
new.metabolites <- getMetaFromOnto(ontology = ontologies.of.interest, db=rampDB)
## [1] "Retreiving Metabolites for input ontology terms."
## [1] "Found 1 ontology term matches."
## [1] "Found 7351 metabolites associated with the input ontology terms."
## [1] "Finished getting metabolies from ontology terms."
# View the first 10 metabolites:
datatable(head(new.metabolites, n=10))

Retrieve ontologies from user-input metabolites

To retrieve ontologies that are associated with metabolites of interest, we can use getOntoFromMeta(). This function takes in a vector of metabolites as an input and returns associated ontologies.

analytes.of.interest <- c("chebi:15422", "hmdb:HMDB0000064",
        "hmdb:HMDB0000148", "wikidata:Q426660")
new.ontologies <- getOntoFromMeta(mets = analytes.of.interest, db=rampDB)
datatable(new.ontologies)

Perform ontology Enrichment Analyses

RaMP-DB performs ontology enrichment analysis using Fisher’s tests with the function runEnrichOntologies().

mets <- c("hmdb:HMDB0000033","hmdb:HMDB0000052","hmdb:HMDB0000094", "hmdb:HMDB0000161",
          "hmdb:HMDB0000168","hmdb:HMDB0000191","hmdb:HMDB0000201","chemspider:10026",
          "hmdb:HMDB0006059", "Chemspider:6405", "CAS:5657-19-2","hmdb:HMDB0002511",
          "chemspider:20171375","CAS:133-32-4", "CAS:5746-90-7", "CAS:477251-67-5",
          "hmdb:HMDB0000695", "chebi:15934", "CAS:838-07-3","hmdb:HMDBP00789",
          "hmdb:HMDBP00283", "hmdb:HMDBP00284", "hmdb:HMDBP00850")
ontologies.enriched <- runEnrichOntologies(mets = mets, 
  db=rampDB)

# Filter results based on user-input p-value cutoff:
filtered.ontologies.enriched <- filterEnrichResults(enrichResults=ontologies.enriched, 
    pValType = 'holm', pValCutoff=0.05)

datatable(filtered.ontologies.enriched$fishertresults)

Reactions

RaMP-DB pulls reaction information from Rhea and HMDB. Only human reactions are retrieved, including reaction classes, information on substrates and products, their enzymes (if any) as well as reaction direction. Both enzymatic and spontaenous biotransformations are represented.

The following analytics involving reactions can be performed: 1) retrieve analytes involved in the same reaction and visualize associated networks, 2) retrieve and interactively explore reaction classes and perform enrichment.

Retrieve analytes involved in the same reaction

Users may want to know what enzymes could catalyze reactions involving metabolites of interest and vice versa.

Users can input metabolites to retrieve associated enzymes or can input enzymes to return metabolites involved in the same chemical reactions. Again, using IDs is preferred over use of names. Reactions are retrieved from Rhea and HMDB. For Rhea queries, only UniProt (for proteins) and ChEBI (for metabolites) IDs are supported. Other ID types are supported for HMDB queries.

# Input Metabolites and Proteins
inputs.of.interest <- c("kegg:C00186" , "hmdb:HMDB0000148", "kegg:C00780", "hmdb:HMDB0000064", "ensembl:ENSG00000115850", "uniprot:Q99259")


catalyzedby.output <- rampFastCata(analytes = inputs.of.interest, db=rampDB)
## [1] "Analyte ID-based reaction partner query."
## [1] "Building metabolite to gene relations."
## [1] "Number of met2gene relations: 132"
## [1] "Building gene to metabolite relations."
## [1] "Total Relation Count: 144"
## [1] "There are no ChEBI metabolite IDs in the input. Skipping metabolite to protein query step."
#just show HMDB analyte associations
datatable(catalyzedby.output)

The enzyme-metabolite relationships retrieved with the rampFastCata() function can be visualized and explored as a network.

plotCataNetwork(catalyzedby.output)

Retrieve reactions from input analytes

Users may want to explore reactions and their classes given a list of analytes of interest. This could be helpful for building networks of analytes based on reaction involvement. Curated reactions from Rhea can be returned given a list of input analytes with the function getReactionsForAnalytes(). Users input a vector metabolite ChEBI ids and/or a vector of gene/protein UniProt IDs. The function returns a list with 3 slots:

  1. met2rxn: reactions involving input metabolites,
  2. prot2rxn: reactions involving input proteins, and
  3. metProteinCommonReactions: reactions that have at least one metabolite and one protein from the input analyte list.

For each list, the substrates, product, reaction direction and other information are returned.

analytes.of.interest = c('chebi:58115', 'chebi:456215', 'chebi:58245', 'chebi:58450',
             'chebi:17596', 'chebi:16335', 'chebi:16750', 'chebi:172878',
             'chebi:62286', 'chebi:77897', 'uniprot:P30566','uniprot:P30520',
             'uniprot:P00568', 'uniprot:P23109', 'uniprot:P22102', 'uniprot:P15531')
reactionsLists <- getReactionsForAnalytes(analytes = analytes.of.interest, db=rampDB)
## Running getReactionsForAnalytes()
## Reporting Function: getReactionsForAnalytes
## The input list has 16 IDs.
## The input list has 10 chebi IDs.
## The input list has 6 uniprot IDs.
## Finished getReactionsForAnalytes()
# Show the reactions with at least one metabolite and one protein from the input 
# list belonging to the same reaction:
datatable(subset(reactionsLists$metProteinCommonReactions))
# Show reactions involving input proteins:
# reactionsLists$prot2rxn
# Show reactions involving input metabolites:
# reactionsLists$met2rxn

Notice that the output returns the reaction classes for each reaction. The function plotAnalyteOverlapPerRxnLevel() generates an interactive UpSet plot showing the number of overlapping input analytes at each reaction class level 1.

plotAnalyteOverlapPerRxnLevel(reactionsLists)

Retrieve reaction classes from input analytes

RaMP-DB includes reaction classes and Enzyme Commission numbers (EC numbers) for enzymes involved in reactions from Rhea. These can be retrieved using the getReactionClassesForAnalytes() given a user input vector metabolite ChEBI ids and/or a vector of gene/protein UniProt IDs. The function outputs a list with the following 4 slots, each summarizing the number of proteins and metabolites corresponding to each reaction class level. with reaction class information 1) class_ec_level_1: main division/class of the enzyme classification 2) class_ec_level_2: subclass of the enzyme classification 3) class_ec_level_3: sub-subclasss of the enzyme classification 4) class_ec_level_4: serial number in the sub-subclass of the enzyme classification

For more information on the classes, please visit the Rhea documentation on the EC numbers.

analytes.of.interest = c('chebi:58115', 'chebi:456215', 'chebi:58245', 'chebi:58450',
             'chebi:17596', 'chebi:16335', 'chebi:16750', 'chebi:172878',
             'chebi:62286', 'chebi:77897', 'uniprot:P30566','uniprot:P30520',
             'uniprot:P00568', 'uniprot:P23109', 'uniprot:P22102', 'uniprot:P15531')
reaction.classes <- getReactionClassesForAnalytes(analytes = analytes.of.interest, db=rampDB)
## [1] "Starting reaction class query..."
## Reporting Function: getReactionClassesForAnalytes
## The input list has 16 IDs.
## The input list has 10 chebi IDs.
## The input list has 6 uniprot IDs.
## [1] "Passed the getReactionClassStats"
## [1] "Completed reaction class query..."

The retrieved reaction classes can be visualized from an interactive sunburst plot, allowing users to explore the reaction classes represented by their data as well as their associated analytes.

plotReactionClasses(reaction.classes)

Perform reaction class enrichment

RaMP-DB performs reaction class enrichment analysis using Fisher’s tests with the function runEnrichReactionClass(). Similar to the other functions related to reaction classes, input IDs supported are ChEBI for metabolites and UniProt for proteins.

rxn.enriched <- runEnrichReactionClass(analytes = analytes.of.interest, db=rampDB)
## Reporting Function: getReactionClassesForAnalytes
## The input list has 16 IDs.
## The input list has 10 chebi IDs.
## The input list has 6 uniprot IDs.
# Filter results based on p-values:
filtered.rxn.enriched <- filterEnrichResults(enrichResults = rxn.enriched, pValType = 'holm', pValCutoff=0.05)

Chemical Descriptors

Users can retrieve chemical classes and chemical property information from input metabolites, as well as perform chemical class enrichment. These anlyses are coplementary to pathway analyses.

Retrieve Chemical Classes from Input Metabolites

RaMP incorporates ClassyFire and LIPID MAPS® classes. The function getChemClass() takes as input a vector of metabolites and outputs the classes associated with each metabolite. For more information on ClassyFire classes, visit here. For more information on LIPID MAPS® classes, visit here.

metabolites.of.interest = c("pubchem:64969", "chebi:16958", "chemspider:20549", "kegg:C05598", "chemspider:388809", "pubchem:53861142", "hmdb:HMDB0001138", "hmdb:HMDB0029412")
chemical.classes <- getChemClass(mets = metabolites.of.interest, db=rampDB)
## [1] "Starting Chemical Class Survey"
## [1] "...finished metabolite list query..."
## [1] "...finished DB population query..."
## [1] "...collating data..."
## [1] "...creating query efficiency summary..."
## [1] "Finished Chemical Class Survey"
metabolite.classes <- as.data.frame(chemical.classes$met_classes)
datatable(metabolite.classes)

Retrieve chemical property information from input metabolites

Chemical properties captured by RaMP-DB include SMILES, InChI, InChI-keys, monoisotopic masses, molecular formula, and common name. The getChemicalProperties() function takes as input a vector of metabolites and outputs a list of chemical property information.

chemical.properties <- getChemicalProperties(metabolites.of.interest, db=rampDB)
## Starting Chemical Property Query
## Finished Chemical Property Query
chemical.data <- chemical.properties$chem_props
datatable(chemical.data)

Chemical class enrichment analyses

RaMP-DB performs chemical class enrichment analysis using Fisher’s tests with the function runEnrichChemClass(). The function performs enrichment analysis for ClassyFire classes, sub-classes, and super-classes, and for LIPID MAPS® categories, main classes, and sub-classes. The function returns a list with enrichment results for each relevant class (depends on the input metabolites retrieved).

metabolites.of.interest = c("pubchem:64969", "chebi:16958", "chemspider:20549", "kegg:C05598", 
    "chemspider:388809", "pubchem:53861142", "hmdb:HMDB0001138", "hmdb:HMDB0029412")
chemClass.enrichment <- runEnrichChemClass(mets = metabolites.of.interest, db=rampDB)
## [1] "Starting Chemical Class Enrichment"
## [1] "Starting Chemical Class Survey"
## [1] "...finished metabolite list query..."
## [1] "...finished DB population query..."
## [1] "...collating data..."
## [1] "...creating query efficiency summary..."
## [1] "Finished Chemical Class Survey"
## [1] "check total summary"
## [1] "getting population totals"
## [1] "Finished Chemical Class Enrichment"
# Enrichment was performed on the following chemical classes:
names(chemClass.enrichment)
## [1] "ClassyFire_class"       "ClassyFire_sub_class"   "ClassyFire_super_class"
## [4] "result_type"
# To retrieve results for the ClassyFire Class:
classy_fire_classes <- chemClass.enrichment$ClassyFire_class
datatable(classy_fire_classes)

Connect to Different Versions of RaMP

Users are able to download previous versions of RaMP, and can input queries in these earlier versions. This may be useful for reproducing past results since annotations are added or changed since updated versions have been posted.

#Example query for earlier version
Alternate.db <- RaMP('2.3.1')
Alternate.Ramp <- getAnalyteFromPathway(db = Alternate.db, pathway = c('Pentose Phosphate Pathway'))
datatable(Alternate.Ramp)

#Example query for current version
Current.db <- RaMP('2.5.4')
path.search <- getAnalyteFromPathway(db = Current.db, pathway = c('Pentose Phosphate Pathway'))
datatable(path.search)
sessionInfo()
## R version 4.5.1 (2025-06-13)
## Platform: aarch64-apple-darwin20
## Running under: macOS Sonoma 14.7
## 
## Matrix products: default
## BLAS:   /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRblas.0.dylib 
## LAPACK: /Library/Frameworks/R.framework/Versions/4.5-arm64/Resources/lib/libRlapack.dylib;  LAPACK version 3.12.1
## 
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
## 
## time zone: America/New_York
## tzcode source: internal
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] magrittr_2.0.3 dplyr_1.1.4    DT_0.33        RaMP_3.0.2    
## 
## loaded via a namespace (and not attached):
##  [1] gtable_0.3.6         xfun_0.52            bslib_0.9.0         
##  [4] ggplot2_3.5.2        htmlwidgets_1.6.4    visNetwork_2.1.2    
##  [7] lattice_0.22-7       vctrs_0.6.5          tools_4.5.1         
## [10] crosstalk_1.2.1      generics_0.1.4       curl_6.4.0          
## [13] Polychrome_1.5.4     tibble_3.3.0         RSQLite_2.4.2       
## [16] blob_1.2.4           janeaustenr_1.0.0    pkgconfig_2.0.3     
## [19] tokenizers_0.3.0     Matrix_1.7-3         data.table_1.17.8   
## [22] dbplyr_2.5.0         RColorBrewer_1.1-3   scatterplot3d_0.3-44
## [25] lifecycle_1.0.4      compiler_4.5.1       farver_2.1.2        
## [28] htmltools_0.5.8.1    SnowballC_0.7.1      sass_0.4.10         
## [31] yaml_2.3.10          lazyeval_0.2.2       tidytext_0.4.3      
## [34] plotly_4.11.0        pillar_1.11.0        jquerylib_0.1.4     
## [37] tidyr_1.3.1          upsetjs_1.11.1       cachem_1.1.0        
## [40] tidyselect_1.2.1     digest_0.6.37        stringi_1.8.7       
## [43] purrr_1.1.0          labeling_0.4.3       fastmap_1.2.0       
## [46] grid_4.5.1           colorspace_2.1-1     cli_3.6.5           
## [49] dichromat_2.0-0.1    withr_3.0.2          filelock_1.0.3      
## [52] scales_1.4.0         bit64_4.6.0-1        rmarkdown_2.29      
## [55] httr_1.4.7           bit_4.6.0            memoise_2.0.1       
## [58] evaluate_1.0.4       knitr_1.50           BiocFileCache_2.16.1
## [61] viridisLite_0.4.2    rlang_1.1.6          Rcpp_1.1.0          
## [64] glue_1.8.0           DBI_1.2.3            rstudioapi_0.17.1   
## [67] jsonlite_2.0.0       R6_2.6.1