This document contains the algorithms necessary to code all the outcomes which measure “abstinence from substance use” or “relapse to substance use”. We only include outcomes which result in a single value per subject. These outcomes are:
Group | Endpoint | Class | Reference | Definition | Missing is |
---|---|---|---|---|---|
Relapse | Time to relapse | survival | CTN-0094 | Weeks to relapse (4 consecutive weeks of positive UOS) | Positive |
Relapse | Time to study dropout | survival | CTN-0094 | Weeks to study dropout (4 consecutive weeks of missing UOS) | Missing |
Relapse | Relapse/failure rate | logical | Johnson, Jaffe, & Fudala, 1992 | Failure rate: 2 consecutive positive UOS following 4 weeks of treatment | Positive |
Relapse | Relapse/failure rate | logical | Krupitsky et al., 2004 | Relapse rate (3 consecutive positive UOS) | Positive |
Relapse | Relapse/failure rate | logical | Krupitsky et al., 2006 | Relapse rate (3 consecutive positive UOS) | Positive |
Relapse | Time to opioid use/relapse | survival | Lee et al., 2016 | Weeks to relapse (≥10 days of opioid use in a 28‐day period [a positive UOS was computed as 5 days of opioid use]) | Positive |
Relapse | Time to opioid use/relapse | survival | Lee et al., 2018 CTN-0051 | Weeks to relapse (starting at day 21 post-randomization: 4 consecutive weeks with positive UOS) | Positive |
Relapse | Time to opioid use/relapse | survival | Schottenfeld et al., 2008 | Days to relapse (3 consecutive positive UOS) | Positive |
We will use the table of participant opioid use patterns from the
ctn0094DataExtra
package to calculate these endpoints (we
have a copy of the endpoints in the dataset
outcomesCTN0094
). Importantly, if you wish to apply these
algorithms to calculate endpoints for your data, the participants’
substance use patterns must be stored in the “substance use pattern
word” format shown here. We also show a subset of the data to visualize
a variety of different real substance use patterns.
We first define the following five-value legend:
### Full Data ###
<-
udsOutcomes_df ::outcomesCTN0094 %>%
CTNoteselect(who, usePatternUDS)
# Make a copy
<- udsOutcomes_df
outcomesRel_df
### Examples ###
<- c(1, 163, 210, 242, 4, 17, 13, 1103, 233, 2089)
examplePeople_int %>%
outcomesRel_df filter(who %in% examplePeople_int)
## # A tibble: 10 × 2
## who usePatternUDS
## <dbl> <chr>
## 1 1 ooooooooooooooo
## 2 4 -------------------o-o-o
## 3 13 ------------o-oooooooooo
## 4 17 --++*++++++-++++++-+++-
## 5 163 -o---o---o--o+----------
## 6 210 -++++++++-+++-----------
## 7 233 *+++++++++++o++++++++++o
## 8 242 -----------------------
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o
## 10 2089 ++++---+--------------o-
For example, participant 1 has a use pattern
ooooooooooooooo
(all missing UDS), which means that they
dropped out of the study. In contrast, participant 233 has a use pattern
*+++++++++++o++++++++++o
(nearly all positive UDS): they
did not drop out of the study, but the treatment was completely
ineffective for them. Participant 2089 started the study in a rough
patch, but greatly improved in treatment over time
(++++---+--------------o-
).
Our CTN-0094 research group has two relapse outcomes: Weeks to relapse (4 consecutive weeks of positive UOS) and Weeks to study dropout (4 consecutive weeks of missing UOS).
Definition: Weeks to relapse (4 consecutive weeks of positive UOS); missing is positive
<-
outcomesRel_df %>%
outcomesRel_df rowwise() %>%
mutate(
udsPattern = recode_missing_visits(
use_pattern = usePatternUDS
)%>%
) mutate(
udsPattern = recode_missing_visits(
use_pattern = udsPattern,
missing_is = "*"
)%>%
) mutate(
ctn0094_relapse = detect_in_window(
use_pattern = udsPattern,
window_width = 4L,
threshold = 4L
)%>%
) unnest(cols = "ctn0094_relapse", names_sep = "_") %>%
select(who, starts_with("ctn0094_relapse")) %>%
left_join(outcomesRel_df, ., by = "who")
%>%
outcomesRel_df filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, starts_with("ctn0094_relapse"))
## # A tibble: 10 × 4
## who usePatternUDS ctn0094_relapse_time ctn0094_rela…¹
## <dbl> <chr> <int> <int>
## 1 1 ooooooooooooooo 1 1
## 2 4 -------------------o-o-o 21 0
## 3 13 ------------o-oooooooooo 15 1
## 4 17 --++*++++++-++++++-+++- 3 1
## 5 163 -o---o---o--o+---------- 21 0
## 6 210 -++++++++-+++----------- 2 1
## 7 233 *+++++++++++o++++++++++o 1 1
## 8 242 ----------------------- 20 0
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 31 1
## 10 2089 ++++---+--------------o- 1 1
## # … with abbreviated variable name ¹ctn0094_relapse_event
Definition: Weeks to study dropout (4 consecutive weeks of missing UOS)
<-
outcomesRel_df %>%
outcomesRel_df rowwise() %>%
# do NOT recode any missing visits
mutate(
ctn0094_dropout = detect_in_window(
use_pattern = usePatternUDS,
window_width = 4L,
threshold = 4L,
match_is = "o"
)%>%
) unnest(cols = "ctn0094_dropout", names_sep = "_") %>%
select(who, starts_with("ctn0094_dropout")) %>%
left_join(outcomesRel_df, ., by = "who")
%>%
outcomesRel_df filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, starts_with("ctn0094_dropout"))
## # A tibble: 10 × 4
## who usePatternUDS ctn0094_dropout_time ctn0094_drop…¹
## <dbl> <chr> <int> <int>
## 1 1 ooooooooooooooo 1 1
## 2 4 -------------------o-o-o 21 0
## 3 13 ------------o-oooooooooo 15 1
## 4 17 --++*++++++-++++++-+++- 20 0
## 5 163 -o---o---o--o+---------- 21 0
## 6 210 -++++++++-+++----------- 21 0
## 7 233 *+++++++++++o++++++++++o 21 0
## 8 242 ----------------------- 20 0
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 32 0
## 10 2089 ++++---+--------------o- 21 0
## # … with abbreviated variable name ¹ctn0094_dropout_event
Definition: Failure rate: 2 consecutive positive UOS following 4 weeks of treatment; missing is positive
<-
outcomesRel_df %>%
outcomesRel_df rowwise() %>%
mutate(
udsPattern = recode_missing_visits(
use_pattern = usePatternUDS,
)%>%
) mutate(
udsPattern = recode_missing_visits(
use_pattern = udsPattern,
missing_is = "*"
)%>%
) mutate(
johnson1992_hasRel = detect_subpattern(
use_pattern = udsPattern,
subpattern = "++",
# Starting at 4 weeks of treatment
start = 4L
)%>%
) select(who, johnson1992_hasRel) %>%
left_join(outcomesRel_df, ., by = "who")
%>%
outcomesRel_df filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, johnson1992_hasRel)
## # A tibble: 10 × 3
## who usePatternUDS johnson1992_hasRel
## <dbl> <chr> <lgl>
## 1 1 ooooooooooooooo TRUE
## 2 4 -------------------o-o-o FALSE
## 3 13 ------------o-oooooooooo TRUE
## 4 17 --++*++++++-++++++-+++- TRUE
## 5 163 -o---o---o--o+---------- TRUE
## 6 210 -++++++++-+++----------- TRUE
## 7 233 *+++++++++++o++++++++++o TRUE
## 8 242 ----------------------- FALSE
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o TRUE
## 10 2089 ++++---+--------------o- FALSE
Definition: Relapse rate (3 consecutive positive UOS); missing is positive (their papers do not explicitly state what to do with missing UDS, but their previous protocols treated missing as positive).
<-
outcomesRel_df %>%
outcomesRel_df rowwise() %>%
mutate(
udsPattern = recode_missing_visits(
use_pattern = usePatternUDS,
)%>%
) mutate(
udsPattern = recode_missing_visits(
use_pattern = udsPattern,
missing_is = "*"
)%>%
) mutate(
krupitsky2004_hasRel = detect_subpattern(
use_pattern = udsPattern,
subpattern = "+++"
)%>%
) select(who, krupitsky2004_hasRel) %>%
left_join(outcomesRel_df, ., by = "who")
%>%
outcomesRel_df filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, krupitsky2004_hasRel)
## # A tibble: 10 × 3
## who usePatternUDS krupitsky2004_hasRel
## <dbl> <chr> <lgl>
## 1 1 ooooooooooooooo TRUE
## 2 4 -------------------o-o-o FALSE
## 3 13 ------------o-oooooooooo TRUE
## 4 17 --++*++++++-++++++-+++- TRUE
## 5 163 -o---o---o--o+---------- FALSE
## 6 210 -++++++++-+++----------- TRUE
## 7 233 *+++++++++++o++++++++++o TRUE
## 8 242 ----------------------- FALSE
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o TRUE
## 10 2089 ++++---+--------------o- TRUE
Definition: Weeks to relapse (≥10 days of opioid use in a 28‐day period [a positive UOS was computed as 5 days of opioid use]); missing is positive
We interpret their outcome as “two or more positive weekly UDS in a 4-week window”.
<-
outcomesRel_df %>%
outcomesRel_df rowwise() %>%
mutate(
udsPattern = recode_missing_visits(
use_pattern = usePatternUDS
)%>%
) mutate(
udsPattern = recode_missing_visits(
use_pattern = udsPattern,
missing_is = "*"
)%>%
) mutate(
lee2016_rel = detect_in_window(
use_pattern = udsPattern,
window_width = 4L,
threshold = 2L
)%>%
) unnest(cols = "lee2016_rel", names_sep = "_") %>%
select(who, starts_with("lee2016_rel")) %>%
left_join(outcomesRel_df, ., by = "who")
%>%
outcomesRel_df filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, starts_with("lee2016_rel"))
## # A tibble: 10 × 4
## who usePatternUDS lee2016_rel_time lee2016_rel_event
## <dbl> <chr> <int> <int>
## 1 1 ooooooooooooooo 3 1
## 2 4 -------------------o-o-o 21 1
## 3 13 ------------o-oooooooooo 14 1
## 4 17 --++*++++++-++++++-+++- 3 1
## 5 163 -o---o---o--o+---------- 12 1
## 6 210 -++++++++-+++----------- 3 1
## 7 233 *+++++++++++o++++++++++o 3 1
## 8 242 ----------------------- 22 0
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 3 1
## 10 2089 ++++---+--------------o- 3 1
Definition: Weeks to relapse (starting at day 21 post-randomization: 4 consecutive weeks with positive UOS); missing is positive
<-
outcomesRel_df %>%
outcomesRel_df rowwise() %>%
mutate(
udsPattern = recode_missing_visits(
use_pattern = usePatternUDS
)%>%
) mutate(
udsPattern = recode_missing_visits(
use_pattern = udsPattern,
missing_is = "*"
)%>%
) mutate(
udsPatternTrimmed = str_sub(udsPattern, start = 3L)
%>%
) rowwise() %>%
mutate(
lee2018_rel = detect_in_window(
use_pattern = udsPatternTrimmed,
window_width = 4L,
threshold = 4L
)%>%
) unnest(cols = "lee2018_rel", names_sep = "_") %>%
mutate(lee2018_rel_time = lee2018_rel_time + 2) %>%
select(who, starts_with("lee2018_rel")) %>%
left_join(outcomesRel_df, ., by = "who")
%>%
outcomesRel_df filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, starts_with("lee2018_rel"))
## # A tibble: 10 × 4
## who usePatternUDS lee2018_rel_time lee2018_rel_event
## <dbl> <chr> <dbl> <int>
## 1 1 ooooooooooooooo 3 1
## 2 4 -------------------o-o-o 21 0
## 3 13 ------------o-oooooooooo 15 1
## 4 17 --++*++++++-++++++-+++- 3 1
## 5 163 -o---o---o--o+---------- 21 0
## 6 210 -++++++++-+++----------- 3 1
## 7 233 *+++++++++++o++++++++++o 3 1
## 8 242 ----------------------- 20 0
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 31 1
## 10 2089 ++++---+--------------o- 21 0
Definition: Days to relapse (3 consecutive positive UOS); missing is positive
<-
outcomesRel_df %>%
outcomesRel_df rowwise() %>%
mutate(
udsPattern = recode_missing_visits(
use_pattern = usePatternUDS
)%>%
) mutate(
udsPattern = recode_missing_visits(
use_pattern = udsPattern,
missing_is = "*"
)%>%
) mutate(
schottenfeld2008_rel = detect_in_window(
use_pattern = udsPattern,
window_width = 3L,
threshold = 3L
)%>%
) unnest(cols = "schottenfeld2008_rel", names_sep = "_") %>%
select(who, starts_with("schottenfeld2008_rel")) %>%
left_join(outcomesRel_df, ., by = "who")
%>%
outcomesRel_df filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, starts_with("schottenfeld2008_rel"))
## # A tibble: 10 × 4
## who usePatternUDS schottenfeld2008_rel_time schotte…¹
## <dbl> <chr> <int> <int>
## 1 1 ooooooooooooooo 1 1
## 2 4 -------------------o-o-o 22 0
## 3 13 ------------o-oooooooooo 15 1
## 4 17 --++*++++++-++++++-+++- 3 1
## 5 163 -o---o---o--o+---------- 22 0
## 6 210 -++++++++-+++----------- 2 1
## 7 233 *+++++++++++o++++++++++o 1 1
## 8 242 ----------------------- 21 0
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 31 1
## 10 2089 ++++---+--------------o- 1 1
## # … with abbreviated variable name ¹schottenfeld2008_rel_event
Here is the information concerning the system configuration, packages, and their versions used in this computation:
sessionInfo()
## R version 4.2.0 (2022-04-22)
## Platform: x86_64-apple-darwin17.0 (64-bit)
## Running under: macOS Big Sur/Monterey 10.16
##
## Matrix products: default
## BLAS: /Library/Frameworks/R.framework/Versions/4.2/Resources/lib/libRblas.0.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/4.2/Resources/lib/libRlapack.dylib
##
## locale:
## [1] C/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
##
## attached base packages:
## [1] stats graphics grDevices utils datasets methods base
##
## other attached packages:
## [1] forcats_0.5.1 stringr_1.4.0 dplyr_1.0.9 purrr_0.3.4
## [5] readr_2.1.2 tidyr_1.2.0 tibble_3.1.8 ggplot2_3.3.6
## [9] tidyverse_1.3.2 kableExtra_1.3.4 readxl_1.4.0 CTNote_0.1.0
##
## loaded via a namespace (and not attached):
## [1] lattice_0.20-45 svglite_2.1.0 lubridate_1.8.0
## [4] assertthat_0.2.1 digest_0.6.29 utf8_1.2.2
## [7] R6_2.5.1 cellranger_1.1.0 backports_1.4.1
## [10] reprex_2.0.1 evaluate_0.16 highr_0.9
## [13] httr_1.4.3 pillar_1.8.0 rlang_1.0.4
## [16] googlesheets4_1.0.0 rstudioapi_0.13 jquerylib_0.1.4
## [19] Matrix_1.4-1 rmarkdown_2.14 splines_4.2.0
## [22] webshot_0.5.3 googledrive_2.0.0 munsell_0.5.0
## [25] broom_1.0.0 compiler_4.2.0 modelr_0.1.8
## [28] xfun_0.32 pkgconfig_2.0.3 systemfonts_1.0.4
## [31] htmltools_0.5.3 tidyselect_1.1.2 fansi_1.0.3
## [34] viridisLite_0.4.0 crayon_1.5.1 withr_2.5.0
## [37] tzdb_0.3.0 dbplyr_2.2.1 grid_4.2.0
## [40] jsonlite_1.8.0 gtable_0.3.0 lifecycle_1.0.1
## [43] DBI_1.1.3 magrittr_2.0.3 scales_1.2.0
## [46] cli_3.3.0 stringi_1.7.8 cachem_1.0.6
## [49] fs_1.5.2 xml2_1.3.3 bslib_0.4.0
## [52] ellipsis_0.3.2 generics_0.1.3 vctrs_0.4.1
## [55] tools_4.2.0 glue_1.6.2 hms_1.1.1
## [58] survival_3.3-1 fastmap_1.1.0 yaml_2.3.5
## [61] colorspace_2.0-3 gargle_1.2.0 rvest_1.0.2
## [64] knitr_1.39 haven_2.5.0 sass_0.4.2