Skip to contents

Introduction

The DrugUtilisation package includes a range of functions that add drug-related information of subjects in OMOP CDM tables and cohort tables. In this vignette, we will explore these functions and provide some examples for its usage.

Create a drug utilisation cohort

We will use Acetaminophen as our example drug to construct our drug utilisation cohort. To begin, we will employ getDrugIngredientCodes() function from CodelistGenerator to generate a concept list associated with Acetaminophen.

conceptList <- getDrugIngredientCodes(cdm, c("acetaminophen"))
conceptList
#> 
#> - acetaminophen (4 codes)

Next, we create a drug utilisation cohort by using the conceptList with the generateDrugUtilisationCohortSet() function. For a better understanding of the arguments and functionalities of generateDrugUtilisationCohortSet(), please refer to the Use DrugUtilisation to create a cohort vignette.

cdm <- generateDrugUtilisationCohortSet(
  cdm  = cdm,
  name = "acetaminophen_example1",
  conceptSet = conceptList
)

Adding routes with addRoute() function

addRoute() function utilises an internal CSV file containing all possible routes for various drug dose forms supported by the package. The function is designed to seamlessly incorporate route information into your drug table for the supported dose forms. See the example below to know how it works.

cdm[["drug_exposure"]] %>%
  addRoute() 
#> # Source:   SQL [?? x 8]
#> # Database: DuckDB v0.10.2 [unknown@Linux 6.5.0-1018-azure:R 4.4.0/:memory:]
#>    drug_exposure_id person_id drug_concept_id drug_exposure_start_date
#>               <int>     <int>           <dbl> <date>                  
#>  1                1         1         1503328 2022-01-11              
#>  2                2         1         2905077 2021-10-26              
#>  3                3         1         1539463 2021-08-10              
#>  4                4         1         1516980 2021-12-20              
#>  5                5         2         1516978 2013-05-09              
#>  6                6         2         2905077 2013-01-20              
#>  7                7         3         1125360 2013-05-25              
#>  8                9         3         1516978 2010-07-16              
#>  9               10         3         2905077 2013-01-26              
#> 10               11         4         1125360 2003-12-11              
#> # ℹ more rows
#> # ℹ 4 more variables: drug_exposure_end_date <date>,
#> #   drug_type_concept_id <dbl>, quantity <dbl>, route <chr>

Generating patterns with patternTable() function

The patternTable() function in the DrugUtilisation package is a powerful tool for deriving patterns from a drug strength table. This function extracts distinct patterns, associating them with pattern_id and formula_id. The resulting tibble provides the following data:

  • number_concepts: the count of distinct concepts in the patterns.
  • number_ingredients: the count of distinct ingredients involved.
  • number_records: the overall count of records in the patterns.

Moreover, the tibble includes a column indicating potentially valid and invalid combinations.

patternTable(cdm)
#> # A tibble: 5 × 12
#>   pattern_id formula_name            validity number_concepts number_ingredients
#>        <dbl> <chr>                   <chr>              <dbl>              <dbl>
#> 1          9 fixed amount formulati… pattern…               7                  4
#> 2         18 concentration formulat… pattern…               1                  1
#> 3         24 concentration formulat… pattern…               1                  1
#> 4         40 concentration formulat… pattern…               1                  1
#> 5         NA NA                      no patt…               4                  4
#> # ℹ 7 more variables: number_records <dbl>, amount_numeric <dbl>,
#> #   amount_unit_concept_id <dbl>, numerator_numeric <dbl>,
#> #   numerator_unit_concept_id <dbl>, denominator_numeric <dbl>,
#> #   denominator_unit_concept_id <dbl>

For detailed information about the patterns, their associated formula, and combinations of amount_unit, numerator_unit, and denominator_unit, you can refer to the data:

patternsWithFormula

Get daily dose with addDailyDose() function

Now that we have all the patterns and formulas supported, the computation of daily doses can be performed using the addDailyDose() function. This function will add to the data with additional columns, including those for quantity, daily dose, unit, and route.

