MyNixOS website logo
Description

Tidy Utilities for RxNorm and NDC Resolution.

Provides a tidy, vectorized interface to the 'RxNorm' / 'RxNav' API for resolving drug names, RxCUIs, National Drug Codes (NDCs), and related drug concept metadata. The package supports workflows for mapping between drug names, RxCUIs, NDCs, ingredients, products, drug classes, and related concepts using data from the National Library of Medicine's 'RxNav' services <https://lhncbc.nlm.nih.gov/RxNav/APIs/> and 'RxNorm' <https://www.nlm.nih.gov/research/umls/rxnorm/>.

rxref

R-CMD-check

rxref is an R package for working with medication identifiers from the National Library of Medicine’s RxNorm and RxClass APIs. It provides tidy, vectorized helpers for resolving medication names to RxCUIs, expanding ingredients to product concepts, mapping between RxCUIs and NDCs, retrieving clinical product attributes, and querying selected drug class relationships.

The package is designed for pharmacoepidemiologic and health services research workflows where medication exposure definitions often need to move between ingredient names, RxNorm concepts, National Drug Codes (NDCs), routes, dose forms, and therapeutic classes.

rxref was originally built to support pharmacoepidemiologic research in the UF CVmedLab, where we often need reproducible, transparent medication definitions for prescriptions, pharmacy dispensings, and claims-based drug exposure measures.

What rxref can do

Common workflows include:

  • resolve free-text medication names to RxNorm ingredient concepts with find_ingredients() and resolve();
  • expand ingredient RxCUIs to product RxCUIs with products_for_ingredients();
  • include active-only or active plus historical RxNorm concepts using concept_status;
  • map between RxCUIs and NDCs with map_to(), map_rxcui_to_ndc(), and map_ndc_to_rxcui();
  • retrieve product metadata with get_properties() and get_clinical_attributes();
  • filter products by route with filter_products_by_route();
  • query selected RxClass relationships with helpers such as get_atc(), get_epc(), and get_medrt();
  • use predefined RxNorm term type sets with product_ttys() and tty_catalogue().

Installation

You can install the development version of rxref from GitHub with:

# install.packages("pak")
# pak::pak("ssmithm/rxref")

Basic Workflow: ingredients to products

This is a basic example for querying product RxCUIs associated with the ingredient lisinopril (a blood pressure-lowering drug):

library(rxref)
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union

lisinopril_ing <- find_ingredients("lisinopril")

lisinopril_products <- products_for_ingredients(
  lisinopril_ing$rxcui,
  ttys = product_ttys("default"),
  include_combos = TRUE
)

# Resulting table 
lisinopril_products |> 
  dplyr::mutate(name = paste0("`", name, "`")) |> 
  knitr::kable()
ingredient_rxcuiproduct_rxcuinamettyn_ingredients
29046104375lisinopril 2.5 MG Oral Tablet [Zestril]SBD1
29046104376lisinopril 5 MG Oral Tablet [Zestril]SBD1
29046104377lisinopril 10 MG Oral Tablet [Zestril]SBD1
29046104378lisinopril 20 MG Oral Tablet [Zestril]SBD1
290461806890lisinopril 1 MG/ML Oral Solution [Qbrelis]SBD1
29046206765lisinopril 10 MG Oral Tablet [Prinivil]SBD1
29046206766lisinopril 20 MG Oral Tablet [Prinivil]SBD1
29046206771lisinopril 40 MG Oral Tablet [Zestril]SBD1
29046213482lisinopril 30 MG Oral Tablet [Zestril]SBD1
29046823971hydrochlorothiazide 25 MG / lisinopril 20 MG Oral Tablet [Zestoretic]SBD2
29046823982hydrochlorothiazide 12.5 MG / lisinopril 20 MG Oral Tablet [Zestoretic]SBD2
29046823986hydrochlorothiazide 12.5 MG / lisinopril 10 MG Oral Tablet [Zestoretic]SBD2
290461806884lisinopril 1 MG/ML Oral SolutionSCD1
29046197884lisinopril 40 MG Oral TabletSCD1
29046197885hydrochlorothiazide 12.5 MG / lisinopril 10 MG Oral TabletSCD2
29046197886hydrochlorothiazide 12.5 MG / lisinopril 20 MG Oral TabletSCD2
29046197887hydrochlorothiazide 25 MG / lisinopril 20 MG Oral TabletSCD2
29046205326lisinopril 30 MG Oral TabletSCD1
29046311353lisinopril 2.5 MG Oral TabletSCD1
29046311354lisinopril 5 MG Oral TabletSCD1
29046314076lisinopril 10 MG Oral TabletSCD1
29046314077lisinopril 20 MG Oral TabletSCD1


