Skip to content

Add mapMetabolites(): metabolite identifier conversion through the MetaboAnalyst API - #284

Open
Cvicnaire wants to merge 1 commit into
devfrom
281-add-mapmetabolites-metabolite-identifier-conversion-through-the-metaboanalyst-api
Open

Cvicnaire wants to merge 1 commit into
devfrom
281-add-mapmetabolites-metabolite-identifier-conversion-through-the-metaboanalyst-api

Conversation

@Cvicnaire

Copy link
Copy Markdown
Collaborator

Closes #281. Serves #171.

What

mapMetabolites(ids, from = "name", timeout = 120) converts metabolite names or identifiers between HMDB, PubChem, ChEBI, KEGG, METLIN and SMILES through MetaboAnalyst's public compound-mapping endpoint (POST https://rest.xialab.ca/api/mapcompounds). One row per distinct input, in input order, with a matched flag and the canonical compound name. No login, no new dependency.

SigRepo::mapMetabolites(c("D-Glucose", "Citric acid", "notacompoundxyz"))
#>             query matched       match        hmdb pubchem chebi   kegg metlin smiles
#> 1       D-Glucose    TRUE   D-Glucose HMDB0000122    5793 15903 C00031    133 OC[C@H]1O...
#> 2     Citric acid    TRUE Citric acid HMDB0000094     311 30769 C00158    124 OC(=O)CC...
#> 3 notacompoundxyz   FALSE        <NA>        <NA>    <NA>  <NA>   <NA>   <NA> <NA>

How

  • R/mapMetabolites.R: the exported function, an input cleaner (trim, drop empty and NA-like values, de-duplicate, refuse values containing the service's ; separator), a fetch step through externalPostJson() and a parse step that reads both the string "NA" and JSON null as missing. Long lists go in chunks of 200 because the service takes about 20 to 30 s per request plus a fraction of a second per compound (1000 ids took 117 s in one request; 2500 timed out).
  • externalUrl("metaboanalyst") with the sigrepo.metaboanalyst_url option, next to the Rummagene, RummaGEO and CORESH entries.
  • tests/testthat/test_mapMetabolites.R: 11 tests, 37 assertions, HTTP mocked, fixture captured from the live service on 2026-10-15.
  • pkgdown entry under "Search Beyond the Repository"; NEWS under a new development-version section (NEWS.md rendered from NEWS.Rmd with the workflow's command, so the next render is a no-op).

Caveat worth knowing

When tested live on 2026-10-15, only from = "name" returned matches. The five identifier input types MetaboAnalyst documents (hmdb, pubchem, chebi, kegg, metlin) came back unmatched for known-good ids, whatever the field name or casing. The function passes them through as documented and the roxygen and NEWS say so; check matched before relying on an id-based lookup.

Tests

Full suite with devtools::load_all() + testthat::test_dir(): 1204 pass, 0 fail, 84 skip (the database-gated tests, no local stack configured).

Out of scope

Enrichment or pathway analysis via MetaboAnalystR, writing mapped ids into metabolite_xref, and any server, MCP or Shiny exposure.

🤖 Generated with Claude Code

…yst API

One exported function over MetaboAnalyst's public mapcompounds endpoint,
built on the searchExternal HTTP plumbing so tests mock externalPostJson().
Inputs are cleaned and sent in chunks of 200; the reply's "NA" strings and
JSON nulls both become NA. The URL is overridable through
options(sigrepo.metaboanalyst_url).

When tested live on 2026-10-15 only from = "name" returned matches; the
documented id input types are passed through as documented but came back
unmatched, which the roxygen and NEWS say.

Closes #281. Serves #171.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant