Generating vocabulary based codelists for medications

In this vignette, we will explore how to generate codelists for medications using the OMOP CDM vocabulary tables. To begin, let’s load the necessary packages and create a cdm reference using Eunomia synthetic data.

library(DBI)
library(duckdb)
library(dplyr)
library(CDMConnector)
library(CodelistGenerator)

# Connect to the database and create the cdm object
con <- dbConnect(duckdb(), 
                 eunomiaDir("synpuf-1k", "5.3"))
cdm <- cdmFromCon(con = con, 
                  cdmName = "Eunomia Synpuf",
                  cdmSchema = "main",
                  writeSchema = "main",
                  achillesSchema = "main")

Ingredient based codelists

The getDrugIngredientCodes() function can be used to generate the medication codelists based on ingredient codes.

We can see that we have many drug ingredients for which we could create codelists.

availableIngredients(cdm) |> glimpse()

We will likely be interested in some specific drug ingredients of interest. Say for example we would like a codelist for acetaminophen then we can get this easily enough.

acetaminophen_codes <- getDrugIngredientCodes(
  cdm = cdm,
  name = c("acetaminophen")
)

acetaminophen_codes

Notice that either the concept name or the concept ID can be specified to find the relevant codes.

acetaminophen_codes <- getDrugIngredientCodes(
  cdm = cdm,
  name = 1125315
)

acetaminophen_codes

Instead of getting back all concepts for acetaminophen, we can use the ingredientRange argument to return only concepts associated with acetaminophen and at least one more drug ingredient (i.e. combination therapies). Here instead of returning a codelist with only the concept IDs, we will get them with details so that we can see concept names.

acetaminophen_two_or_more_ingredients <- getDrugIngredientCodes(
  cdm = cdm,
  name = "acetaminophen",
  ingredientRange = c(2, Inf),
  type = "codelist_with_details"
)

acetaminophen_two_or_more_ingredients

acetaminophen_two_or_more_ingredients[[1]] |> 
  pull("concept_name") |> 
  head(n = 5) # Only the first five will be shown

Or we could instead only return concepts associated with acetaminophen and no other drug ingredient.

acetaminophen_one_ingredient <- getDrugIngredientCodes(
  cdm = cdm,
  name = "acetaminophen",
  ingredientRange = c(1, 1),
  type = "codelist_with_details"
)

acetaminophen_one_ingredient

acetaminophen_one_ingredient[[1]] |> 
  pull("concept_name") |> 
  head(n = 5) # Only the first five will be shown

Restrict to a specific dose form

Perhaps we are just interested in a particular dose form. We can see that there are many available.

getDoseForm(cdm) |> glimpse()

We can choose one or more of these to restrict to a particular dose form when finding our relevant codes. Here, for example, we only include codes with a dose form of injection.

acetaminophen_injections <- getDrugIngredientCodes(
  cdm = cdm,
  name = "acetaminophen",
  doseForm = "injection",
  type = "codelist_with_details"
)

acetaminophen_injections[[1]] |> 
  pull("concept_name") |> 
  head(n = 5) 

Restrict to a specific dose unit

Similarly, we can might also want to restrict to a specific dose unit. Again we have a number of options available in our vocabularies.

getDoseUnit(cdm) |> glimpse()

Here we’ll just include codes with a dose unit of milligram.

acetaminophen_miligram <- getDrugIngredientCodes(
  cdm = cdm,
  name = "acetaminophen",
  doseUnit = "milligram",
  type = "codelist_with_details"
)

acetaminophen_miligram[[1]] |> 
  pull("concept_name") |> 
  head(n = 5) 

Restrict to a specific route

Lastly, we can restrict to a specific route category. We can see we again have a number of options.

getRouteCategories(cdm) |> glimpse()

Here we’ll include only concepts with a route category of inhalable.

acetaminophen_inhalable <- getDrugIngredientCodes(
  cdm = cdm,
  name = "acetaminophen",
  routeCategory = "inhalable",
  type = "codelist_with_details"
)

acetaminophen_inhalable[[1]] |> 
  pull("concept_name") |> 
  head(n = 5) 

Search multiple ingredients

The previous examples have focused on single drug ingredient, acetaminophen. We can though specify multiple ingredients, in which case we will get a codelist back for each.

acetaminophen_heparin_codes <- getDrugIngredientCodes(
  cdm = cdm,
  name = c("acetaminophen", "heparin")
  )

acetaminophen_heparin_codes

And if we don´t specify an ingredient, we will get a codelist for every drug ingredient in the vocabularies!

ATC based codelists

Analogous to getDrugIngredientCodes(), getATCCodes() can be used to generate a codelist based on a particular ATC class.

With ATC we have five levels of the classification which we could be interested in. The first level is the broadest while the fifth is the narrowest.

availableATC(cdm, level = c("ATC 1st")) |> glimpse()
availableATC(cdm, level = c("ATC 2nd")) |> glimpse()
availableATC(cdm, level = c("ATC 3rd")) |> glimpse()
availableATC(cdm, level = c("ATC 4th")) |> glimpse()
availableATC(cdm, level = c("ATC 5th")) |> glimpse()

In this example, we will produce an ATC level 1 codelist based on Alimentary Tract and Metabolism Drugs.

atc_codelist <- getATCCodes(
  cdm = cdm,
  level = "ATC 1st",
  name = "alimentary tract and metabolism"
)

atc_codelist

Similarly as with getDrugIngredientCodes(), we can use nameStyle to specify the name of the elements in the list, type argument to obtain a codelist with details, the doseForm argument to restrict to specific dose forms, the doseUnit argument to restrict to specific dose unit, and the routeCategory argument to restrict to specific route categories.