# Count of TTYs in resulting table
lisinopril_products |> 
  count(tty, n_ingredients, sort=TRUE)
#> # A tibble: 4 × 3
#>   tty   n_ingredients     n
#>   <chr>         <int> <int>
#> 1 SBD               1     9
#> 2 SCD               1     7
#> 3 SBD               2     3
#> 4 SCD               2     3

Active and historical RxNorm concepts

By default, products_for_ingredients() searches active RxNorm concepts:

products_for_ingredients(
  "29046",
  ttys = product_ttys("extended_product"),
  concept_status = "active"
) |> knitr::kable()
ingredient_rxcuiproduct_rxcuinamettyn_ingredients
290461806883lisinopril Oral SolutionSCDF1
29046372613hydrochlorothiazide / lisinopril Oral TabletSCDF2
29046372614lisinopril Oral TabletSCDF1
290461162124hydrochlorothiazide / lisinopril Oral ProductSCDG2
290461162125hydrochlorothiazide / lisinopril PillSCDG2
290461164689lisinopril Oral ProductSCDG1
290461164690lisinopril PillSCDG1
290461806882lisinopril Oral Liquid ProductSCDG1
29046104375lisinopril 2.5 MG Oral Tablet [Zestril]SBD1
29046104376lisinopril 5 MG Oral Tablet [Zestril]SBD1
29046104377lisinopril 10 MG Oral Tablet [Zestril]SBD1
29046104378lisinopril 20 MG Oral Tablet [Zestril]SBD1
290461806890lisinopril 1 MG/ML Oral Solution [Qbrelis]SBD1
29046206765lisinopril 10 MG Oral Tablet [Prinivil]SBD1
29046206766lisinopril 20 MG Oral Tablet [Prinivil]SBD1
29046206771lisinopril 40 MG Oral Tablet [Zestril]SBD1
29046213482lisinopril 30 MG Oral Tablet [Zestril]SBD1
29046823971hydrochlorothiazide 25 MG / lisinopril 20 MG Oral Tablet [Zestoretic]SBD2
29046823982hydrochlorothiazide 12.5 MG / lisinopril 20 MG Oral Tablet [Zestoretic]SBD2
29046823986hydrochlorothiazide 12.5 MG / lisinopril 10 MG Oral Tablet [Zestoretic]SBD2
290461806887lisinopril Oral Solution [Qbrelis]SBDF1
29046368248lisinopril Oral Tablet [Zestril]SBDF1
29046368865lisinopril Oral Tablet [Prinivil]SBDF1
29046823970hydrochlorothiazide / lisinopril Oral Tablet [Zestoretic]SBDF2
290461178275Prinivil Oral ProductSBDG1
290461178276Prinivil PillSBDG1
290461187277Zestoretic Oral ProductSBDG2
290461187278Zestoretic PillSBDG2
290461187283Zestril Oral ProductSBDG1
290461187284Zestril PillSBDG1
290461806888Qbrelis Oral Liquid ProductSBDG1
290461806889Qbrelis Oral ProductSBDG1
290461806884lisinopril 1 MG/ML Oral SolutionSCD1
29046197884lisinopril 40 MG Oral TabletSCD1
29046197885hydrochlorothiazide 12.5 MG / lisinopril 10 MG Oral TabletSCD2
29046197886hydrochlorothiazide 12.5 MG / lisinopril 20 MG Oral TabletSCD2
29046197887hydrochlorothiazide 25 MG / lisinopril 20 MG Oral TabletSCD2
29046205326lisinopril 30 MG Oral TabletSCD1
29046311353lisinopril 2.5 MG Oral TabletSCD1
29046311354lisinopril 5 MG Oral TabletSCD1
29046314076lisinopril 10 MG Oral TabletSCD1
29046314077lisinopril 20 MG Oral TabletSCD1