addDailyDose(
  cdm$drug_exposure,
  cdm = cdm,
  ingredientConceptId = 1125315
)
#> # Source:   table<og_007_1715701318> [?? x 9]
#> # Database: DuckDB v0.10.2 [unknown@Linux 6.5.0-1018-azure:R 4.4.0/:memory:]
#>    drug_exposure_id person_id drug_concept_id drug_exposure_start_date
#>               <int>     <int>           <dbl> <date>                  
#>  1                2         1         2905077 2021-10-26              
#>  2                6         2         2905077 2013-01-20              
#>  3                7         3         1125360 2013-05-25              
#>  4               10         3         2905077 2013-01-26              
#>  5               11         4         1125360 2003-12-11              
#>  6               13         4         1125360 1990-09-04              
#>  7               15         4        43135274 1995-04-04              
#>  8               21         6        43135274 2020-05-19              
#>  9               25         7         2905077 2005-11-18              
#> 10               26         7         2905077 2008-10-22              
#> # ℹ more rows
#> # ℹ 5 more variables: drug_exposure_end_date <date>,
#> #   drug_type_concept_id <dbl>, quantity <dbl>, daily_dose <dbl>, unit <chr>

There is also a function, dailyDoseCoverage(), to check the coverage of daily dose computation for chosen concept sets and ingredients.

suppressWarnings(dailyDoseCoverage(cdm, 1125315))
#>  The following estimates will be computed:
#>  daily_dose: count_missing, percentage_missing, mean, sd, min, q05, q25,
#>   median, q75, q95, max
#> ! Table is collected to memory as not all requested estimates are supported on
#>   the database side
#> → Start summary of data, at 2024-05-14 15:41:59.135467
#> 
#>  Summary finished, at 2024-05-14 15:41:59.405324
#> ! The following variables: result_type, package_name, package_version; were added to `settings`
#> # A tibble: 84 × 13
#>    result_id cdm_name group_name      group_level   strata_name strata_level
#>        <int> <chr>    <chr>           <chr>         <chr>       <chr>       
#>  1         1 DUS MOCK ingredient_name acetaminophen overall     overall     
#>  2         1 DUS MOCK ingredient_name acetaminophen overall     overall     
#>  3         1 DUS MOCK ingredient_name acetaminophen overall     overall     
#>  4         1 DUS MOCK ingredient_name acetaminophen overall     overall     
#>  5         1 DUS MOCK ingredient_name acetaminophen overall     overall     
#>  6         1 DUS MOCK ingredient_name acetaminophen overall     overall     
#>  7         1 DUS MOCK ingredient_name acetaminophen overall     overall     
#>  8         1 DUS MOCK ingredient_name acetaminophen overall     overall     
#>  9         1 DUS MOCK ingredient_name acetaminophen overall     overall     
#> 10         1 DUS MOCK ingredient_name acetaminophen overall     overall     
#> # ℹ 74 more rows
#> # ℹ 7 more variables: variable_name <chr>, variable_level <chr>,
#> #   estimate_name <chr>, estimate_type <chr>, estimate_value <chr>,
#> #   additional_name <chr>, additional_level <chr>

Adding Drug Usage Details to a Cohort with addDrugUse() function

Additional drug usage details, including duration, initial dose, cumulative dose, etc., can be incorporated into a cohort using the addDrugUse() function.

cdm$acetaminophen_example1 |>
  addDrugUse(ingredientConceptId = 1125315)
#> # Source:   table<og_014_1715701327> [?? x 13]
#> # Database: DuckDB v0.10.2 [unknown@Linux 6.5.0-1018-azure:R 4.4.0/:memory:]
#>    cohort_definition_id subject_id cohort_start_date cohort_end_date duration
#>                   <int>      <int> <date>            <date>             <dbl>
#>  1                    1          7 2008-10-22        2008-12-23            63
#>  2                    1         86 2005-02-12        2016-06-22          4149
#>  3                    1         25 2013-04-08        2016-08-10          1221
#>  4                    1         12 2003-06-26        2004-10-19           482
#>  5                    1         36 2018-05-24        2019-10-31           526
#>  6                    1        146 2008-04-22        2008-05-25            34
#>  7                    1        186 2000-10-19        2005-05-04          1659
#>  8                    1        114 2022-10-17        2022-11-13            28
#>  9                    1        184 2009-04-22        2010-03-13           326
#> 10                    1         18 2015-08-16        2017-08-06           722
#> # ℹ more rows
#> # ℹ 8 more variables: number_exposures <dbl>, cumulative_quantity <dbl>,
#> #   initial_quantity <dbl>, impute_duration_percentage <dbl>,
#> #   number_eras <dbl>, impute_daily_dose_percentage <dbl>,
#> #   initial_daily_dose_milligram <dbl>, cumulative_dose_milligram <dbl>

