Introduction To DrugExposureDiagnostics
Source:vignettes/IntroductionToDrugExposureDiagnostics.Rmd
IntroductionToDrugExposureDiagnostics.Rmd
First, connect to the database. Examples of how to connect your
database using CDMConnector can be found here: https://darwin-eu.github.io/CDMConnector/articles/a04_DBI_connection_examples.html
Here we use the internal mock database.
cdm <- mockDrugExposure()
#> Note: method with signature 'DBIConnection#Id' chosen for function 'dbExistsTable',
#> target signature 'duckdb_connection#Id'.
#> "duckdb_connection#ANY" would also be valid
#> Warning: ! 1 column in vocabulary do not match expected column type:
#> • `vocabulary_concept_id` is numeric but expected integer
#> Warning: ! 1 column in drug_strength do not match expected column type:
#> • `box_size` is numeric but expected integer
Drug(s) of interest
In the DrugExposureDiagnostics package, all the diagnostics are
conducted on ingredient level, and if requested, additionally on drug
level. We will use the ingredient “acetaminophen” as an example.
Here is a brief look at this ingredient.
Property | Value |
Concept Name | acetaminophen |
Domain ID | Drug |
Concept Class ID | Ingredient |
Vocabulary ID | RxNorm |
Concept ID | 1125315 |
Concept code | 161 |
Validity | Valid |
Concept | Standard |
Valid start | 01-Jan-1970 |
Valid end | 31-Dec-2099 |
Running the diagnostics
We can run all available checks at the same time using the
´executeChecks()´ function. This will return a list which contains the
results of each check.
Multiple ingredients can be added in the vector of ´ingredients´
all_checks <- executeChecks(cdm,
ingredients = c(1125315),
subsetToConceptId = NULL,
checks = c(
"missing", "exposureDuration", "type", "route", "sourceConcept", "daysSupply",
"verbatimEndDate", "dose", "sig", "quantity", "diagnosticsSummary"
),
minCellCount = 5,
sample = 10000,
tablePrefix = NULL,
earliestStartDate = "2010-01-01",
verbose = FALSE,
byConcept = TRUE
)
#> population after earliestStartDate smaller than sample, sampling ignored
#> ℹ The following estimates will be computed:
#> • daily_dose: count_missing, percentage_missing, mean, sd, q05, q25, median,
#> q75, q95, min, max
#> ! Table is collected to memory as not all requested estimates are supported on
#> the database side
#> → Start summary of data, at 2024-11-22 18:52:23.466645
#>
#> ✔ Summary finished, at 2024-11-22 18:52:23.768233
The cdm
is the database reference of the OMOP CDM using
the CDMConnector
package.
The ingredients
is a list of ingredients of interests, by
default it is 1125315 for acetaminophen. The
subsetToConceptId
vector of concept IDs of the ingredients
to filter. If a concept ID is positive it will be included, a negative
one will be excluded. If NULL, all concept IDs for an ingredient will be
considered. checks
allows to select the checks to be
executed, by default the missing values, the exposure duration and the
quantity checks will be run. The minCellCount
is minimum
number of events to report, numbers lower than this will be obscured.
sample
is the number of samples, by default, 10.000 drug
record samples will be used.
The tablePrefix
is an optional value for database tables
that will be created during executeChecks.
earliestStartDate
is the earliest data from which drug
records will be included. verbose
is a parameter that
enables the printing of messages to the console. byConcept
is a boolean that determines if only overall results should be returned
or also by drug concept.
The check “missing” outputs the missingValuesOverall
if
byConcept = FALSE
and additionally
missingValuesbyConcept
if
byConcept = TRUE
The check “exposureDuration” outputs the
drugExposureDurationOverall
if
byConcept = FALSE
and additionally
drugExposureDurationbyConcept
if
byConcept = TRUE
The check “type” outputs the drugTypesOverall
if
byConcept = FALSE
and additionally
drugTypesbyConcept
if byConcept = TRUE
The check “route” outputs the drugRoutesOverall
if
byConcept = FALSE
and additionally
drugRoutesbyConcept
if byConcept = TRUE
The check “sourceConcept” outputs the sourceConceptsOverall
(which is actually the drug concept level. It disregards the
byConcept
argument because only the drug concept level
makes sense here)
The check “daysSupply” outputs the drugDaysSupplyOverall
if
byConcept = FALSE
and additionally
drugDaysSupplybyConcept
if
byConcept = TRUE
The check “verbatimEndDate” outputs the drugVerbatimEndDate
if byConcept = FALSE
and additionally
drugVerbatimEndDatebyConcept
if
byConcept = TRUE
The check “dose” outputs the drugDoseOverall
(output only
on ingredient level. It disregards the byConcept
argument
because only the drug concept level makes sense here)
The check “sig” outputs the drugSig
if
byConcept = FALSE
and additionally
drugSigbyConcept
if byConcept = TRUE
The check “quantity” outputs the drugQuantity
if
byConcept = FALSE
and additionally
drugQuantitybyConcept
if
byConcept = TRUE
The check “diagnosticsSummary” outputs a summary called
diagnosticsSummary
Here, we see the files created:
names(all_checks)
#> [1] "conceptSummary" "missingValuesOverall"
#> [3] "missingValuesByConcept" "drugExposureDurationOverall"
#> [5] "drugExposureDurationByConcept" "drugTypesOverall"
#> [7] "drugTypesByConcept" "drugRoutesOverall"
#> [9] "drugRoutesByConcept" "drugSourceConceptsOverall"
#> [11] "drugDaysSupply" "drugDaysSupplyByConcept"
#> [13] "drugVerbatimEndDate" "drugVerbatimEndDateByConcept"
#> [15] "drugDose" "drugSig"
#> [17] "drugSigByConcept" "drugQuantity"
#> [19] "drugQuantityByConcept" "diagnosticsSummary"
#> [21] "metadata"
Assessing the drug concepts (of interest)
The first item shown, the conceptSummary
is not the
output from a check but always output. This table is used within the
function as an input for all the requested checks.
It contains information from the CONCEPT table and DRUG_STRENGTH
table.
The conceptSummary
has several use:
It can be quickly seen whether a certain drug is mapped on ingredient
level. Thereby, the drug_concept_id and ingredient_concept_id are
identical.
Furthermore, the conceptSummary
can be used to make
decisions about further refine the concept list. For example, though the
argument subsetToConceptId
in the
executeChecks()
function, the selected concepts can be
requested or eliminated.
The conceptSummary
in the case of acetaminophen with
subsetToConceptId = NULL
, the following drug concepts are
part of the diagnostics investigation.
datatable(all_checks$conceptSummary,
rownames = FALSE
)
Column | Description |
---|---|
drug_concept_id | ID of the drug concept. |
drug | Name of the drug concept. |
ingredient_concept_id | Concept ID of ingredient. |
ingredient | Name of drug ingredient for which the checks have been performed. |
n_records | Number of records for drug concept. |
domain_id | From the CONCEPT table. A foreign key to the domain table the drug concept belongs to. |
vocabulary_id | From the CONCEPT table. A foreign key to the vocabulary table indicating from which source the drug concept has been adapted. |
concept_class_id | From the CONCEPT table. The concept class of the drug concept (e.g.‘Ingredient’ or ‘Clinical Drug’). |
standard_concept | From the CONCEPT table. A flag indicating whether the drug concept is standard (‘S’), a classification (‘C’), or a non-standard Source (NULL). |
concept_code | From the CONCEPT table. The concept code represents the identifier of the Concept in the source vocabulary. |
valid_start_date | From the CONCEPT table. The date when the drug concept was first recorded |
valid_end_date | From the CONCEPT table. The date when the drug concept became invalid because it was deleted or superseded (updated) by a new concept. |
invalid_reason | From the CONCEPT table. Reason the Concept was invalidated. Possible values are D (deleted), U (replaced with an update) or NULL when valid_end_date has the default value. |
amount_value | From DRUG_STRENGTH table. The numeric value or the amount of active ingredient contained within the drug product. |
amount_unit_concept_id | From DRUG_STRENGTH table. The Concept representing the Unit of measure for the amount of active ingredient contained within the drug product. |
numerator_value | From DRUG_STRENGTH table. The concentration of the active ingredient contained within the drug product. |
numerator_unit_concept_id | From DRUG_STRENGTH table. The Concept representing the Unit of measure for the concentration of active ingredient. |
numerator_unit | From the CONCEPT table. The concept name associated with the numerator_unit_concept_id. |
denominator_value | From DRUG_STRENGTH table. The amount of total liquid (or other divisible product, such as ointment, gel, spray, etc.). |
denominator_unit_concept_id | From DRUG_STRENGTH table. The Concept representing the denominator unit for the concentration of active ingredient. |
denominator_unit | From the CONCEPT table. The concept name associated with the denominator_unit_concept_id |
box_size | The number of units of Clinical Branded Drug or Quantified Clinical or Branded Drug contained in a box as dispensed to the patient. |
amount_unit | From DRUG_STRENGTH table. |
dose_form | From CONCEPT_RELATIONSHIP table. The RxNorm dose form associated with the drug concept. |
result_obscured | TRUE if count has been suppressed due to being below the minimum cell count, otherwise FALSE. |
Saving the diagnostic output
After running the checks, we can write the created outputs (CSV
files) into a zip file to disk using the
writeResultToDisk()
function. The zip created from using
the writeResultToDisk()
function serves as the input for
the corresponding Shiny Application.
Please replace the “your_database” with the name of your database.
Create your designated “output_folder” at your desired location and put
the path if not the working directory.
writeResultToDisk(all_checks,
databaseId = "your_database",
outputFolder = "output_folder"
)
View results in the Shiny app & make it available for publishing
viewResults(
dataFolder = file.path(getwd(), "output_folder"),
makePublishable = TRUE,
publishDir = file.path(getwd(), "MyStudyResultsExplorer"),
overwritePublishDir = TRUE
)