For older prescribing (or dispensing) data, users may need products that are no longer active in the current RxNorm release. Set concept_status = "active_and_historical" to include active concepts plus selected historical statuses:

products_for_ingredients(
  "1369",
  ttys = "SCD",
  include_combos = FALSE,
  concept_status = "active_and_historical"
) |> knitr::kable()
ingredient_rxcuiproduct_rxcuinamettyn_ingredientsconcept_statusactive_start_dateactive_end_daterelease_start_daterelease_end_date
1369197394bendroflumethiazide 5 MG Oral TabletSCD1ActiveNANANANA
1369308614bendroflumethiazide 2.5 MG Oral TabletSCD1ActiveNANANANA
1369197393bendroflumethiazide 10 MG Oral TabletSCD1Obsolete042005062014042005
1369308617bendroflumethiazide 5 MG Extended Release Oral TabletSCD1Obsolete042005092010042005
1369429502bendroflumethiazide 1.25 MG Oral TabletSCD1Obsolete042005072005042005

Historical searches return additional status and date fields, including concept_status, active_start_date, active_end_date, release_start_date, and release_end_date.

Note: Historical searches are slower than active-only searches because they require broader RxNorm status lookups. rxref caches repeated API calls where possible, but active-only queries should be preferred when historical concepts are not needed.

Clinical product attributes and route filtering

get_clinical_attributes() retrieves product-level attributes such as ingredients, dose form, dose form group, route, strength, and ingredient count.

attrs <- get_clinical_attributes(lisinopril_products$product_rxcui)

attrs |>
  select(rxcui, related_rxcui, name, strength, dose_form, route, tty)
#> # A tibble: 22 × 7
#>    rxcui   related_rxcui name                     strength dose_form route tty  
#>    <chr>   <chr>         <chr>                    <chr>    <chr>     <chr> <chr>
#>  1 104375  104375        lisinopril 2.5 MG Oral … 2.5 MG   Oral Tab… ORAL  SBD  
#>  2 104376  104376        lisinopril 5 MG Oral Ta… 5 MG     Oral Tab… ORAL  SBD  
#>  3 104377  104377        lisinopril 10 MG Oral T… 10 MG    Oral Tab… ORAL  SBD  
#>  4 104378  104378        lisinopril 20 MG Oral T… 20 MG    Oral Tab… ORAL  SBD  
#>  5 1806890 1806890       lisinopril 1 MG/ML Oral… 1 MG/ML  Oral Sol… ORAL  SBD  
#>  6 206765  206765        lisinopril 10 MG Oral T… 10 MG    Oral Tab… ORAL  SBD  
#>  7 206766  206766        lisinopril 20 MG Oral T… 20 MG    Oral Tab… ORAL  SBD  
#>  8 206771  206771        lisinopril 40 MG Oral T… 40 MG    Oral Tab… ORAL  SBD  
#>  9 213482  213482        lisinopril 30 MG Oral T… 30 MG    Oral Tab… ORAL  SBD  
#> 10 823971  823971        hydrochlorothiazide 25 … 25 MG /… Oral Tab… ORAL  SBD  
#> # ℹ 12 more rows

