Skip to contents

Introduction

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:

  • +: positive for the substance(s) in a specified window of time (a day, week, month, etc.) by urine screen (or participant self report, if such data are of interest)
  • : negative for the substance(s)
  • o: subject failed to provide a urine sample
  • *: inconclusive results or mixed results (e.g. subject provided more than one urine sample in the time interval and they did not agree)
  • _: no specimens required (weekends, holidays, pre-randomization period, alternating visit days/weeks)
###  Full Data  ###
udsOutcomes_df <- 
    CTNote::outcomesCTN0094 %>% 
  select(who, usePatternUDS)

# Make a copy
outcomesRel_df <- udsOutcomes_df


###  Examples  ###
examplePeople_int <- c(1, 163, 210, 242, 4, 17, 13, 1103, 233, 2089)
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-).


“Relapse to Substance Use” Endpoints

CTN-0094 Endpoints

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).

CTN-0094 Relapse

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")) %>% 
  rename(
    RsT_ctnNinetyFour_2023 = ctn0094_relapse_time,
    RsE_ctnNinetyFour_2023 = ctn0094_relapse_event
  ) %>% 
    left_join(outcomesRel_df, ., by = "who")

outcomesRel_df %>% 
  filter(who %in% examplePeople_int) %>% 
  select(who, usePatternUDS, RsT_ctnNinetyFour_2023, RsE_ctnNinetyFour_2023)
## # A tibble: 10 × 4
##      who usePatternUDS             RsT_ctnNinetyFour_2023 RsE_ctnNinetyFour_2023
##    <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--------…                     31                      1
## 10  2089 ++++---+--------------o-                       1                      1

CTN-0094 Dropout

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")) %>% 
  rename(
    DrT_ctnNinetyFour_2023 = ctn0094_dropout_time,
    DrE_ctnNinetyFour_2023 = ctn0094_dropout_event
  ) %>% 
    left_join(outcomesRel_df, ., by = "who")

outcomesRel_df %>% 
  filter(who %in% examplePeople_int) %>% 
  select(who, usePatternUDS, DrT_ctnNinetyFour_2023, DrE_ctnNinetyFour_2023)
## # A tibble: 10 × 4
##      who usePatternUDS             DrT_ctnNinetyFour_2023 DrE_ctnNinetyFour_2023
##    <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--------…                     32                      0
## 10  2089 ++++---+--------------o-                      21                      0

Johnson, Jaffe, and Fudala (1992)

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(
        Rs_johnson_1992 = detect_subpattern(
            use_pattern = udsPattern,
            subpattern = "++",
            # Starting at 4 weeks of treatment
            start = 4L
        )
    ) %>% 
    select(who, Rs_johnson_1992) %>% 
    left_join(outcomesRel_df, ., by = "who")

outcomesRel_df %>% 
  filter(who %in% examplePeople_int) %>% 
  select(who, usePatternUDS, Rs_johnson_1992)
## # A tibble: 10 × 3
##      who usePatternUDS                       Rs_johnson_1992
##    <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

Evgeny M. Krupitsky et al. (2004) and Evgeny M. Krupitsky et al. (2006)

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(
        Rs_krupitsky_2004 = detect_subpattern(
            use_pattern = udsPattern,
            subpattern = "+++"
        )
    ) %>% 
    select(who, Rs_krupitsky_2004) %>% 
    left_join(outcomesRel_df, ., by = "who")

outcomesRel_df %>% 
  filter(who %in% examplePeople_int) %>% 
  select(who, usePatternUDS, Rs_krupitsky_2004)
## # A tibble: 10 × 3
##      who usePatternUDS                       Rs_krupitsky_2004
##    <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

Joshua D. Lee et al. (2016)

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")) %>% 
  rename(
    RsT_lee_2016 = lee2016_rel_time,
    RsE_lee_2016 = lee2016_rel_event
  ) %>% 
    left_join(outcomesRel_df, ., by = "who")

outcomesRel_df %>% 
  filter(who %in% examplePeople_int) %>% 
  select(who, usePatternUDS, contains("lee_2016"))
## # A tibble: 10 × 4
##      who usePatternUDS                       RsT_lee_2016 RsE_lee_2016
##    <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

Joshua D. Lee et al. (2018, CTN–0051)

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")) %>% 
  rename(
    RsT_ctnFiftyOne_2018 = lee2018_rel_time,
    RsE_ctnFiftyOne_2018 = lee2018_rel_event
  ) %>% 
    left_join(outcomesRel_df, ., by = "who")

outcomesRel_df %>% 
  filter(who %in% examplePeople_int) %>% 
  select(who, usePatternUDS, contains("ctnFiftyOne_2018"))
## # A tibble: 10 × 4
##      who usePatternUDS                 RsT_ctnFiftyOne_2018 RsE_ctnFiftyOne_2018
##    <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-…                   31                    1
## 10  2089 ++++---+--------------o-                        21                    0

Schottenfeld, Chawarski, and Mazlan (2008)

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")) %>% 
  rename(
    RsT_schottenfeld_2008 = schottenfeld2008_rel_time,
    RsE_schottenfeld_2008 = schottenfeld2008_rel_event
  ) %>% 
    left_join(outcomesRel_df, ., by = "who")

outcomesRel_df %>% 
  filter(who %in% examplePeople_int) %>% 
  select(who, usePatternUDS, contains("schottenfeld_2008"))
## # A tibble: 10 × 4
##      who usePatternUDS               RsT_schottenfeld_2008 RsE_schottenfeld_2008
##    <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----------…                    31                     1
## 10  2089 ++++---+--------------o-                        1                     1