duration parameter

The duration parameter is a boolean variable (TRUE/FALSE) determining whether to include duration related columns, which correspond to:

  1. duration: duration is calculated as cohort_end_date - cohort_start_date + 1.
  2. impute_duration_percentage: if a drug exposure record does not have the duration of the exposure, or falls outside the specified duration range, duration will be imputed. The number of records that have been imputed or that would have been imputed (if we choose not to impute the duration) is recorded in this column.

To set the imputation method for duration, use the imputeDuration input, which can take values such as none (default), median, mode or a numerical value. Define the durationRange parameter as a numeric vector of length two, where the first value should be equal or smaller than the second one. If set to NULL, no restrictions are applied.

quantity parameter

The quantity parameter, another boolean variable (TRUE/FALSE), controls the inclusion of quantity-related columns. If set to TRUE (default), the following columns are added:

  1. cumulative_quantity: cumulative sum of the column quantity of the drug_exposure table during the drug exposure period.
  2. initial_quantity: quantity at drug_exposure_start_date.

dose parameter

The dose parameter, also a boolean variable (TRUE/FALSE), governs the addition of daily dose-related columns. When set to TRUE, the following columns are added:

  1. initial_daily_dose_milligram: dose at drug_exposure_start_date.
  2. cumulative_dose_milligram: cumulative sum of the column dose of drug_exposure table during the drug exposure period.
  3. impute_daily_dose_percentage: If daily dose is missing, or falls outside the imputation range, records will be imputed. This column shows the number of records that have been imputed or that would have been imputed (if we choose not to impute the daily dose).

Similar to duration imputation, use the imputeDose parameter to set the method for imputing daily dose, with options like none (default), median, mean, mode. Define the imputation range with the dailyDoseRange parameter, a numeric vector of length two, where the first value should be equal or smaller than the second one. If set to NULL, no restrictions are applied.

These parameters offer flexibility in customizing the drug usage details added to the cohort. See the next example, where we use the cohort created at the beginning of this vignette acetaminophen_example1.

addDrugUse(
  cohort = cdm[["acetaminophen_example1"]],
  cdm    = cdm,
  ingredientConceptId = 1125315,
  duration = TRUE,
  quantity = TRUE,
  dose     = TRUE
)
#> # Source:   table<og_019_1715701334> [?? x 13]
#> # Database: DuckDB v0.10.2 [unknown@Linux 6.5.0-1018-azure:R 4.4.0/:memory:]
#>    cohort_definition_id subject_id cohort_start_date cohort_end_date duration
#>                   <int>      <int> <date>            <date>             <dbl>
#>  1                    1          7 2008-10-22        2008-12-23            63
#>  2                    1         86 2005-02-12        2016-06-22          4149
#>  3                    1         25 2013-04-08        2016-08-10          1221
#>  4                    1         12 2003-06-26        2004-10-19           482
#>  5                    1         36 2018-05-24        2019-10-31           526
#>  6                    1        146 2008-04-22        2008-05-25            34
#>  7                    1        186 2000-10-19        2005-05-04          1659
#>  8                    1        114 2022-10-17        2022-11-13            28
#>  9                    1        184 2009-04-22        2010-03-13           326
#> 10                    1         18 2015-08-16        2017-08-06           722
#> # ℹ more rows
#> # ℹ 8 more variables: number_exposures <dbl>, cumulative_quantity <dbl>,
#> #   initial_quantity <dbl>, impute_duration_percentage <dbl>,
#> #   number_eras <dbl>, impute_daily_dose_percentage <dbl>,
#> #   initial_daily_dose_milligram <dbl>, cumulative_dose_milligram <dbl>