Products can also be filtered by route:

oral_lisinopril <- filter_products_by_route(
  lisinopril_products,
  route = "ORAL"
)

oral_lisinopril 
#> # A tibble: 22 × 8
#>    ingredient_rxcui product_rxcui name       tty   n_ingredients route dose_form
#>    <chr>            <chr>         <chr>      <chr>         <int> <chr> <chr>    
#>  1 29046            104375        lisinopri… SBD               1 ORAL  Oral Tab…
#>  2 29046            104376        lisinopri… SBD               1 ORAL  Oral Tab…
#>  3 29046            104377        lisinopri… SBD               1 ORAL  Oral Tab…
#>  4 29046            104378        lisinopri… SBD               1 ORAL  Oral Tab…
#>  5 29046            1806890       lisinopri… SBD               1 ORAL  Oral Sol…
#>  6 29046            206765        lisinopri… SBD               1 ORAL  Oral Tab…
#>  7 29046            206766        lisinopri… SBD               1 ORAL  Oral Tab…
#>  8 29046            206771        lisinopri… SBD               1 ORAL  Oral Tab…
#>  9 29046            213482        lisinopri… SBD               1 ORAL  Oral Tab…
#> 10 29046            823971        hydrochlo… SBD               2 ORAL  Oral Tab…
#> # ℹ 12 more rows
#> # ℹ 1 more variable: dose_form_group <chr>

Mapping between RxCUIs and NDCs

RxCUIs can be mapped to NDCs (and vice-versa):

ndcs <- map_rxcui_to_ndc("314077")

ndcs
#> # A tibble: 249 × 3
#>    rxcui  ndc11       ndc_status
#>    <chr>  <chr>       <chr>     
#>  1 314077 00143971301 ACTIVE    
#>  2 314077 00143971310 ACTIVE    
#>  3 314077 00185062001 ACTIVE    
#>  4 314077 00185062010 ACTIVE    
#>  5 314077 00378207501 ACTIVE    
#>  6 314077 00378207510 ACTIVE    
#>  7 314077 00591040801 ACTIVE    
#>  8 314077 00591040810 ACTIVE    
#>  9 314077 00615825505 ACTIVE    
#> 10 314077 00615825530 ACTIVE    
#> # ℹ 239 more rows

The direction-agnostic map_to() function can be used when you want to map between identifier types with one interface:

map_to("314077", to = "ndc") 
#> # A tibble: 249 × 3
#>    rxcui  ndc11       ndc_status
#>    <chr>  <chr>       <chr>     
#>  1 314077 00143971301 ACTIVE    
#>  2 314077 00143971310 ACTIVE    
#>  3 314077 00185062001 ACTIVE    
#>  4 314077 00185062010 ACTIVE    
#>  5 314077 00378207501 ACTIVE    
#>  6 314077 00378207510 ACTIVE    
#>  7 314077 00591040801 ACTIVE    
#>  8 314077 00591040810 ACTIVE    
#>  9 314077 00615825505 ACTIVE    
#> 10 314077 00615825530 ACTIVE    
#> # ℹ 239 more rows

Drug class relationships

rxref includes selected helpers for querying RxClass relationships, including ATC, EPC, and MED-RT classes.