Computing Environment

Here is the information concerning the system configuration, packages, and their versions used in this computation:

## R version 4.3.2 (2023-10-31)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 22.04.3 LTS
## 
## Matrix products: default
## BLAS:   /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3 
## LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.20.so;  LAPACK version 3.10.0
## 
## locale:
##  [1] LC_CTYPE=C.UTF-8       LC_NUMERIC=C           LC_TIME=C.UTF-8       
##  [4] LC_COLLATE=C.UTF-8     LC_MONETARY=C.UTF-8    LC_MESSAGES=C.UTF-8   
##  [7] LC_PAPER=C.UTF-8       LC_NAME=C              LC_ADDRESS=C          
## [10] LC_TELEPHONE=C         LC_MEASUREMENT=C.UTF-8 LC_IDENTIFICATION=C   
## 
## time zone: UTC
## tzcode source: system (glibc)
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
##  [1] lubridate_1.9.3  forcats_1.0.0    stringr_1.5.1    dplyr_1.1.4     
##  [5] purrr_1.0.2      readr_2.1.4      tidyr_1.3.0      tibble_3.2.1    
##  [9] ggplot2_3.4.4    tidyverse_2.0.0  kableExtra_1.3.4 readxl_1.4.3    
## [13] CTNote_0.1.3    
## 
## loaded via a namespace (and not attached):
##  [1] generics_0.1.3    sass_0.4.8        utf8_1.2.4        xml2_1.3.6       
##  [5] stringi_1.8.3     hms_1.1.3         digest_0.6.33     magrittr_2.0.3   
##  [9] timechange_0.2.0  evaluate_0.23     grid_4.3.2        fastmap_1.1.1    
## [13] cellranger_1.1.0  jsonlite_1.8.8    httr_1.4.7        rvest_1.0.3      
## [17] fansi_1.0.6       viridisLite_0.4.2 scales_1.3.0      textshaping_0.3.7
## [21] jquerylib_0.1.4   cli_3.6.2         rlang_1.1.2       munsell_0.5.0    
## [25] withr_2.5.2       cachem_1.0.8      yaml_2.3.8        tools_4.3.2      
## [29] tzdb_0.4.0        memoise_2.0.1     colorspace_2.1-0  webshot_0.5.5    
## [33] vctrs_0.6.5       R6_2.5.1          lifecycle_1.0.4   fs_1.6.3         
## [37] ragg_1.2.7        pkgconfig_2.0.3   desc_1.4.3        pkgdown_2.0.7    
## [41] bslib_0.6.1       pillar_1.9.0      gtable_0.3.4      glue_1.6.2       
## [45] systemfonts_1.0.5 highr_0.10        tidyselect_1.2.0  xfun_0.41        
## [49] rstudioapi_0.15.0 knitr_1.45        htmltools_0.5.7   rmarkdown_2.25   
## [53] svglite_2.1.3     compiler_4.3.2

References

Johnson, Rolley E., Jerome H. Jaffe, and Paul J. Fudala. 1992. “A Controlled Trial of Buprenorphine Treatment for Opioid Dependence.” Journal of the American Medical Association 267 (20): 2750–55. https://doi.org/10.1001/jama.1992.03480200058024.
Krupitsky, Evgeny M., Edwin E. Zvartau, Dimitry V. Masalov, Marina V. Tsoy, Andrey M. Burakov, Valentina Y. Egorova, Tatyana Y. Didenko, et al. 2006. “Naltrexone with or Without Fluoxetine for Preventing Relapse to Heroin Addiction in St. Petersburg, Russia.” Journal of Substance Abuse Treatment 31 (4): 319–28. https://doi.org/10.1016/j.jsat.2006.05.005.
Krupitsky, Evgeny M, Edwin E Zvartau, Dimitry V Masalov, Marina V Tsoi, Andrey M Burakov, Valentina Y Egorova, Tatyana Y Didenko, et al. 2004. “Naltrexone for Heroin Dependence Treatment in St. Petersburg, Russia.” Journal of Substance Abuse Treatment 26 (4): 285–94. https://doi.org/10.1016/j.jsat.2004.02.002.
Lee, Joshua D., Peter D. Friedmann, Timothy W. Kinlock, Edward V. Nunes, Tamara Y. Boney, Randall A. Hoskinson, Donna Wilson, et al. 2016. “Extended-Release Naltrexone to Prevent Opioid Relapse in Criminal Justice Offenders.” New England Journal of Medicine 374 (13): 1232–42. https://doi.org/10.1056/NEJMoa1505409.
Lee, Joshua D, Edward V Nunes, Patricia Novo, Ken Bachrach, Genie L Bailey, Snehal Bhatt, Sarah Farkas, et al. 2018. “Comparative Effectiveness of Extended-Release Naltrexone Versus Buprenorphine-Naloxone for Opioid Relapse Prevention (X:BOT): A Multicentre, Open-Label, Randomised Controlled Trial.” The Lancet 391 (10118): 309–18. https://doi.org/10.1016/S0140-6736(17)32812-X.
Schottenfeld, Richard S, Marek C Chawarski, and Mahmud Mazlan. 2008. “Maintenance Treatment with Buprenorphine and Naltrexone for Heroin Dependence in Malaysia: A Randomised, Double-Blind, Placebo-Controlled Trial.” The Lancet 371 (9631): 2192–2200. https://doi.org/10.1016/S0140-6736(08)60954-X.