If all these parameters are set to false, only number_exposures and number_eras will be added.

Parameters for Joining Exposures

The way continuous exposures are joined can be configured by using different parameters. Let’s have a look to all the options we have.

gapEra parameter

This parameter sets the number of days between two continuous exposures to be considered in the same era. If the previous exposure’s end date minus the next exposure’s start date is less than or equal to the specified gapEra, these two exposures will be joined. Let’s see an illustrative example.

First, let’s create a cohort with gapEra = 0. For a better understanding, we will observe only subject number 56.

cdm <- generateDrugUtilisationCohortSet(
  cdm = cdm,
  name = "acetaminophen_example2",
  conceptSet = conceptList,
  gapEra = 0
)
 
cdm$drug_exposure %>%
  filter(drug_concept_id %in% !!conceptList$acetaminophen) %>%
  filter(person_id == 56)
#> # Source:   SQL [2 x 7]
#> # Database: DuckDB v0.10.2 [unknown@Linux 6.5.0-1018-azure:R 4.4.0/:memory:]
#>   drug_exposure_id person_id drug_concept_id drug_exposure_start_date
#>              <int>     <int>           <dbl> <date>                  
#> 1              166        56         1125360 2022-01-27              
#> 2              164        56        43135274 2021-08-08              
#> # ℹ 3 more variables: drug_exposure_end_date <date>,
#> #   drug_type_concept_id <dbl>, quantity <dbl>

This subject has two different drug exposure periods separated by less than 6 months. Hence, it has two different cohort periods:

cdm[["acetaminophen_example2"]] %>%
  addDrugUse(
    ingredientConceptId = 1125315,
    gapEra = 0
  ) %>%
  filter(subject_id == 56)
#> # Source:   SQL [2 x 13]
#> # Database: DuckDB v0.10.2 [unknown@Linux 6.5.0-1018-azure:R 4.4.0/:memory:]
#>   cohort_definition_id subject_id cohort_start_date cohort_end_date duration
#>                  <int>      <int> <date>            <date>             <dbl>
#> 1                    1         56 2022-01-27        2022-03-04            37
#> 2                    1         56 2021-08-08        2021-09-17            41
#> # ℹ 8 more variables: number_exposures <dbl>, cumulative_quantity <dbl>,
#> #   initial_quantity <dbl>, impute_duration_percentage <dbl>,
#> #   number_eras <dbl>, impute_daily_dose_percentage <dbl>,
#> #   initial_daily_dose_milligram <dbl>, cumulative_dose_milligram <dbl>

Now, we merge this two periods by modifying the gapEra input when creating the cohort. For a better understanding of gapEra arguments and functionalities, please see Use DrugUtilisation to create a cohort vignette.

cdm <- generateDrugUtilisationCohortSet(
  cdm = cdm,
  name = "acetaminophen_example3",
  conceptSet = conceptList,
  gapEra = 180
)

cdm$acetaminophen_example3 %>%
  addDrugUse(
    ingredientConceptId = 1125315,
    gapEra = 180,
    duration = TRUE,
    quantity = FALSE,
    dose = FALSE
  ) %>%
  filter(subject_id == 56) 
#> # Source:   SQL [1 x 8]
#> # Database: DuckDB v0.10.2 [unknown@Linux 6.5.0-1018-azure:R 4.4.0/:memory:]
#>   cohort_definition_id subject_id cohort_start_date cohort_end_date duration
#>                  <int>      <int> <date>            <date>             <dbl>
#> 1                    1         56 2021-08-08        2022-03-04           209
#> # ℹ 3 more variables: number_exposures <dbl>, impute_duration_percentage <dbl>,
#> #   number_eras <dbl>

See that we only have one record with two exposures for subject number 56. Note that the number of eras is still 1, as we have defined the same gapEra as when the cohort was created. However, it is possible to specify a different gapEra than the one defined when the cohort was created.

cdm$acetaminophen_example3 %>%
  addDrugUse(
    ingredientConceptId = 1125315,
    gapEra = 0
  ) %>%
  filter(subject_id == 56) 
#> # Source:   SQL [1 x 13]
#> # Database: DuckDB v0.10.2 [unknown@Linux 6.5.0-1018-azure:R 4.4.0/:memory:]
#>   cohort_definition_id subject_id cohort_start_date cohort_end_date duration
#>                  <int>      <int> <date>            <date>             <dbl>
#> 1                    1         56 2021-08-08        2022-03-04           209
#> # ℹ 8 more variables: number_exposures <dbl>, cumulative_quantity <dbl>,
#> #   initial_quantity <dbl>, impute_duration_percentage <dbl>,
#> #   number_eras <dbl>, impute_daily_dose_percentage <dbl>,
#> #   initial_daily_dose_milligram <dbl>, cumulative_dose_milligram <dbl>

Notice that number_eras now indicates that we have two eras within the same record.

eraJoinMode parameter

This parameter defines how two different continuous exposures are joined in an era. There are four options:

  1. eraJoinMode = "zero" (default option): Exposures are joined considering that the period between both continuous exposures means the subject is treated with a daily dose of zero. The time between both exposures contributes to the total exposed time.
  2. eraJoinMode = "join": Exposures are joined, considering that the period between both continuous exposures means the subject is treated with a daily dose of zero. The time between both exposures does not contribute to the total exposed time.
  3. eraJoinMode = "previous": Exposures are joined, considering that the period between both continuous exposures means the subject is treated with the daily dose of the previous subexposure. The time between both exposures contributes to the total exposed time.
  4. eraJoinMode = "subsequent": Exposures are joined, considering that the period between both continuous exposures means the subject is treated with the daily dose of the subsequent subexposure. The time between both exposures contributes to the total exposed time.

overlapMode parameter

This parameter defines how the overlapping between two exposures that do not start on the same day is resolved inside a subexposure. There are five possible options:

  1. overlapMode* = "sum" (default): The considered daily dose is the sum of all the exposures present in the subexposure.
  2. overlapMode = minimum: The considered daily dose is the minimum of all the exposures in the subexposure.
  3. overlapMode = maximum: The considered daily dose is the maximum of all the exposures in the subexposure.
  4. overlapMode = previous: The considered daily dose is that of the earliest exposure.
  5. overlapMode = subsequent: The considered daily dose is that of the latest exposure.

sameIndexMode parameter

This parameter works similarly to overlapMode, but it customizes the overlapping between two exposures starting on the same date. It includes the options sum (default), minimum, and maximum described in overlapMode.

For example, the following example sets a maximum gap of 30 days for exposures to be joined. It uses the daily dose of the previous subexposure when joining exposures, employs the minimum daily dose for exposures starting on the same day, and considers the minimum daily dose for exposures that overlap.

cdm[["acetaminophen_example1"]] %>%
  addDrugUse(ingredientConceptId = 1125315,
             gapEra = 30,
             eraJoinMode = "previous",
             overlapMode = "minimum",
             sameIndexMode = "minimum")
#> # Source:   table<og_038_1715701364> [?? x 13]
#> # Database: DuckDB v0.10.2 [unknown@Linux 6.5.0-1018-azure:R 4.4.0/:memory:]
#>    cohort_definition_id subject_id cohort_start_date cohort_end_date duration
#>                   <int>      <int> <date>            <date>             <dbl>
#>  1                    1          7 2008-10-22        2008-12-23            63
#>  2                    1         86 2005-02-12        2016-06-22          4149
#>  3                    1         25 2013-04-08        2016-08-10          1221
#>  4                    1         12 2003-06-26        2004-10-19           482
#>  5                    1         36 2018-05-24        2019-10-31           526
#>  6                    1        146 2008-04-22        2008-05-25            34
#>  7                    1        186 2000-10-19        2005-05-04          1659
#>  8                    1        114 2022-10-17        2022-11-13            28
#>  9                    1        184 2009-04-22        2010-03-13           326
#> 10                    1         18 2015-08-16        2017-08-06           722
#> # ℹ more rows
#> # ℹ 8 more variables: number_exposures <dbl>, cumulative_quantity <dbl>,
#> #   initial_quantity <dbl>, impute_duration_percentage <dbl>,
#> #   number_eras <dbl>, impute_daily_dose_percentage <dbl>,
#> #   initial_daily_dose_milligram <dbl>, cumulative_dose_milligram <dbl>

