The drugTargetInteractions package provides utilities for identifying
drug-target interactions starting from either a gene/protein identifier
(target → drug) or a compound identifier (drug → target). It
covers seven independent drug-target data sources - ChEMBL
(Gaulton et al. 2012; Bento et al. 2014), PubChem,
DGIdb, Open Targets,
the Therapeutic Target Database (TTD), the
Broad Institute Drug Repurposing Hub
(CLUE) and the IUPHAR/BPS Guide to PHARMACOLOGY
(GtoPdb) - each queried through its own live REST/GraphQL API or, for TTD,
the Repurposing Hub and GtoPdb, a small local SQLite built from public
bulk data. ChEMBL remains additionally available through a downloaded
local SQLite instance for users who prefer that (see the Supplement).
Six of these (ChEMBL, DGIdb, Open Targets, TTD, Broad Repurposing Hub,
GtoPdb) provide curated drug-target annotations - an expert-curated call
that a drug acts on a target via some mechanism - and are queried the same
way via queryDrugTargets()/combineDrugTargets() (see Cross-Source
Queries). PubChem instead provides raw bioassay measurements
(individual assay results, no mechanism claim attached) - a genuinely
different kind of data, covered separately in Bioassay Queries alongside
ChEMBL’s own bioassay function, getChemblBioassay().
Because every source has its own native identifier vocabulary (a ChEMBL
molecule ID is not a PubChem CID is not a DrugBank ID), the package also
provides a generic ID-translation layer: live services for mapping
protein/gene identifiers (UniProt’s REST ID
Mapping API (Wu et al. 2006)) and finding paralogs/orthologs
(Ensembl’s homology REST API), plus a local
SQLite built from UniChem’s bulk compound
cross-reference table for translating between compound ID types (ChEMBL,
PubChem, DrugBank, ChEBI, and more). A dispatcher function,
queryDrugTargets(), ties all of this together: give it an identifier of
any recognised type and it resolves that identifier to whatever native ID
each requested source needs, queries one or more sources, and returns the
results.
This vignette is organised as follows:
queryDrugTargets() across one or many
sources at once, performance guidance, and combining results into a
single table.As Bioconductor package drugTargetInteraction can be installed with the BiocManager::install() function.
if (!requireNamespace("BiocManager", quietly = TRUE))
install.packages("BiocManager")
BiocManager::install("drugTargetInteractions")
Alternatively, the package can be installed from GitHub as follows.
devtools::install_github("girke-lab/drugTargetInteractions", build_vignettes=TRUE) # Installs from github
library("drugTargetInteractions") # Loads the package
library(help="drugTargetInteractions") # Lists package info
vignette(topic="drugTargetInteractions", package="drugTargetInteractions") # Opens vignette
This section is meant to be read (and run) in about five minutes. It uses only sources that need no local database setup, so every chunk here works immediately after installing the package - no downloads beyond the live API calls themselves.
Every per-source function uses the same queryBy = list(molType, idType, ids) interface. Target → drug for the FGFR1 gene via ChEMBL:
getChemblDrugTarget(list(molType = "protein", idType = "Uniprot", ids = "P11362"))[
, c("QueryIDs", "Drug_Name", "Action_Type", "Max_Phase")]
## QueryIDs Drug_Name Action_Type Max_Phase
## 1 P11362 PAZOPANIB HYDROCHLORIDE INHIBITOR 4
## 2 P11362 INFIGRATINIB PHOSPHATE INHIBITOR 4
## 3 P11362 INFIGRATINIB INHIBITOR 4
## 4 P11362 REGORAFENIB INHIBITOR 4
## 5 P11362 RG-1530 INHIBITOR 1
## 6 P11362 LUCITANIB INHIBITOR 2
## 7 P11362 BRIVANIB ALANINATE INHIBITOR 3
## 8 P11362 ORANTINIB INHIBITOR 3
## 9 P11362 NINTEDANIB ESYLATE INHIBITOR 4
## 10 P11362 FEXAGRATINIB INHIBITOR 2
## 11 P11362 PD-0166285 HYDROCHLORIDE INHIBITOR 1
## 12 P11362 CP-459632 INHIBITOR 1
## 13 P11362 ERDAFITINIB INHIBITOR 4
## 14 P11362 E-7090 INHIBITOR 2
## 15 P11362 FUTIBATINIB INHIBITOR 4
## 16 P11362 BRIVANIB INHIBITOR 3
## 17 P11362 LY-2874455 INHIBITOR 1
## 18 P11362 FGFR INHIBITOR DEBIO 1347 INHIBITOR 2
## 19 P11362 ROGARATINIB INHIBITOR 2
## 20 P11362 TG100-801 INHIBITOR 2
## 21 P11362 DERAZANTINIB INHIBITOR 2
## 22 P11362 SURUFATINIB INHIBITOR 3
## 23 P11362 PEMIGATINIB INHIBITOR 4
## 24 P11362 HMPL-453 INHIBITOR 2
## 25 P11362 ENMD-981693 INHIBITOR 2
## 26 P11362 XL-999 INHIBITOR 2
The reverse direction (drug → target) uses the same function with
molType = "cmp":
getChemblDrugTarget(list(molType = "cmp", idType = "chembl_id", ids = "CHEMBL1421"))[ # dasatinib
, c("QueryIDs", "UniProt_ID", "Action_Type")]
## QueryIDs UniProt_ID Action_Type
## 1 CHEMBL1421 P00519 INHIBITOR
## 2 CHEMBL1421 P09619 INHIBITOR
## 3 CHEMBL1421 P10721 INHIBITOR
## 4 CHEMBL1421 P29317 INHIBITOR
## 5 CHEMBL1421 P00519 INHIBITOR
## 6 CHEMBL1421 P11274 INHIBITOR
## 7 CHEMBL1421 P06239 INHIBITOR
## 8 CHEMBL1421 P07947 INHIBITOR
## 9 CHEMBL1421 P06241 INHIBITOR
## 10 CHEMBL1421 P12931 INHIBITOR
## 11 CHEMBL1421 P07948 INHIBITOR
## 12 CHEMBL1421 P42685 INHIBITOR
## 13 CHEMBL1421 P51451 INHIBITOR
## 14 CHEMBL1421 P08631 INHIBITOR
## 15 CHEMBL1421 P09769 INHIBITOR
## 16 CHEMBL1421 Q9H3Y6 INHIBITOR
queryDrugTargets() accepts an identifier of essentially any type (not
just each source’s own native ID - see ID Translation Layer) and queries
as many sources as you like in one call:
res <- queryDrugTargets(
list(molType = "gene", idType = "symbol", ids = "FGFR1"),
sources = c("chembl", "dgidb", "opentargets"))
names(res) # one data.frame per source that returned results
## [1] "chembl" "dgidb" "opentargets"
sapply(res, nrow)
## chembl dgidb opentargets
## 26 143 94
res above is a list - each source keeps its own native columns. To see
one aligned table across sources, use combineDrugTargets():
combineDrugTargets(res)[1:6, ]
## query_id gene_symbol drug_name action source
## 1 FGFR1 <NA> PAZOPANIB HYDROCHLORIDE INHIBITOR ChEMBL
## 2 FGFR1 <NA> INFIGRATINIB PHOSPHATE INHIBITOR ChEMBL
## 3 FGFR1 <NA> INFIGRATINIB INHIBITOR ChEMBL
## 4 FGFR1 <NA> REGORAFENIB INHIBITOR ChEMBL
## 5 FGFR1 <NA> RG-1530 INHIBITOR ChEMBL
## 6 FGFR1 <NA> LUCITANIB INHIBITOR ChEMBL
That is the essential workflow: pick an identifier, pick one or more sources, query, optionally combine. The rest of this vignette covers each piece in more detail.
Each source below is queried through its own bidirectional function, using
that source’s native identifier types directly. queryDrugTargets()
(see Cross-Source Queries) builds on top of these by resolving other
identifier types first.
ChEMBL (Gaulton et al. 2012; Bento et al. 2014) is queried live through its REST
API via getChemblDrugTarget(). Native identifiers: a UniProt
accession for target → drug, a ChEMBL molecule ID for drug
→ target.
chembl_t2d <- getChemblDrugTarget(
list(molType = "protein", idType = "Uniprot", ids = "P11362")) # FGFR1
head(chembl_t2d[, c("Drug_Name", "MOA", "Action_Type", "Max_Phase")])
## Drug_Name MOA Action_Type Max_Phase
## 1 PAZOPANIB HYDROCHLORIDE Fibroblast growth factor receptor 1 inhibitor INHIBITOR 4
## 2 INFIGRATINIB PHOSPHATE Fibroblast growth factor receptor inhibitor INHIBITOR 4
## 3 INFIGRATINIB Fibroblast growth factor receptor inhibitor INHIBITOR 4
## 4 REGORAFENIB Fibroblast growth factor receptor 1 inhibitor INHIBITOR 4
## 5 RG-1530 Fibroblast growth factor receptor 1 inhibitor INHIBITOR 1
## 6 LUCITANIB Fibroblast growth factor receptor 1 inhibitor INHIBITOR 2
chembl_d2t <- getChemblDrugTarget(
list(molType = "cmp", idType = "chembl_id", ids = "CHEMBL25")) # aspirin
chembl_d2t[, c("UniProt_ID", "Organism", "MOA")]
## UniProt_ID Organism MOA
## 1 P35354 Homo sapiens Cyclooxygenase inhibitor
## 2 P23219 Homo sapiens Cyclooxygenase inhibitor
Large ID batches are chunked automatically (see Performance Considerations).
Standalone helpers are also available: getChemblMolecule() (compound
properties), getChemblTarget() (search targets by gene/protein name), and
getChemblBioactivities() (raw IC50/Ki/Kd/EC50 measurements for one
target).
The Drug Gene Interaction Database is queried through its GraphQL API via
getDgidbDrugTarget(). DGIdb’s schema is bidirectional by construction - a
single interactions() query returns nodes that already carry both a gene
and a drug identity - so both directions use the same underlying query,
just filtered by a different argument. Native identifiers: a gene
symbol or a drug name, both matched case-insensitively.
dgidb_t2d <- getDgidbDrugTarget(
list(molType = "gene", idType = "symbol", ids = "FGFR1"))
head(dgidb_t2d[, c("drug_name", "interaction_types", "sources")])
## drug_name interaction_types sources
## 1 DERAZANTINIB inhibitor TdgClinicalTrial; CKB-CORE; GuideToPharmacology; TTD
## 2 ENMD-981693 inhibitor ChEMBL
## 3 SUNITINIB inhibitor CKB-CORE; GuideToPharmacology
## 4 ENTRECTINIB DTC
## 5 FEXAGRATINIB inhibitor MyCancerGenome; OncoKB; CKB-CORE; CIViC; TALC; TTD
## 6 PD173074 CKB-CORE; CIViC
dgidb_d2t <- getDgidbDrugTarget(
list(molType = "cmp", idType = "name", ids = "imatinib"))
head(dgidb_d2t[, c("gene_name", "interaction_types", "interaction_score")])
## gene_name interaction_types interaction_score
## 1 KIT inhibitor 0.74132923
## 2 MAPK10 0.01394415
## 3 PDGFRB inhibitor 0.06759367
## 4 IKZF1 0.29003830
## 5 PDGFRA 0.21326345
## 6 CYP2F1 1.45019149
The sources column matters for reuse: DGIdb aggregates interactions from
many upstream databases (ChEMBL, DrugBank, TTD, and others), each with its
own license - a row’s sources value tells you where that specific
interaction actually came from.
Open Targets is queried through its GraphQL API via
getOpenTargetsDrugTarget(). Unlike DGIdb, its schema is asymmetric:
target → drug goes through Target.drugAndClinicalCandidates, drug
→ target through Drug.mechanismsOfAction. Native identifiers: a
gene symbol (an Ensembl gene ID also passes through unresolved) for
target → drug, a compound name (a ChEMBL ID also passes through
unresolved, since Open Targets drug IDs are ChEMBL IDs) for drug →
target.
ot_t2d <- getOpenTargetsDrugTarget(
list(molType = "gene", idType = "symbol", ids = "FGFR1"))
head(ot_t2d[, c("drug_name", "mechanism_of_action", "max_clinical_stage")])
## drug_name mechanism_of_action max_clinical_stage
## 1 TG100-801 Ephrin type-B receptor 4 inhibitor PHASE_2
## 2 TG100-801 Fibroblast growth factor receptor 1 inhibitor PHASE_2
## 3 TG100-801 Platelet-derived growth factor receptor beta inhibitor PHASE_2
## 4 TG100-801 Fibroblast growth factor receptor 2 inhibitor PHASE_2
## 5 TG100-801 SRC inhibitor PHASE_2
## 6 TG100-801 Vascular endothelial growth factor receptor 1 inhibitor PHASE_2
ot_d2t <- getOpenTargetsDrugTarget(
list(molType = "cmp", idType = "name", ids = "aspirin"))
ot_d2t[, c("approved_symbol", "mechanism_of_action")] # PTGS1/PTGS2 = COX1/COX2
## approved_symbol mechanism_of_action
## 1 PTGS2 Cyclooxygenase inhibitor
## 2 PTGS1 Cyclooxygenase inhibitor
Note that agonist targets or those without a drugged pocket (e.g. FGF21, NLRP3, TFEB, ADIPOR1/2 in this package’s original test-gene set) legitimately return zero rows from Open Targets - that reflects the state of drug discovery for that target, not a query failure.
getChemblDrugTarget(), getPubchemDrugTarget(), getDgidbDrugTarget()
and getOpenTargetsDrugTarget() return a small, harmonized set of columns
by default (fields = "core") - this is exactly what lets
combineDrugTargets() bind rows from different sources into one table
(see Combining Results). For a single-source query, though, each
underlying API exposes many more fields than this curated set. Pass
fields = "all" to get everything available, source-prefixed to avoid
name clashes between sources:
chembl_all <- getChemblDrugTarget(
list(molType = "cmp", idType = "chembl_id", ids = "CHEMBL25"), fields = "all")
dim(chembl_all)
## [1] 2 111
chembl_all[, c("Drug_Name", "mechanism.mechanism_comment", "molecule.molecule_type")]
## Drug_Name mechanism.mechanism_comment molecule.molecule_type
## 1 ASPIRIN <NA> Small molecule
## 2 ASPIRIN <NA> Small molecule
Use listDrugTargetFields() to browse what a source offers before
deciding what to keep:
listDrugTargetFields("chembl")[1:10]
## [1] "QueryIDs" "chembl_id" "Drug_Name" "MOA" "Action_Type"
## [6] "Max_Phase" "First_Approval" "ChEMBL_TID" "UniProt_ID" "Desc"
fields also accepts a character vector directly, so a single call can
ask for just the extra columns you actually want:
getChemblDrugTarget(
list(molType = "cmp", idType = "chembl_id", ids = "CHEMBL25"),
fields = c("Drug_Name", "molecule.molecule_type", "target.organism"))
## QueryIDs Drug_Name molecule.molecule_type target.organism
## 1 CHEMBL25 ASPIRIN Small molecule Homo sapiens
## 2 CHEMBL25 ASPIRIN Small molecule Homo sapiens
The same fields argument works identically on all four source
functions (and on queryDrugTargets(), which forwards it through). For
ChEMBL and PubChem (REST APIs), fields = "all" costs nothing extra -
the full response is already fetched, just no longer discarded. For
DGIdb and Open Targets (GraphQL APIs), it does request a wider response,
since GraphQL only returns fields a query explicitly asks for.
TTD has no live API. Its flat files are downloaded once and assembled into
a small local SQLite via buildTtdDb(); ttdTargetAnnot() then queries
that local database repeatedly. This mirrors ChEMBL’s local-SQLite option
(see the Supplement) - build once, query many times.
ttdDbPath <- buildTtdDb(rerun = TRUE) # first build must fetch; rerun = FALSE reuses the cache afterward
Native identifiers for ttdTargetAnnot(): for target → drug, a
gene symbol (idType = "symbol"), a UniProt mnemonic entry name
such as "FGFR1_HUMAN" (idType = "uniprot" - note this is not the
UniProt accession "P11362" other sources use), or TTD’s own
TargetID (idType = "ttd_target_id"); for drug → target, a
drug name or TTD’s own DrugID (idType = "ttd_drug_id").
The result’s Uniprot_acc column carries a resolved UniProt accession
where available (via the package’s UniProt REST scaffold, keyed on
GeneName, not on string-mangling the mnemonic) - check the paired
uniprot_source column before trusting it: "resolved" means it
worked, "TTD_missing" means TTD itself had no usable ID for that
target at all (overwhelmingly family/pathway-level “targets” with no
single accession by construction, e.g. “Fibroblast growth factor
receptor (FGFR)” rather than the single-protein “FGFR1”), and
"unresolved"/"resolution_failed" mean resolution was attempted but
failed - a real gene symbol with no UniProt mapping, or a transient
UniProt outage, respectively.
ttd_t2d <- ttdTargetAnnot(
list(molType = "protein", idType = "symbol", ids = "FGFR1"), ttdDbPath)
head(ttd_t2d[, c("DrugName", "Highest_status", "MOA", "Uniprot_acc", "molecule_type")])
## DrugName Highest_status MOA Uniprot_acc molecule_type
## 1 KW-2449 Phase 1 <NA> P11362 small molecule
## 2 MK-2461 Phase 1/2 Inhibitor P11362 small molecule
## 3 Anti-FGFR1 mab program Investigative <NA> P11362 antibody
## 4 SAR-106881 Investigative Agonist P11362 other
## 5 Romiplostim Approved Inhibitor P11362 small molecule
## 6 E-3810 Phase 3 Inhibitor P11362 small molecule
ttd_d2t <- ttdTargetAnnot(
list(molType = "cmp", idType = "name", ids = "Pemigatinib"), ttdDbPath)
ttd_d2t[, c("GeneName", "Highest_status", "MOA", "PubChem_CID", "Indication")]
## GeneName Highest_status MOA PubChem_CID
## 1 FGFR1 Approved Inhibitor 86705695
## 2 FGFR3 Approved Inhibitor 86705695
## 3 FGFR2 Approved Inhibitor 86705695
## Indication
## 1 Cholangiocarcinoma [2C12.10]: Approved; Myeloproliferative syndrome [2A22]: Phase 2; Bladder cancer [2C94]: Phase 2
## 2 Cholangiocarcinoma [2C12.10]: Approved; Myeloproliferative syndrome [2A22]: Phase 2; Bladder cancer [2C94]: Phase 2
## 3 Cholangiocarcinoma [2C12.10]: Approved; Myeloproliferative syndrome [2A22]: Phase 2; Bladder cancer [2C94]: Phase 2
Note Indication packs every disease Pemigatinib is associated with,
each with its own clinical status (e.g. approved for cholangiocarcinoma
but only Phase 2 for bladder cancer) - richer than the single
Highest_status column, which only ever reflects the drug’s single
most-advanced status across all diseases combined.
molecule_type is a derived classification - TTD’s own DRUGTYPE field
where available, a SMILES-presence/name heuristic otherwise (see
?buildTtdDb) - not an authoritative structural determination. Useful
for filtering before a downstream cheminformatics step (e.g. keep only
"small molecule" rows before computing descriptors), but not something
to trust for anything decision-critical without checking Smiles
directly.
Like the four REST-backed sources, ttdTargetAnnot() supports
fields = "core"/"all"/<vector> (see Requesting Additional Fields) -
though since ttd_interactions is one flat local table with nothing
larger to opt into, "core" and "all" return the same full column set
here; the option mainly exists to narrow down to a specific subset:
listDrugTargetFields("ttd")
## [1] "QueryIDs" "TargetID" "GeneName" "Uniprot" "TargetType"
## [6] "DrugID" "DrugName" "Smiles" "Highest_status" "MOA"
## [11] "Uniprot_acc" "uniprot_source" "molecule_type" "PubChem_CID" "PubChem_SID"
## [16] "CAS" "ChEBI_ID" "Indication"
ttdTargetAnnot(
list(molType = "protein", idType = "symbol", ids = "FGFR1"), ttdDbPath,
fields = c("DrugName", "CAS", "ChEBI_ID"))[1:3, ]
## QueryIDs DrugName CAS ChEBI_ID
## 1 FGFR1 KW-2449 841258-76-2 CHEBI:91441
## 2 FGFR1 MK-2461 917879-39-1 <NA>
## 3 FGFR1 Anti-FGFR1 mab program <NA> <NA>
Every downloaded TTD file’s own release stamp (version and date - TTD
does not always move these together across files, see ?buildTtdDb) is
attached to ttdTargetAnnot()’s result as attr(result, "ttd_release"):
attr(ttd_t2d, "ttd_release")
## file version date
## 1 targets 10.1.01 2024.01.10
## 2 drugs 10.1.01 2024.01.10
## 3 mapping <NA> <NA>
## 4 crossmatch 10.1.01 2024.01.10
## 5 drugDisease 10.1.01 2024.03.30
Distribution note: buildTtdDb() only ever downloads TTD’s own files
into your local cache and builds the SQLite there - the package itself
ships no TTD data (TTD’s license permits academic use but has no explicit
redistribution grant). The cross-matching columns (PubChem_CID,
PubChem_SID, CAS, ChEBI_ID) are TTD’s own; this release’s
cross-matching file does not carry ChEMBL_ID, DrugBank_ID, or
InChIKey at all (confirmed by reading the raw file, not just its
header) - joining to those needs a separate hop through
getUnichemMapping()/buildUnichemDb() via PubChem_CID, not this
function.
Like TTD, the Broad Institute Drug Repurposing
Hub has no live API - two
flat TSV files (drug-level and physical-sample-level annotation) are
downloaded once and assembled into a small local SQLite via
buildBroadRepurposingHubDb(); broadRepurposingHubAnnot() then queries
that local database repeatedly.
brhDbPath <- buildBroadRepurposingHubDb(rerun = TRUE) # first build must fetch; rerun = FALSE reuses the cache afterward
Native identifiers for broadRepurposingHubAnnot(): for target → drug,
a gene symbol (idType = "symbol" - the Repurposing Hub only exposes
gene symbols, no accession system of its own); for drug → target, a
drug name (idType = "name", matched case-insensitively against the
Hub’s own lower-case pert_iname) or a specific physical sample/batch ID
(idType = "broad_id").
broad_t2d <- broadRepurposingHubAnnot(
list(molType = "protein", idType = "symbol", ids = "FGFR1"), brhDbPath)
head(broad_t2d[, c("pert_iname", "clinical_phase", "moa")])
## pert_iname clinical_phase moa
## 1 AZD4547 Phase 2/Phase 3 FGFR inhibitor
## 2 CH-5183284 Phase 2 fibroblast growth factor inhibitor
## 3 ENMD-2076 Phase 2 Aurora kinase inhibitor | FLT3 inhibitor | VEGFR inhibitor
## 4 KW-2449 Phase 1 Abl kinase inhibitor | Aurora kinase inhibitor | FLT3 inhibitor
## 5 LY2874455 Phase 1 FGFR antagonist
## 6 MK-2461 Phase 1/Phase 2 FGFR inhibitor | VEGFR inhibitor
broad_d2t <- broadRepurposingHubAnnot(
list(molType = "cmp", idType = "name", ids = "pemigatinib"), brhDbPath)
broad_d2t[, c("target_gene", "clinical_phase", "moa")]
## target_gene clinical_phase moa
## 1 FGFR1 Launched fgfr inhibitor
## 2 FGFR2 Launched fgfr inhibitor
## 3 FGFR3 Launched fgfr inhibitor
Distribution note: buildBroadRepurposingHubDb() only ever downloads
the Repurposing Hub’s own files into your local cache and builds the SQLite
there - the package itself ships no Repurposing Hub data. Its license is
more restrictive than TTD’s: the source files explicitly state they are
“provided for non-commercial use only.”
Two tables, not one: unlike TTD, the Repurposing Hub’s sample-level
file has a genuinely different grain than a drug-target edge - one
compound routinely has several physical samples/lots. broad_interactions
(what broadRepurposingHubAnnot() returns above) is kept strictly at
one row per (pert_iname, target_gene); physical-sample/QC metadata
(purity, vendor, catalog number, etc.) lives separately in
broad_samples, queryable directly by broad_id. A structure_ambiguous
column flags the rare case (~2% of compounds) where one pert_iname
display name actually covers more than one distinct chemical structure
(different salts/stereoisomers) - smiles/InChIKey/pubchem_cid are
then "; "-joined rather than picking one arbitrarily; structure-sensitive
work should key on InChIKey, not name, for those rows.
Known operational caveat, worked around automatically:
repo-hub.broadinstitute.org has been observed serving an incomplete TLS
certificate chain (missing the InCommon intermediate certificate).
Browsers usually mask this by auto-fetching the missing intermediate;
curl/R’s default download methods generally do not. This is a
server-side issue, not something fixable at the source - but
downloadBroadRepurposingHub() now retries automatically with a CA
bundle extended to include the one missing (legitimate, publicly-issued)
certificate, so a plain call should succeed regardless.
GtoPdb offers a documented REST API, but its per-target endpoints are
one-resource-per-call with no bulk target-to-gene-symbol mapping endpoint -
impractical for a genome-wide build. Instead, buildGtoPdbDb() uses
GtoPdb’s bulk /services/interactions endpoint (one call returns the
whole ~24,000-row interaction table as JSON) joined locally against a
small bulk flat file GtoPdb separately publishes for target-ID-to-HGNC
mapping, assembled into a small local SQLite - the same build-once,
query-many pattern as TTD and the Repurposing Hub, just sourced from
REST plus one small file instead of pure flat files.
gtoPdbDbPath <- buildGtoPdbDb(rerun = TRUE) # first build must fetch; rerun = FALSE reuses the cache afterward
Native identifiers for gtoPdbTargetAnnot(): for target → drug, a
gene symbol (idType = "symbol") or GtoPdb’s own target ID
(idType = "gtp_target_id"); for drug → target, a ligand name
(idType = "name") or GtoPdb’s own ligand ID (idType = "gtp_ligand_id").
Interactions are pre-filtered to species == "Human" at build time.
gtopdb_t2d <- gtoPdbTargetAnnot(
list(molType = "protein", idType = "symbol", ids = "FGFR1"), gtoPdbDbPath)
head(gtopdb_t2d[, c("ligandName", "type", "action", "affinity")])
## ligandName type action affinity
## 1 dovitinib Inhibitor Inhibition 8.0 - 8.1
## 2 dabogratinib Inhibitor Inhibition 6.6
## 3 pexmetinib Inhibitor Inhibition 7.6
## 4 infigratinib Inhibitor Inhibition 9.1
## 5 orantinib Inhibitor Inhibition 5.7
## 6 compound 2c [PMID: 24900538] Inhibitor Inhibition 8.1
gtopdb_d2t <- gtoPdbTargetAnnot(
list(molType = "cmp", idType = "name", ids = "pemigatinib"), gtoPdbDbPath)
gtopdb_d2t[, c("target_gene", "type", "action", "affinity")]
## target_gene type action affinity
## 1 FGFR1 Inhibitor Inhibition 7.0
## 2 FGFR2 Inhibitor Inhibition 7.0
## 3 FGFR3 Inhibitor Inhibition 7.0
GtoPdb is a more targeted, expert-curated resource than TTD/the Repurposing Hub, not exhaustive - of this vignette’s 8 target genes, only FGFR1 and NLRP3 are covered.
Distribution note: unlike TTD and the Repurposing Hub, GtoPdb’s data
is licensed under the Open Data Commons Open Database License (ODbL)
with contents under CC-BY-SA 4.0 - clear terms that explicitly permit
redistribution (with attribution/share-alike). buildGtoPdbDb() still
only ever downloads into your local cache and builds the SQLite there,
matching the other local-SQLite sources’ posture for consistency, though
that default isn’t a licensing requirement here the way it is for TTD/
the Repurposing Hub.
Everything in Data Sources in Detail returns curated drug-target
annotations - a database’s own expert-curated call that a drug acts on
a target via some mechanism (ChEMBL’s drug_mechanism, DGIdb’s
aggregated interactions, Open Targets’ mechanismsOfAction, TTD’s
target-drug mappings). That’s a genuinely different kind of data from a
raw bioassay measurement - one experimental result, e.g. “this compound
inhibited this target with an IC50 of 42nM in this specific assay” - with
no claim about mechanism or curation attached. PubChem’s REST API only
ever returns the latter, and ChEMBL exposes both kinds side by side. To
keep the two from being silently conflated, this package always keeps
them in separate functions and never combines them:
queryDrugTargets()/combineDrugTargets() (see Cross-Source Queries)
only ever touch the four annotation sources - PubChem is not one of
their sources.
getChemblBioassay() is the bioassay-track sibling of
getChemblDrugTarget(): same bidirectional queryBy interface (UniProt
accession for target → drug, ChEMBL molecule ID for drug →
target), but pulling from ChEMBL’s activity resource instead of
drug_mechanism.
chembl_ba_t2d <- getChemblBioassay(
list(molType = "protein", idType = "Uniprot", ids = "P11362"), # FGFR1
standardType = "IC50")
head(chembl_ba_t2d[, c("Drug_Name", "standard_value", "standard_units")])
## Drug_Name standard_value standard_units
## 1 <NA> NA <NA>
## 2 <NA> 42 nM
## 3 <NA> 10000 nM
## 4 <NA> 50000 nM
## 5 <NA> 50000 nM
## 6 <NA> 1520 nM
chembl_ba_d2t <- getChemblBioassay(
list(molType = "cmp", idType = "chembl_id", ids = "CHEMBL1421")) # dasatinib
head(chembl_ba_d2t[, c("UniProt_ID", "standard_type", "standard_value")])
## UniProt_ID standard_type standard_value
## 1 P34152 Inhibition NA
## 2 <NA> GI50 15.00
## 3 <NA> GI80 50000.00
## 4 <NA> IC50 NA
## 5 O60885 Delta TM -1.33
## 6 P06241 Kd 4.00
A single-target convenience helper, getChemblBioactivities(), is also
available for a quick one-target lookup without the batching/direction
machinery. getChemblBioassay() also supports the same fields = "core"/"all"/<vector> mechanism as the annotation functions (see
Requesting Additional Fields) - use listBioassayFields("chembl") to
browse the extra columns available:
listBioassayFields("chembl")[1:10]
## [1] "QueryIDs" "chembl_id" "Drug_Name" "ChEMBL_TID"
## [5] "UniProt_ID" "Organism" "Desc" "assay_chembl_id"
## [9] "assay_description" "standard_type"
PubChem’s bioactivity data is queried through its PUG-REST API and NCBI
E-utilities via getPubchemDrugTarget(). Native identifiers: a gene
symbol (an NCBI GeneID also passes through unresolved) for target →
drug, a compound name (a PubChem CID also passes through unresolved)
for drug → target.
pubchem_t2d <- getPubchemDrugTarget(
list(molType = "gene", idType = "symbol", ids = "KLB"))
head(pubchem_t2d[, c("drug_name", "activity_name", "activity_value_uM")])
## drug_name activity_name activity_value_uM
## 1 <NA> <NA> <NA>
pubchem_d2t <- getPubchemDrugTarget(
list(molType = "cmp", idType = "name", ids = "aspirin"))
pubchem_d2t[, c("gene_symbol", "activity_name", "activity_value_uM")]
## gene_symbol activity_name activity_value_uM
## 1 NAPRT Ki 0.0005
## 2 PTGS1 IC50 0.3500
## 3 PTGS2 IC50 2.4000
## 4 ITGB3 IC50 5.0000
## 5 ITGA2B IC50 5.0000
## 6 CYP2D6 Potency 15.4871
## 7 CYP3A7 Potency 15.4871
## 8 CYP1A2 Potency 24.5454
## 9 CYP2C19 Potency 79.1862
PubChem is compound-centric and high-volume; results are capped per gene
(maxCids, default 400) and filtered to Active, numeric, potency-endpoint
measurements (IC50/Ki/Kd/EC50/AC50/Potency) by default. Because
compound-centric assay data spans whatever species each assay used (e.g.
aspirin’s classic COX1/COX2 potency assays are annotated against sheep
GeneIDs in PubChem), getPubchemTargets()/getPubchemDrugTarget() filter
to human (taxid = 9606) by default - pass taxid = NULL for all species.
Like ChEMBL’s bioassay function, fields = "core"/"all"/<vector> and
listBioassayFields("pubchem") are available here too.
Every source function above expects that source’s native identifier
type. The functions in this section translate between identifier types
directly, and are also what queryDrugTargets() uses internally.
getUniprotMapping() maps identifiers via UniProt’s REST ID Mapping
service. from/to use UniProt’s own database-name vocabulary (see
UniProt’s ID Mapping help page
for the full list) - a few of the most useful:
getUniprotMapping(c("FGFR1", "KLB"), from = "Gene_Name", to = "UniProtKB-Swiss-Prot")
## From To
## 1 FGFR1 P11362
## 2 KLB Q86Z14
getUniprotMapping("P11362", from = "UniProtKB_AC-ID", to = "Ensembl")
## From To
## 1 P11362 ENSG00000077782.24
taxId restricts matches to one organism (default 9606 = human) -
important because a gene symbol can match entries from several species.
getEnsemblParalogs()/getEnsemblOrthologs() query Ensembl’s homology
REST API. Their type classification (ortholog_one2one,
other_paralog, etc.) comes from gene-tree reconciliation, not raw
sequence-identity thresholding, so it is a more principled “best hit”
signal than picking the highest perc_id alone - prefer
type == "ortholog_one2one" when you need a single best cross-species
match.
getEnsemblParalogs("NLRP3")[, c("homolog_id", "type", "perc_id")]
## homolog_id type perc_id
## 1 ENSG00000167984 other_paralog 20.65730
## 2 ENSG00000179583 other_paralog 14.86730
## 3 ENSG00000158077 other_paralog 34.30920
## 4 ENSG00000253548 other_paralog 8.24742
## 5 ENSG00000022556 other_paralog 21.75140
## 6 ENSG00000167207 other_paralog 19.54590
## 7 ENSG00000185792 other_paralog 32.59330
## 8 ENSG00000179709 other_paralog 28.43510
## 9 ENSG00000142405 other_paralog 46.55980
## 10 ENSG00000167634 other_paralog 22.08290
## 11 ENSG00000140853 other_paralog 12.70100
## 12 ENSG00000091592 other_paralog 17.65110
## 13 ENSG00000182261 other_paralog 29.77100
## 14 ENSG00000160703 other_paralog 16.41030
## 15 ENSG00000106100 other_paralog 18.99270
## 16 ENSG00000171487 other_paralog 25.67450
## 17 ENSG00000179873 other_paralog 20.23230
## 18 ENSG00000173572 other_paralog 29.53020
## 19 ENSG00000174885 other_paralog 25.92590
## 20 ENSG00000160505 other_paralog 33.09860
getEnsemblOrthologs("NLRP3", targetSpecies = "mouse")[
, c("homolog_id", "homolog_species", "type", "perc_id")]
## homolog_id homolog_species type perc_id
## 1 ENSMUSG00000032691 mus_musculus ortholog_one2one 82.575
Large gene families need the default query shape here - by design,
getEnsemblParalogs()/getEnsemblOrthologs() already avoid a
pathological slowdown found for such families (see
?.dot-dtiEnsemblHomologyFetch for details); pass condensed = TRUE for
an even faster existence-check-only path when you don’t need
perc_id/perc_pos.
getUnichemMapping() translates compound identifiers via a local SQLite
built from UniChem’s bulk compound cross-reference table
(buildUnichemDb()). It is genuinely source-agnostic: from/to accept
any source name present in the underlying data (not a fixed list
hand-coded per database) - "chembl", "pubchem", "drugbank",
"chebi", and dozens more.
## One-time setup (not run automatically in this vignette - takes on the
## order of an hour and downloads ~1.5GB). Rerun = FALSE afterward always
## reuses whatever was built, regardless of which day that was.
unichemDbPath <- buildUnichemDb()
unichemDbPath <- buildUnichemDb(rerun = FALSE)
getUnichemMapping("CHEMBL25", from = "chembl", to = "pubchem", unichemDbPath) # aspirin -> CID
getUnichemMapping("CHEMBL25", from = "chembl", to = "drugbank", unichemDbPath) # aspirin -> DrugBank ID
Unlike UniProt’s or Ensembl’s REST APIs, UniChem’s own live per-compound
API does not support batch queries and was found to be intermittently
unreliable for even single lookups - the local-SQLite approach exists
specifically to avoid depending on it (see ?buildUnichemDb). Because the
build is a real, deliberate operation (not something to trigger silently),
buildUnichemDb(rerun = FALSE) is always required explicitly before using
getUnichemMapping() or queryDrugTargets() on structured compound IDs.
queryDrugTargets() resolves queryBy$ids to whatever native identifier
each requested sources entry needs, then dispatches. queryBy$idType
uses the same canonical vocabulary as the translation layer above -
"symbol"/"uniprot"/"ensembl" for genes, "name"/"chembl_id"/
"pubchem_id"/"drugbank_id"/"chebi_id" for compounds - not each
source’s own native type.
res_one <- queryDrugTargets(
list(molType = "gene", idType = "symbol", ids = "FGFR1"), sources = "chembl")
names(res_one)
## [1] "chembl"
## Starting from an Ensembl gene ID instead of a symbol - resolved
## automatically (via a UniProt accession as an intermediate hop, since
## UniProt's mapping API requires one side of any call to be UniProtKB).
res_ensembl <- queryDrugTargets(
list(molType = "gene", idType = "ensembl", ids = "ENSG00000077782"),
sources = c("chembl", "opentargets"))
sapply(res_ensembl, nrow)
## chembl opentargets
## 26 94
## TTD, Broad Repurposing Hub and GtoPdb each need a local db path (see
## above); other sources ignore the ones they don't use.
res_all_live <- queryDrugTargets(
list(molType = "gene", idType = "symbol", ids = "FGFR1"),
sources = c("chembl", "dgidb", "opentargets", "ttd", "broad", "gtopdb"),
ttdDbPath = ttdDbPath, brhDbPath = brhDbPath, gtoPdbDbPath = gtoPdbDbPath)
sapply(res_all_live, nrow)
## chembl dgidb opentargets ttd broad gtopdb
## 26 143 94 37 37 47
Starting from a compound identifier that needs the UniChem SQLite works the same way once one has been built:
res_drugbank <- queryDrugTargets(
list(molType = "cmp", idType = "drugbank_id", ids = "DB00945"), # aspirin
sources = "chembl", unichemDbPath = unichemDbPath)
res_drugbank$chembl[, c("QueryIDs", "UniProt_ID", "Organism")]
A source that a query resolved nothing for, or whose own call failed (e.g.
a required local database path was not supplied), simply contributes no
element to the result list rather than raising an error - set
verbose = TRUE on any of the calls above to see why.
None of the seven sources support unlimited-size ID batches in a single request, and the live APIs are courtesy-throttled client-side regardless. The defaults already reflect each source’s real constraints (do not raise these without a specific reason):
| Source | Constraint | Default batch size |
|---|---|---|
| ChEMBL | REST server request-line length (~4KB; httr2 percent-encodes separators) |
200 IDs/request |
| PubChem | Compound-property lookup batch | 100 CIDs/request; bioactivity summary 50 CIDs/request |
| DGIdb | Courtesy chunking (no documented server limit found) | 300 names/request |
| Open Targets | GraphQL aliasing payload size | 25 targets/request |
| UniProt ID Mapping | Server-enforced job size cap | up to 100,000 IDs/job (asynchronous) |
| UniChem | No batching in the live API at all - hence the local-SQLite design | n/a (local queries) |
Every per-source function chunks large ids vectors into these batch
sizes automatically - including queryDrugTargets(), for the six
annotation sources it dispatches to (see Bioassay Queries for why
PubChem isn’t one of them) - so a query of, say, 2,000 UniProt
accessions works the same as one - it just takes proportionally longer
and issues proportionally more requests. When testing or debugging
with a deliberately small chunkSize, pick one relative to the endpoint’s
fan-out, not arbitrarily small: a tiny chunkSize against a low-fan-out
endpoint (e.g. ChEMBL’s molecule lookup, one record per ID) is a cheap
way to exercise pagination, but the same tiny chunkSize against a
high-fan-out join (e.g. ChEMBL’s target/mechanism join, where a handful of
UniProt accessions can expand into 100+ drug rows) multiplies into far
more live requests than intended.
combineDrugTargets() row-binds a small set of canonical columns
(query_id, gene_symbol, drug_name, action, source by default)
across whichever sources are present in a queryDrugTargets() result,
mapping each source’s own column names to this shared vocabulary:
combined <- combineDrugTargets(res_all_live)
table(combined$source)
##
## Broad Repurposing Hub ChEMBL DGIdb GtoPdb
## 37 26 143 47
## OpenTargets TTD
## 94 37
head(combined)
## query_id gene_symbol drug_name action source
## 1 FGFR1 <NA> PAZOPANIB HYDROCHLORIDE INHIBITOR ChEMBL
## 2 FGFR1 <NA> INFIGRATINIB PHOSPHATE INHIBITOR ChEMBL
## 3 FGFR1 <NA> INFIGRATINIB INHIBITOR ChEMBL
## 4 FGFR1 <NA> REGORAFENIB INHIBITOR ChEMBL
## 5 FGFR1 <NA> RG-1530 INHIBITOR ChEMBL
## 6 FGFR1 <NA> LUCITANIB INHIBITOR ChEMBL
query_id reflects your original query token, not each source’s own
(possibly translated) QueryIDs - useful once a query starts from a
non-native identifier, as in res_ensembl above:
unique(combineDrugTargets(res_ensembl)$query_id) # still "ENSG00000077782" for every source
## [1] "ENSG00000077782"
ChEMBL’s REST output has no gene-symbol column at all (it is
UniProt-accession-keyed), so gene_symbol is NA for ChEMBL rows by
default. Pass resolveGeneSymbol = TRUE to fill it in via one extra
getUniprotMapping() call:
combineDrugTargets(res_all_live, resolveGeneSymbol = TRUE) |>
subset(source == "ChEMBL") |> head(3)
## query_id gene_symbol drug_name action source
## 1 FGFR1 FGFR1 PAZOPANIB HYDROCHLORIDE INHIBITOR ChEMBL
## 2 FGFR1 FGFR1 INFIGRATINIB PHOSPHATE INHIBITOR ChEMBL
## 3 FGFR1 FGFR1 INFIGRATINIB INHIBITOR ChEMBL
This is deliberately just column-name alignment and row append - not
deduplication and not cross-source identity resolution (the same compound
or target appearing under different native IDs in different sources is
not merged into one row). A more principled harmonized container - an S4
class analysed but not yet built, so that different sources’ rows for the
literal same compound/target could be properly joined - is a separate,
deferred phase. Every source’s full original data remains available
unchanged in the list queryDrugTargets() returned, regardless of what
you pass to combineDrugTargets().
queryDrugTargets() is designed for on-demand queries of a handful to a
few thousand identifiers. A different, common need is a periodically
rebuilt, shareable master table covering essentially all human
protein-coding genes at once - the natural resource for genome-wide
questions like “do disease-associated gene variants have known drugs
annotated?” or “do hits from a LINCS perturbation-signature search have
known targets/MOAs?”. A single target-centric genome-wide run
already answers the reverse drug → target question too: every
row already carries whichever drug matched that gene, so filtering the
assembled table by drug identifier gives you that direction for free -
no separate compound-centric run is needed.
The code in this section is illustrative only (eval=FALSE) - a
genome-wide run queries live APIs for ~19,200 genes and can take hours;
it has no place executing during vignette or R CMD check builds. Run
it directly in an interactive session or a scheduled job instead.
The gene-centric anchor is HGNC’s complete
gene set - the single authoritative source for the current approved
symbol and every previous/alias symbol a gene has ever had, alongside
its Ensembl gene ID, UniProt accession(s), and Entrez ID, all in one row
per approved gene (~19,200 of them are protein-coding).
getHgncGeneTable() downloads (and caches) it and reshapes the
pipe-separated multi-value columns into list-columns:
hgncTable <- getHgncGeneTable()
nrow(hgncTable)
hgncTable[hgncTable$symbol == "FGFR1", c("symbol", "ensembl_gene_id")]
hgncTable$uniprot_ids[hgncTable$symbol == "FGFR1"]
By default this uses a pinned quarterly HGNC snapshot (not the
rolling always-latest file) specifically so a master table built today
and one built next year start from the same gene list unless you
deliberately ask otherwise (current = TRUE for the rolling file, or
archiveFile = "..." for any other specific HGNC archive snapshot).
Symbol normalization matters here: DGIdb and TTD echo back whatever
gene symbol was current when their own records were curated, and a
nontrivial fraction are now outdated relative to HGNC. buildHgncSymbolMap()
builds a lookup from every historical prev_symbol/alias_symbol to its
gene’s current approved symbol; normalizeGeneSymbols() applies it
(flagging any symbol it still can’t resolve, rather than silently
dropping it):
symbolMap <- buildHgncSymbolMap(hgncTable)
normalizeGeneSymbols(c("FGFR1", "ABL"), symbolMap = symbolMap, hgncTable = hgncTable)
buildGenomeWideDrugTargetTable() loops the four annotation sources’
own bidirectional functions over every gene in an HGNC table, in
checkpointed chunks written to outDir as it goes - so an interrupted
run resumes from the last completed chunk instead of starting over
(rerun = FALSE, the default, skips anything the chunk manifest already
marks done):
ttdDbPath <- buildTtdDb(rerun = FALSE)
masterTable <- buildGenomeWideDrugTargetTable(
hgncTable = hgncTable,
sources = c("chembl", "dgidb", "opentargets", "ttd"),
ttdDbPath = ttdDbPath,
outDir = "genomewide_build", # persists chunk files + a manifest here
chunkGenes = 500L)
sapply(masterTable, nrow)
This deliberately covers only the four curated-annotation sources - not ChEMBL’s bioassay function or PubChem (see Bioassay Queries). ChEMBL’s full activity table is tens of millions of rows and PubChem’s accessor is inherently a one-gene-at-a-time loop; a genome-wide sweep of either is a different kind of job, better done from their bulk data downloads than by looping this package’s live-API functions tens of thousands of times.
The result is a named list - one data.frame per source, each row tagged
with hgnc_id/symbol/ensembl_gene_id alongside that source’s own
native columns (deliberately not passed through combineDrugTargets()’s
harmonization, so no information is lost from a resource meant to be
reused repeatedly; apply combineDrugTargets() afterward if you want the
flattened cross-source view). The assembled result is also cached via
BiocFileCache, so a completed build is reusable across sessions and
machines without recomputation - exactly the “compute every few months,
share the result” workflow this section is meant to support.
The functions below predate, and are independent of, the sources and translation layer described above. They remain available as backward-compatible/alternative options but are not the default workflow recommended by this vignette.
Before ChEMBL’s REST API was added, this package’s ChEMBL support was
exclusively through a downloaded local SQLite instance of the full ChEMBL
database, queried via drugTargetAnnot() (and the related
getDrugTarget(), which queries a pre-generated flat-file export rather
than the SQLite directly). This remains useful for bulk, offline, or
very-high-volume ChEMBL querying where the REST API’s batch limits (see
Performance Considerations) are impractical.
config <- genConfig(chemblDbPath = "chembldb.db")
downloadChemblDb(rerun = TRUE, config = config) # downloads the full ChEMBL SQLite (several GB)
queryBy <- list(molType = "protein", idType = "UniProt_ID", ids = "P11362")
drugTargetAnnot(queryBy, config = config)
getUniprotIDs() predates getUniprotMapping() (see ID Translation
Layer) and is based on the Bioconductor UniProt.ws
package rather than a direct REST call. It is kept for backward
compatibility; getUniprotMapping() is the recommended path going
forward.
getUniprotIDs(taxId = 9606, kt = "ENSEMBL", keys = c("ENSG00000077782"))
getParalogs() predates getEnsemblParalogs()/getEnsemblOrthologs()
(see ID Translation Layer) and is based on biomaRt’s
BioMart interface rather than Ensembl’s REST API directly. It returns
within-human paralogs only (no cross-species orthologs). Kept for
backward compatibility.
queryBy <- list(molType = "gene", idType = "external_gene_name", ids = "FGFR1")
getParalogs(queryBy)
downloadUniChem()/cmpIdMapping() predate buildUnichemDb()/
getUnichemMapping() (see ID Translation Layer) and work from a small,
static, pre-computed ChEMBL↔︎{DrugBank, PubChem, ChEBI} cross-reference
snapshot hosted on a project S3 bucket, rather than UniChem’s own current
bulk data. Kept for backward compatibility and for the local-ChEMBL-SQLite
workflow above, which uses it internally via cmpIdMapping().
downloadUniChem(rerun = TRUE)
cmpIdMapping(outfile = "cmp_ids.rds", rerun = TRUE)
sessionInfo()
## R version 4.6.1 (2026-06-24)
## Platform: x86_64-pc-linux-gnu
## Running under: Ubuntu 24.04.4 LTS
##
## Matrix products: default
## BLAS: /home/biocbuild/bbs-3.24-bioc/R/lib/libRblas.so
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.12.0 LAPACK version 3.12.0
##
## locale:
## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C LC_TIME=en_GB
## [4] LC_COLLATE=C LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
## [7] LC_PAPER=en_US.UTF-8 LC_NAME=C LC_ADDRESS=C
## [10] LC_TELEPHONE=C LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
##
## time zone: America/New_York
## tzcode source: system (glibc)
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] drugTargetInteractions_1.21.3 BiocStyle_2.41.0
##
## loaded via a namespace (and not attached):
## [1] tidyselect_1.2.1 dplyr_1.2.1 blob_1.3.0
## [4] filelock_1.0.3 Biostrings_2.81.5 bitops_1.0-9
## [7] lazyeval_0.2.3 fastmap_1.2.0 RCurl_1.98-1.19
## [10] BiocFileCache_3.3.0 GenomicAlignments_1.49.1 XML_3.99-0.23
## [13] digest_0.6.39 lifecycle_1.0.5 ProtGenerics_1.45.0
## [16] KEGGREST_1.53.5 RSQLite_3.53.3 magrittr_2.0.5
## [19] compiler_4.6.1 rlang_1.3.0 sass_0.4.10
## [22] progress_1.2.3 tools_4.6.1 yaml_2.3.12
## [25] rtracklayer_1.73.0 knitr_1.51 prettyunits_1.2.0
## [28] S4Arrays_1.13.0 bit_4.6.0 curl_7.1.0
## [31] DelayedArray_0.39.3 abind_1.4-8 BiocParallel_1.47.0
## [34] withr_3.0.3 purrr_1.2.2 BiocGenerics_0.59.10
## [37] grid_4.6.1 stats4_4.6.1 biomaRt_2.69.0
## [40] SummarizedExperiment_1.43.0 cli_3.6.6 rmarkdown_2.31
## [43] crayon_1.5.3 generics_0.1.4 otel_0.2.0
## [46] httr_1.4.8 rjson_0.2.23 BiocBaseUtils_1.15.1
## [49] readxl_1.5.0 DBI_1.3.0 cachem_1.1.0
## [52] stringr_1.6.0 parallel_4.6.1 AnnotationDbi_1.75.2
## [55] cellranger_1.1.0 AnnotationFilter_1.37.0 BiocManager_1.30.27
## [58] XVector_0.53.0 restfulr_0.0.17 matrixStats_1.5.0
## [61] vctrs_0.7.3 Matrix_1.7-5 jsonlite_2.0.0
## [64] bookdown_0.47 IRanges_2.47.2 hms_1.1.4
## [67] S4Vectors_0.51.5 bit64_4.8.2 ensembldb_2.37.3
## [70] GenomicFeatures_1.65.0 jquerylib_0.1.4 glue_1.8.1
## [73] codetools_0.2-20 stringi_1.8.7 GenomeInfoDb_1.49.1
## [76] GenomicRanges_1.65.1 BiocIO_1.23.3 UCSC.utils_1.9.0
## [79] tibble_3.3.1 pillar_1.11.1 rappdirs_0.3.4
## [82] htmltools_0.5.9 Seqinfo_1.3.0 R6_2.6.1
## [85] dbplyr_2.6.0 httr2_1.3.0 evaluate_1.0.5
## [88] Biobase_2.73.1 lattice_0.22-9 cigarillo_1.3.1
## [91] png_0.1-9 Rsamtools_2.29.0 memoise_2.0.1
## [94] bslib_0.11.0 rjsoncons_1.3.3 SparseArray_1.13.2
## [97] xfun_0.60 MatrixGenerics_1.25.0 UniProt.ws_2.53.3
## [100] pkgconfig_2.0.3
Bento, A Patrı́cia, Anna Gaulton, Anne Hersey, Louisa J Bellis, Jon Chambers, Mark Davies, Felix A Krüger, et al. 2014. “The ChEMBL bioactivity database: an update.” Nucleic Acids Res. 42 (Database issue): D1083–90. https://doi.org/10.1093/nar/gkt1031.
Gaulton, Anna, Louisa J Bellis, A Patricia Bento, Jon Chambers, Mark Davies, Anne Hersey, Yvonne Light, et al. 2012. “ChEMBL: a large-scale bioactivity database for drug discovery.” Nucleic Acids Res. 40 (Database issue): D1100–7. https://doi.org/10.1093/nar/gkr777.
Wu, C H, R Apweiler, A Bairoch, D A Natale, W C Barker, B Boeckmann, S Ferro, et al. 2006. “The Universal Protein Resource (UniProt): an expanding universe of protein information.” Nucleic Acids Res. 34 (Database issue): D187–D191. https://doi.org/10.1093/nar/gkj161.