get_atc("29046")
#> # A tibble: 1 × 10
#>   input rxcui drug_name  drug_tty class_id class_name class_type class_url rela 
#>   <chr> <chr> <chr>      <chr>    <chr>    <chr>      <chr>      <chr>     <chr>
#> 1 29046 29046 lisinopril IN       C09AA    ACE inhib… ATC1-4     <NA>      ""   
#> # ℹ 1 more variable: rela_source <chr>
get_epc("29046")
#> # A tibble: 2 × 10
#>   input rxcui  drug_name drug_tty class_id class_name class_type class_url rela 
#>   <chr> <chr>  <chr>     <chr>    <chr>    <chr>      <chr>      <chr>     <chr>
#> 1 29046 15460… lisinopr… PIN      N000017… Angiotens… EPC        <NA>      has_…
#> 2 29046 15460… lisinopr… PIN      N000017… Angiotens… EPC        <NA>      has_…
#> # ℹ 1 more variable: rela_source <chr>
get_medrt("29046")
#> # A tibble: 43 × 10
#>    input rxcui drug_name drug_tty class_id class_name class_type class_url rela 
#>    <chr> <chr> <chr>     <chr>    <chr>    <chr>      <chr>      <chr>     <chr>
#>  1 29046 1546… lisinopr… PIN      D000799  Angioedema DISEASE    <NA>      ci_w…
#>  2 29046 1546… lisinopr… PIN      D003928  Diabetic … DISEASE    <NA>      may_…
#>  3 29046 1546… lisinopr… PIN      D003928  Diabetic … DISEASE    <NA>      may_…
#>  4 29046 1546… lisinopr… PIN      D004342  Drug Hype… DISEASE    <NA>      ci_w…
#>  5 29046 1546… lisinopr… PIN      D006333  Heart Fai… DISEASE    <NA>      may_…
#>  6 29046 1546… lisinopr… PIN      D006929  Hyperaldo… DISEASE    <NA>      ci_w…
#>  7 29046 1546… lisinopr… PIN      D006973  Hypertens… DISEASE    <NA>      may_…
#>  8 29046 1546… lisinopr… PIN      D007022  Hypotensi… DISEASE    <NA>      ci_w…
#>  9 29046 1546… lisinopr… PIN      D009203  Myocardia… DISEASE    <NA>      may_…
#> 10 29046 1546… lisinopr… PIN      D011247  Pregnancy  DISEASE    <NA>      ci_w…
#> # ℹ 33 more rows
#> # ℹ 1 more variable: rela_source <chr>

API use and caching

rxref queries public RxNorm and RxClass APIs. The package includes configurable rate-delay and caching behavior to reduce repeated API requests and to support longer medication-definition workflows. Note that RxNorm indicates a rate of no more than 20 API requests per second per IP.

rxref_conf()
#> $base_url
#> [1] "https://rxnav.nlm.nih.gov/REST"
#> 
#> $rate_delay
#> [1] 0.1
#> 
#> $cache
#> <cache_mem> <cachem>
#>   Methods:
#>     get(key, missing = missing_)
#>     set(key, value)
#>     exists(key)
#>     keys()
#>     remove(key)
#>     reset()
#>     prune()
#>     size()
#>     info()
rxref_conf(rate_delay = 0.1)
#> $base_url
#> [1] "https://rxnav.nlm.nih.gov/REST"
#> 
#> $rate_delay
#> [1] 0.1
#> 
#> $cache
#> <cache_mem> <cachem>
#>   Methods:
#>     get(key, missing = missing_)
#>     set(key, value)
#>     exists(key)
#>     keys()
#>     remove(key)
#>     reset()
#>     prune()
#>     size()
#>     info()

Notes

RxNorm concepts and NDC mappings can change over time. For reproducible research, consider recording the date of API access and retaining intermediate drug-definition outputs used in analyses.

rxref is intended to support research workflows and medication-definition development. Users should review outputs carefully before using them in any high-stakes regulatory, clinical, or production settings.

Metadata

Version

0.4.0

License

Unknown

Platforms (79)

    Darwin
    FreeBSD
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    uefi
    wasip1
    Windows
Show all
  • aarch64-darwin
  • aarch64-freebsd
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64-uefi
  • aarch64-windows
  • aarch64_be-none
  • arc-linux
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-freebsd
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-linux
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • sh4-linux
  • vc4-none
  • wasm32-wasip1
  • wasm64-wasip1
  • x86_64-cygwin
  • x86_64-freebsd
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-uefi
  • x86_64-windows