The hardware and bandwidth for this mirror is donated by METANET, the Webhosting and Full Service-Cloud Provider.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]metanet.ch.
We saw in the previous vignette how we can summarise the overlap
between cohorts. In addition to this, we might also be interested in
timings between cohorts. That is, the time between an individual
entering one cohort and another. For this we can use the
summariseCohortTiming()
. In this example we’ll look at the
time between entering cohorts for acetaminophen, morphine, and oxycodone
using the Eunomia data.
library(CDMConnector)
library(CodelistGenerator)
library(CohortCharacteristics)
library(dplyr)
library(ggplot2)
con <- DBI::dbConnect(duckdb::duckdb(),
dbdir = CDMConnector::eunomia_dir()
)
cdm <- CDMConnector::cdm_from_con(con,
cdm_schem = "main",
write_schema = "main",
cdm_name = "Eunomia"
)
meds_cs <- getDrugIngredientCodes(
cdm = cdm,
name = c(
"acetaminophen",
"morphine",
"warfarin"
)
)
cdm <- generateConceptCohortSet(
cdm = cdm,
name = "meds",
conceptSet = meds_cs,
end = "event_end_date",
limit = "all",
overwrite = TRUE
)
settings(cdm$meds)
#> # A tibble: 3 × 6
#> cohort_definition_id cohort_name limit prior_observation future_observation
#> <int> <chr> <chr> <dbl> <dbl>
#> 1 1 11289_warfarin all 0 0
#> 2 2 161_acetamino… all 0 0
#> 3 3 7052_morphine all 0 0
#> # ℹ 1 more variable: end <chr>
cohortCount(cdm$meds)
#> # A tibble: 3 × 3
#> cohort_definition_id number_records number_subjects
#> <int> <int> <int>
#> 1 1 137 137
#> 2 2 13908 2679
#> 3 3 35 35
Now we have our cohorts we can summarise the timing between cohort entry. Note setting restrictToFirstEntry to TRUE will mean that we only consider timing between an individual’s first record in each cohort (i.e. their first exposure to each of the medications).
meds_timing <- cdm$meds |>
summariseCohortTiming(restrictToFirstEntry = TRUE)
meds_timing |>
glimpse()
#> Rows: 42
#> Columns: 13
#> $ result_id <int> 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,…
#> $ cdm_name <chr> "Eunomia", "Eunomia", "Eunomia", "Eunomia", "Eunomia"…
#> $ group_name <chr> "cohort_name_reference &&& cohort_name_comparator", "…
#> $ group_level <chr> "161_acetaminophen &&& 11289_warfarin", "11289_warfar…
#> $ strata_name <chr> "overall", "overall", "overall", "overall", "overall"…
#> $ strata_level <chr> "overall", "overall", "overall", "overall", "overall"…
#> $ variable_name <chr> "number records", "number records", "number records",…
#> $ variable_level <chr> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, N…
#> $ estimate_name <chr> "count", "count", "count", "count", "count", "count",…
#> $ estimate_type <chr> "integer", "integer", "integer", "integer", "integer"…
#> $ estimate_value <chr> "136", "136", "35", "35", "6", "6", "136", "136", "35…
#> $ additional_name <chr> "overall", "overall", "overall", "overall", "overall"…
#> $ additional_level <chr> "overall", "overall", "overall", "overall", "overall"…
As with cohort overlap, we have table and plotting functions to help view our results.
tableCohortTiming(meds_timing,
timeScale = "years",
.options = list(decimals = c(numeric = 0))
)
CDM name | Cohort name reference | Cohort name comparator | Variable name | Estimate name | Estimate value |
---|---|---|---|---|---|
Eunomia | 11289 warfarin | 161 acetaminophen | Number records | N | 136 |
Number subjects | N | 136 | |||
7052 morphine | Number records | N | 6 | ||
Number subjects | N | 6 | |||
161 acetaminophen | 7052 morphine | Number records | N | 35 | |
Number subjects | N | 35 | |||
11289 warfarin | 161 acetaminophen | Years between cohort entries | Median [Q25 - Q75] | -54 [-67 - -46] | |
Range | -92 - 3 | ||||
7052 morphine | Years between cohort entries | Median [Q25 - Q75] | -5 [-10 - 5] | ||
Range | -19 - 9 | ||||
161 acetaminophen | 7052 morphine | Years between cohort entries | Median [Q25 - Q75] | 16 [5 - 34] | |
Range | -34 - 77 |
plotCohortTiming(meds_timing,
plotType = "boxplot",
timeScale = "years"
)
If we want to see an even more granular summary of cohort timings we can make a density plot instead of a box plot. Note, for this we’ll need to set density as TRUE when getting our initial results.
meds_timing <- cdm$meds |>
summariseCohortTiming(
restrictToFirstEntry = TRUE,
density = TRUE
)
plotCohortTiming(meds_timing,
plotType = "density",
timeScale = "years"
)
As well as generating these estimates for cohorts overall, we can also obtain stratified estimates.
cdm$meds <- cdm$meds |>
PatientProfiles::addAge(ageGroup = list(c(0, 49), c(50, 150))) |>
compute(temporary = FALSE, name = "meds") |>
newCohortTable()
meds_timing <- cdm$meds |>
summariseCohortTiming(
restrictToFirstEntry = TRUE,
strata = list("age_group"),
density = TRUE
)
tableCohortTiming(meds_timing,
timeScale = "years",
.options = list(decimals = c(numeric = 0))
)
CDM name | Cohort name reference | Cohort name comparator | Variable name | Estimate name | Age group | ||
---|---|---|---|---|---|---|---|
0 to 49 | 50 to 150 | Overall | |||||
Eunomia | 11289 warfarin | 161 acetaminophen | Number records | N | 8 | 1 | 9 |
Number subjects | N | 8 | 1 | 9 | |||
7052 morphine | Number records | N | - | 6 | 6 | ||
Number subjects | N | - | 6 | 6 | |||
161 acetaminophen | 7052 morphine | Number records | N | 25 | 1 | 26 | |
Number subjects | N | 25 | 1 | 26 | |||
11289 warfarin | 161 acetaminophen | Years between cohort entries | Median [Q25 - Q75] | -45 [-46 - -33] | 2 [2 - 2] | -44 [-46 - -32] | |
Range | -49 - -29 | 2 - 2 | -49 - 2 | ||||
7052 morphine | Years between cohort entries | Median [Q25 - Q75] | - | -5 [-10 - 5] | -5 [-10 - 5] | ||
Range | - | -19 - 9 | -19 - 9 | ||||
161 acetaminophen | 7052 morphine | Years between cohort entries | Median [Q25 - Q75] | 9 [0 - 30] | 24 [24 - 24] | 10 [1 - 29] | |
Range | -34 - 37 | 24 - 24 | -34 - 37 |
plotCohortTiming(meds_timing,
plotType = "boxplot",
timeScale = "years",
facet = "strata_level",
colour = "strata_level",
colourName = "Age group"
)
These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.