---
title: "Generating vocabulary based codelists for medications"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{a04_GenerateVocabularyBasedCodelist}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
NOT_CRAN <- identical(tolower(Sys.getenv("NOT_CRAN")), "true")

knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  eval = NOT_CRAN
)

CDMConnector::requireEunomia("synpuf-1k", "5.3")
```

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.
```{r,  message=FALSE, warning=FALSE}
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.
```{r}
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.
```{r}
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.
```{r}
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.

```{r}
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.

```{r}
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.
```{r}
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. 

```{r}
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.

```{r}
getDoseUnit(cdm) |> glimpse()
```

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

```{r}
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.

```{r}
getRouteCategories(cdm) |> glimpse()
```

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

```{r}
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.

```{r}
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.

```{r}
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.

```{r}
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.