Summarise drug usage information with summariseDrugUse() function

This functions creates a tibble summarising the dose table across multiple cohorts. See an example below:

cdm[["acetaminophen_example1"]] <- cdm[["acetaminophen_example1"]] %>% 
  addDrugUse(
    cdm = cdm,
    ingredientConceptId = 1125315
  )

summariseDrugUse(cdm[["acetaminophen_example1"]])
#> # A tibble: 101 × 13
#>    result_id cdm_name group_name  group_level   strata_name strata_level
#>        <int> <chr>    <chr>       <chr>         <chr>       <chr>       
#>  1         1 DUS MOCK cohort_name acetaminophen overall     overall     
#>  2         1 DUS MOCK cohort_name acetaminophen overall     overall     
#>  3         1 DUS MOCK cohort_name acetaminophen overall     overall     
#>  4         1 DUS MOCK cohort_name acetaminophen overall     overall     
#>  5         1 DUS MOCK cohort_name acetaminophen overall     overall     
#>  6         1 DUS MOCK cohort_name acetaminophen overall     overall     
#>  7         1 DUS MOCK cohort_name acetaminophen overall     overall     
#>  8         1 DUS MOCK cohort_name acetaminophen overall     overall     
#>  9         1 DUS MOCK cohort_name acetaminophen overall     overall     
#> 10         1 DUS MOCK cohort_name acetaminophen overall     overall     
#> # ℹ 91 more rows
#> # ℹ 7 more variables: variable_name <chr>, variable_level <chr>,
#> #   estimate_name <chr>, estimate_type <chr>, estimate_value <chr>,
#> #   additional_name <chr>, additional_level <chr>

strata parameter

We can also stratify our cohort and calculate the estimates within each strata group by using the strata parameter.

cdm[["acetaminophen_example1"]] <- cdm[["acetaminophen_example1"]] %>%
  addSex() # Function from PatientProfiles

summariseDrugUse(cdm[["acetaminophen_example1"]],
                 strata = list("sex" = "sex")) 
#> # A tibble: 303 × 13
#>    result_id cdm_name group_name  group_level   strata_name strata_level
#>        <int> <chr>    <chr>       <chr>         <chr>       <chr>       
#>  1         1 DUS MOCK cohort_name acetaminophen overall     overall     
#>  2         1 DUS MOCK cohort_name acetaminophen overall     overall     
#>  3         1 DUS MOCK cohort_name acetaminophen overall     overall     
#>  4         1 DUS MOCK cohort_name acetaminophen overall     overall     
#>  5         1 DUS MOCK cohort_name acetaminophen overall     overall     
#>  6         1 DUS MOCK cohort_name acetaminophen overall     overall     
#>  7         1 DUS MOCK cohort_name acetaminophen overall     overall     
#>  8         1 DUS MOCK cohort_name acetaminophen overall     overall     
#>  9         1 DUS MOCK cohort_name acetaminophen overall     overall     
#> 10         1 DUS MOCK cohort_name acetaminophen overall     overall     
#> # ℹ 293 more rows
#> # ℹ 7 more variables: variable_name <chr>, variable_level <chr>,
#> #   estimate_name <chr>, estimate_type <chr>, estimate_value <chr>,
#> #   additional_name <chr>, additional_level <chr>

drugEstimates parameter

Customize the estimates to be calculated by using the drugEstimates parameter. By default, it will compute the minimum value, quartiles (5%, 25%, 50% - median, 75% and 95%), the maximum value, the mean, the standard deviation, and the number of missings values for each column added with addDrugUse().

minCellCount parameter

Specify the minimum number of individuals that a strata group must have in order to appear in the table.