This document contains the algorithms necessary to code all the outcomes which measure “substance use reduction”. We only include outcomes which result in a single value per subject. These outcomes are:
Group | Endpoint | Class | Reference | Definition | Missing is |
---|---|---|---|---|---|
Reduction | Rate of negative UOS | ratio | Comer et al., 2006 | Percentage of negative UOS during 8 weeks of treatment | Positive |
Reduction | Opioid use rate | ratio | Eissenberg et al., 1997 | subject retained in study at least 17 weeks AND subject showed 4 consecutive negative UDS between weeks 1-17 | Imputed |
Reduction | Rate of negative UOS | ratio | Fiellin et al., 2006 | Percentage of negative UOS | Positive |
Reduction | Rate of negative UOS | ratio | Fudala et al., 2003 | Percentage of negative UOS | Missing |
Reduction | Rate of negative UOS | ratio | Haight et al., 2019 | Percentage of negative UOS from week 5 to week 24 | Positive |
Reduction | Rate of negative UOS | ratio | Jaffe et al., 1972 | Percentage of treatment weeks characterized by negative UOS for patients who completed ≥8 weeks of the study | Imputed |
Reduction | Rate of negative UOS | ratio | Johnson et al., 1992 | Average percentage of negative UOS | Positive |
Reduction | Rate of negative UOS | logical | Kosten et al., 1993 | ≥70% negative UOS during the 24-week trial period | Missing/not imputed |
Reduction | Rate of negative UOS | ratio | Ling et al., 1998 | Mean percentage negative UOS | Missing/not imputed |
Reduction | Rate of negative UOS | integer | Ling et al., 1998 | no. of negative UOS (“treatment effectiveness score”) | Missing/not imputed |
Reduction | Rate of negative UOS | ratio | Ling et al., 2010 | Percentage of negative UOS during weeks 1-16 of the trial | Positive |
Reduction | Opioid use rate | ratio | Ling, Charuvastra, Kaim, & Klett, 1976 | Index of illicit morphine use ([0, 120]). Note: this is a complex definition; for details see the original paper. | Positive |
Reduction | Rate of negative UOS | ratio | Lofwall et al., 2018 | Mean percentage of negative UOS for weeks 1 to 24 | Positive |
Reduction | Rate of negative UOS | ratio | Mattick et al., 2003 | “Percentage of clean urines (PCU)”: Rate of negative UOS for the time that the patient remained in the study | Missing/not imputed |
Reduction | Rate of negative UOS | ratio | Mattick et al., 2003 | “treatment effectiveness percentage (TEP)”: Rate of negative UOS for the full 13‐week study (ITT) | Missing/not imputed |
Reduction | Rate of negative UOS | ratio | Pani, Maremmani, Pirastu, Tagliamonte, & Gessa, 2000 | PCC: Percentage ratio of negative UOS and the total number of UOS carried out for each patient during the period of treatment | Missing/not imputed |
Reduction | Rate of negative UOS | ratio | Pani, Maremmani, Pirastu, Tagliamonte, & Gessa, 2000 | TEC: Percentage ratio between the number of negative UOS and the number of UOS as per protocol | Positive |
Reduction | Opioid use rate | ratio | Petitjean et al., 2001 | Weekly proportion of positive UOS (intent-to-treat and completer analysis) | Positive |
Reduction | Rate of negative UOS | ratio | Preston, Umbricht, & Epstein, 2000 | “Mean intervention percent negative”: Percentage of negative UOS in the treatment phase | Positive |
Reduction | Rate of negative UOS | ratio | Schottenfeld et al., 2005 | Proportion of negative UOS | Missing |
Reduction | Opioid use rate | integer | Schwartz et al., 2006 | Number of positive UOS at 120-day follow-up | Missing/not imputed |
Reduction | Opioid use rate | ratio | Shufman et al., 1994 | Percentage of positive UOS | Missing |
Reduction | Opioid use rate | ratio | Soyka, Zingg, Koller, & Kuefner, 2008 | Monthly rates of positive UOS | Missing/not imputed |
Reduction | Opioid use rate | ratio | Strain, Bigelow, Liebson, & Stitzer, 1999 | Percentage of positive UOS | Missing/not imputed |
Reduction | Opioid use rate | ratio | Strain, Stitzer, Liebson, & Bigelow, 1993 | Rate of positive UOS through the end of the stable dosing period | Not defined |
Reduction | Opioid use rate | ratio | Strain, Stitzer, Liebson, & Bigelow, 1994 | Overall rate of positive UOS | Missing/not imputed |
Reduction | Opioid use rate | ratio | Strain, Stitzer, Liebson, & Bigelow, 1996 | Percentage of positive UOS – Overall AND summarized in consecutive 2-week blocks | Missing/not imputed |
Reduction | Rate of negative UOS | logical | Strang et al., 2010 | ≥50% negative UOS during weeks 14-26 | Positive |
Reduction | Rate of negative UOS | ratio | Strang et al., 2019 | Proportion of negative UOS at the end of the 12‐week post-randomization time point | Positive |
Reduction | Rate of negative UOS | NA | Tanum et al., 2017 | Rate of negative UOS: Number of negative UOS divided by the total number of attended tests (group proportion) | Positive |
Reduction | Rate of negative UOS | ratio | Wolstein et al., 2009 | Number of negative UOS per number of weeks of study participation | Unknown |
Reduction | Opioid use rate | ratio | Woody et al., 2008 | Percentage of positive UOS at weeks 4, 8, and 12 | Imputed |
Reduction | Opioid use rate | integer | Zaks, Fink, & Freedman, 1972 | Number of positive UOS | Not defined |
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 <-
CTNote::outcomesCTN0094 %>%
select(who, usePatternUDS)
# Make a copy
outcomesRed_df <- udsOutcomes_df
### Examples ###
examplePeople_int <- c(1, 163, 210, 242, 4, 17, 13, 1103, 233, 2089)
outcomesRed_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-
).
Definition: Percentage of negative UOS during 8 weeks of treatment
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
mutate(
Rd_comer_2006 = count_matches(
use_pattern = usePatternUDS,
match_is = "-",
# Mixed results weeks count as half of a negative week
mixed_results_are = "*", mixed_weight = 0.5,
# first 8 weeks of treatment
start = 1, end = 8,
proportion = TRUE
)
) %>%
select(who, Rd_comer_2006) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_comer_2006)
## # A tibble: 10 × 3
## who usePatternUDS Rd_comer_2006
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 1
## 3 13 ------------o-oooooooooo 1
## 4 17 --++*++++++-++++++-+++- 0.312
## 5 163 -o---o---o--o+---------- 0.75
## 6 210 -++++++++-+++----------- 0.125
## 7 233 *+++++++++++o++++++++++o 0.0625
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.5
## 10 2089 ++++---+--------------o- 0.375
Definition: Percentage of negative UOS
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
mutate(
Rd_fiellin_2006 = count_matches(
use_pattern = usePatternUDS,
match_is = "-",
# Mixed results weeks count as half of a negative week
mixed_results_are = "*", mixed_weight = 0.5,
proportion = TRUE
)
) %>%
select(who, Rd_fiellin_2006) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_fiellin_2006)
## # A tibble: 10 × 3
## who usePatternUDS Rd_fiellin_2006
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 0.875
## 3 13 ------------o-oooooooooo 0.542
## 4 17 --++*++++++-++++++-+++- 0.239
## 5 163 -o---o---o--o+---------- 0.792
## 6 210 -++++++++-+++----------- 0.542
## 7 233 *+++++++++++o++++++++++o 0.0208
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.571
## 10 2089 ++++---+--------------o- 0.75
Definition: Percentage of negative UOS; they exclude missing values.
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
# Drop weeks with missing UDS
mutate(
usePatternPresent = recode_missing_visits(
usePatternUDS,
missing_becomes = ""
)
) %>%
mutate(
Rd_fudala_2003 = count_matches(
use_pattern = usePatternPresent,
match_is = "-",
# Mixed results weeks count as half of a negative week
mixed_results_are = "*", mixed_weight = 0.5,
proportion = TRUE
)
) %>%
select(who, Rd_fudala_2003) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_fudala_2003)
## # A tibble: 10 × 3
## who usePatternUDS Rd_fudala_2003
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 1
## 3 13 ------------o-oooooooooo 1
## 4 17 --++*++++++-++++++-+++- 0.239
## 5 163 -o---o---o--o+---------- 0.95
## 6 210 -++++++++-+++----------- 0.542
## 7 233 *+++++++++++o++++++++++o 0.0227
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.769
## 10 2089 ++++---+--------------o- 0.783
Definition: Percentage of negative UOS from week 5 to week 24
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
mutate(
Rd_haight_2019 = count_matches(
use_pattern = usePatternUDS,
match_is = "-",
# Mixed results weeks count as half of a negative week
mixed_results_are = "*", mixed_weight = 0.5,
# The end-of-protocol for our trials is 15-16 weeks
start = 5, end = 15,
proportion = TRUE
)
) %>%
select(who, Rd_haight_2019) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_haight_2019)
## # A tibble: 10 × 3
## who usePatternUDS Rd_haight_2019
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 1
## 3 13 ------------o-oooooooooo 0.818
## 4 17 --++*++++++-++++++-+++- 0.136
## 5 163 -o---o---o--o+---------- 0.636
## 6 210 -++++++++-+++----------- 0.273
## 7 233 *+++++++++++o++++++++++o 0
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.545
## 10 2089 ++++---+--------------o- 0.909
Definition: Percentage of treatment weeks characterized by negative UOS for patients who completed ≥8 weeks of the study; and missing values were imputed to the mode for each participant.
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
# Mark if participants completed 8 weeks of treatment; remove those who do not
# (but we will add them back in at the end)
mutate(lastWeek_idx = measure_retention(use_pattern = usePatternUDS)) %>%
filter(lastWeek_idx >= 8) %>%
# For participants who stayed in the trials at least 8 weeks, impute their
# missing weeks to their personal most common UDS result; in the event of a
# tie between a negative and a positive result for the mode, the tiebreaker
# is a positive result.
mutate(
usePatternImputed = impute_missing_visits(
use_pattern = usePatternUDS,
method = "mode"
)
) %>%
mutate(
Rd_jaffe_1972 = count_matches(
usePatternImputed,
match_is = "-",
mixed_results_are = "*",
mixed_weight = 0.5,
proportion = TRUE
)
) %>%
select(who, Rd_jaffe_1972) %>%
left_join(outcomesRed_df, ., by = "who") %>%
# Lots of NAs from the participants who did not make it to week 8; replace
# these NAs with 0
replace_na(list(Rd_jaffe_1972 = 0))
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_jaffe_1972)
## # A tibble: 10 × 3
## who usePatternUDS Rd_jaffe_1972
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 1
## 3 13 ------------o-oooooooooo 1
## 4 17 --++*++++++-++++++-+++- 0.239
## 5 163 -o---o---o--o+---------- 0.958
## 6 210 -++++++++-+++----------- 0.542
## 7 233 *+++++++++++o++++++++++o 0.0208
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.829
## 10 2089 ++++---+--------------o- 0.792
Definitions: Average percentage of negative UOS
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
mutate(
Rd_johnson_1992 = count_matches(
use_pattern = usePatternUDS,
match_is = "-",
# Mixed results weeks count as half of a negative week
mixed_results_are = "*", mixed_weight = 0.5,
proportion = TRUE
)
) %>%
select(who, Rd_johnson_1992) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_johnson_1992)
## # A tibble: 10 × 3
## who usePatternUDS Rd_johnson_1992
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 0.875
## 3 13 ------------o-oooooooooo 0.542
## 4 17 --++*++++++-++++++-+++- 0.239
## 5 163 -o---o---o--o+---------- 0.792
## 6 210 -++++++++-+++----------- 0.542
## 7 233 *+++++++++++o++++++++++o 0.0208
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.571
## 10 2089 ++++---+--------------o- 0.75
Definition: ≥70% negative UOS during the 24-week trial period; missing UDS are excluded
Note: there are multiple definitions of treatment failure in this paper; we provide an algorithm for the definition which results in a single value for each participant.
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
# Exclude missing visits
mutate(
usePatternPresent = recode_missing_visits(
usePatternUDS,
missing_becomes = ""
)
) %>%
mutate(
kosten1993B_prop = count_matches(
use_pattern = usePatternPresent,
match_is = "-",
# Mixed results weeks count as half of a negative week
mixed_results_are = "*", mixed_weight = 0.5,
start = 1,
end = 15,
proportion = TRUE
)
) %>%
mutate(Rd_kostenB_1993 = kosten1993B_prop >= 0.7) %>%
select(who, Rd_kostenB_1993) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_kostenB_1993)
## # A tibble: 10 × 3
## who usePatternUDS Rd_kostenB_1993
## <dbl> <chr> <lgl>
## 1 1 ooooooooooooooo FALSE
## 2 4 -------------------o-o-o TRUE
## 3 13 ------------o-oooooooooo TRUE
## 4 17 --++*++++++-++++++-+++- FALSE
## 5 163 -o---o---o--o+---------- TRUE
## 6 210 -++++++++-+++----------- FALSE
## 7 233 *+++++++++++o++++++++++o FALSE
## 8 242 ----------------------- TRUE
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o TRUE
## 10 2089 ++++---+--------------o- FALSE
There are two definitions from this paper which we include in the reduction section our library: Mean percentage negative UOS and no. of negative UOS (“treatment effectiveness score”). Both of these outcome definitions exclude missing UDS. We also include an abstinence endpoint from this paper in our “abstinence and relapse endpoints” section.
Definition: Mean percentage negative UOS
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
# Exclude missing UDS
mutate(
usePatternPresent = recode_missing_visits(
usePatternUDS,
missing_becomes = ""
)
) %>%
mutate(
Rd_lingA_1998 = count_matches(
use_pattern = usePatternPresent,
match_is = "-",
# Mixed results weeks count as half of a negative week
mixed_results_are = "*", mixed_weight = 0.5,
start = 1, end = 15,
proportion = TRUE
)
) %>%
select(who, Rd_lingA_1998) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_lingA_1998)
## # A tibble: 10 × 3
## who usePatternUDS Rd_lingA_1998
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 1
## 3 13 ------------o-oooooooooo 1
## 4 17 --++*++++++-++++++-+++- 0.233
## 5 163 -o---o---o--o+---------- 0.933
## 6 210 -++++++++-+++----------- 0.267
## 7 233 *+++++++++++o++++++++++o 0.0333
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.733
## 10 2089 ++++---+--------------o- 0.667
Definition: no. of negative UOS (“treatment effectiveness score”)
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
mutate(
Rd_lingC_1998 = count_matches(
use_pattern = usePatternUDS,
match_is = "-",
end = 15,
mixed_results_are = "*",
mixed_weight = 0.5
)
) %>%
select(who, Rd_lingC_1998) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_lingC_1998)
## # A tibble: 10 × 3
## who usePatternUDS Rd_lingC_1998
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 15
## 3 13 ------------o-oooooooooo 13
## 4 17 --++*++++++-++++++-+++- 3.5
## 5 163 -o---o---o--o+---------- 10
## 6 210 -++++++++-+++----------- 4
## 7 233 *+++++++++++o++++++++++o 0.5
## 8 242 ----------------------- 15
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 8
## 10 2089 ++++---+--------------o- 10
Definition: Percentage of negative UOS during weeks 1-16 of the trial
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
mutate(
Rd_ling_2010 = count_matches(
use_pattern = usePatternUDS,
match_is = "-",
# Mixed results weeks count as half of a negative week
mixed_results_are = "*", mixed_weight = 0.5,
# We only have 15 weeks of data from some arms
start = 1, end = 15,
proportion = TRUE
)
) %>%
select(who, Rd_ling_2010) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_ling_2010)
## # A tibble: 10 × 3
## who usePatternUDS Rd_ling_2010
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 1
## 3 13 ------------o-oooooooooo 0.867
## 4 17 --++*++++++-++++++-+++- 0.233
## 5 163 -o---o---o--o+---------- 0.667
## 6 210 -++++++++-+++----------- 0.267
## 7 233 *+++++++++++o++++++++++o 0.0333
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.533
## 10 2089 ++++---+--------------o- 0.667
Definition: Index of illicit morphine use ([0, 120]). Note: this is a complex definition; for details see the original paper.
The definition in this paper is quite complex, but very well thought out. It is one of our favorite MOUD treatment endpoints because of its flexibility.
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
# Rule 1: mark induction failures
# The Ling et al. protocol lasted 40 weeks while requiring 7 weeks of data for
# the subjects to be counted as "estimable participants"; our 3 studies each
# lasted at least 15 weeks. Therefore, we should require at least
# (7/40) * 15) ~= 3 weeks of data to consider a participant "estimable"
mutate(
inductFail = measure_retention(usePatternUDS) <= 3
) %>%
mutate(
usePatternTrunc = str_sub(usePatternUDS, end = 15)
) %>%
# Rules 2-4: weighting and scaling visits. The flexibility here is amazing.
# If we think that dropout is worse than positive, then we can reflect that
# in the weights. Ling et al. counted a missing visit as 0.22 of a positive;
# and they use a step function to increase the penalty of a positive UDS
# over time.
mutate(
ling1976o22_use = weight_positive_visits(
use_pattern = usePatternTrunc,
weights_num = c(`+` = 1.0, `*` = 0.5, `o` = 0.22, `-` = 0),
posPenalty_num = rep(1:5, each = 3) # step function for 15 weeks
)
) %>%
mutate(
ling1976o22_use = case_when(
inductFail ~ 120,
!inductFail ~ ling1976o22_use
),
Rd_lingA_1976 = 120 - ling1976o22_use
) %>%
select(who, Rd_lingA_1976) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_lingA_1976)
## # A tibble: 10 × 3
## who usePatternUDS Rd_lingA_1976
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 120
## 3 13 ------------o-oooooooooo 119.
## 4 17 --++*++++++-++++++-+++- 18.7
## 5 163 -o---o---o--o+---------- 104.
## 6 210 -++++++++-+++----------- 40
## 7 233 *+++++++++++o++++++++++o 14.1
## 8 242 ----------------------- 120
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 88.9
## 10 2089 ++++---+--------------o- 98.7
We also include a variant of this definition which includes a greater penalty for missing values and a smooth function to increase weights of positive UDS.
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
mutate(
inductFail = measure_retention(usePatternUDS) <= 3
) %>%
mutate(
usePatternTrunc = str_sub(usePatternUDS, end = 15)
) %>%
mutate(
ling1976o100_use = weight_positive_visits(
use_pattern = usePatternTrunc,
# Higher weight for missing values
weights_num = c(`+` = 0.8, `*` = 0.4, `o` = 1.0, `-` = 0),
# Smooth penalty function for increasing positive UDS
posPenalty_num = seq(
from = 1, to = 5, length.out = str_length(usePatternTrunc)
)
)
) %>%
mutate(
ling1976o100_use = case_when(
inductFail ~ 120,
!inductFail ~ ling1976o100_use
),
Rd_lingB_1976 = 120 - ling1976o100_use
) %>%
select(who, Rd_lingB_1976) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_lingB_1976)
## # A tibble: 10 × 3
## who usePatternUDS Rd_lingB_1976
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 120
## 3 13 ------------o-oooooooooo 113.
## 4 17 --++*++++++-++++++-+++- 20.6
## 5 163 -o---o---o--o+---------- 94.2
## 6 210 -++++++++-+++----------- 38.5
## 7 233 *+++++++++++o++++++++++o 10.4
## 8 242 ----------------------- 120
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 82.0
## 10 2089 ++++---+--------------o- 96.9
Definition: Mean percentage of negative UOS for weeks 1 to 24; but urine screens are collected each week for the first 12 weeks, then every other week for weeks 13-24. We project this onto a 15-16 week protocol by requiring UDS each week for the first 7 weeks, then every other week for the next 8. Then, we impute the skipped weeks to be whatever the value of the UDS was from the last visit.
### Define a Visit Pattern (Lattice) ###
lofwallLattice_char <- collapse_lattice(
lattice_patterns = c("o", "_o"),
# For the lattice as defined over 24 weeks, you need 12 weeks of weekly visits
# and 6 sets of alternating "no visit" and "visit" week pairs, or c(12, 6).
# For us, we want 7 weeks straight of weekly visits followed by 4 pairs of
# alternating visits (8 weeks) for a total of 15 weeks.
times = c(7, 4)
)
lofwallLattice_char
## [1] "ooooooo_o_o_o_o"
### Calculate the Endpoint ###
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
# Mark all missing UDS as positive
mutate(
udsPattern = recode_missing_visits(usePatternUDS)
) %>%
# View the current use pattern "through" the Lofwall protocol
mutate(
udsLattice = view_by_lattice(
use_pattern = udsPattern,
lattice_pattern = str_sub(lofwallLattice_char, end = 15) # first 15 weeks
)
) %>%
# Impute the visits from the "unobserved" weeks to the last observed week
mutate(
udsLatticeLOCF = impute_missing_visits(
use_pattern = udsLattice,
method = "locf",
# This is only imputing values that we wouldn't have seen because of the
# protocol ("_" means missing by design; "o" means missing)
missing_is = "_",
quietly = TRUE
)
) %>%
mutate(
Rd_lofwall_2018 = count_matches(
use_pattern = udsLatticeLOCF,
match_is = "-",
# Mixed results weeks count as half of a negative week
mixed_results_are = "*", mixed_weight = 0.5,
start = 1, end = 15, # first 15 weeks
proportion = TRUE
)
) %>%
select(who, Rd_lofwall_2018) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_lofwall_2018)
## # A tibble: 10 × 3
## who usePatternUDS Rd_lofwall_2018
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 1
## 3 13 ------------o-oooooooooo 0.8
## 4 17 --++*++++++-++++++-+++- 0.167
## 5 163 -o---o---o--o+---------- 0.733
## 6 210 -++++++++-+++----------- 0.133
## 7 233 *+++++++++++o++++++++++o 0.0333
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.333
## 10 2089 ++++---+--------------o- 0.733
There are also two definitions from this paper included in our library.
Definition: “Percentage of clean urines (PCU)”: Rate of negative UOS for the time that the patient remained in the study
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
# Find out how long the participant stayed in the study
mutate(lastWeek_idx = measure_retention(use_pattern = usePatternUDS)) %>%
mutate(
Rd_mattickA_2003 = count_matches(
use_pattern = usePatternUDS,
match_is = "-",
# Mixed results weeks count as half of a negative week
mixed_results_are = "*", mixed_weight = 0.5,
# Measure proportion of negative UDS only during study participation
start = 1, end = lastWeek_idx,
proportion = TRUE
)
) %>%
select(who, Rd_mattickA_2003) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_mattickA_2003)
## # A tibble: 10 × 3
## who usePatternUDS Rd_mattickA_2003
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 0.913
## 3 13 ------------o-oooooooooo 0.929
## 4 17 --++*++++++-++++++-+++- 0.239
## 5 163 -o---o---o--o+---------- 0.792
## 6 210 -++++++++-+++----------- 0.542
## 7 233 *+++++++++++o++++++++++o 0.0217
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.588
## 10 2089 ++++---+--------------o- 0.75
Definition: “treatment effectiveness percentage (TEP)”: Rate of negative UOS for the full 13‐week study (ITT)
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
mutate(
Rd_mattickB_2003 = count_matches(
use_pattern = usePatternUDS,
match_is = "-",
# Mixed results weeks count as half of a negative week
mixed_results_are = "*", mixed_weight = 0.5,
# They used a 13-week protocol
start = 1, end = 13,
proportion = TRUE
)
) %>%
select(who, Rd_mattickB_2003) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_mattickB_2003)
## # A tibble: 10 × 3
## who usePatternUDS Rd_mattickB_2003
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 1
## 3 13 ------------o-oooooooooo 0.923
## 4 17 --++*++++++-++++++-+++- 0.269
## 5 163 -o---o---o--o+---------- 0.692
## 6 210 -++++++++-+++----------- 0.154
## 7 233 *+++++++++++o++++++++++o 0.0385
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.462
## 10 2089 ++++---+--------------o- 0.615
There are also two definitions from this paper included in our library.
Definition: PCC: Percentage ratio of negative UOS and the total number of UOS carried out for each patient during the period of treatment
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
# Remove weeks where participant failed to provide UDS
mutate(
usePatternPresent = recode_missing_visits(
usePatternUDS,
missing_becomes = ""
)
) %>%
mutate(
Rd_paniA_2000 = count_matches(
use_pattern = usePatternPresent,
match_is = "-",
# Mixed results weeks count as half of a negative week
mixed_results_are = "*", mixed_weight = 0.5,
proportion = TRUE
)
) %>%
select(who, Rd_paniA_2000) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_paniA_2000)
## # A tibble: 10 × 3
## who usePatternUDS Rd_paniA_2000
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 1
## 3 13 ------------o-oooooooooo 1
## 4 17 --++*++++++-++++++-+++- 0.239
## 5 163 -o---o---o--o+---------- 0.95
## 6 210 -++++++++-+++----------- 0.542
## 7 233 *+++++++++++o++++++++++o 0.0227
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.769
## 10 2089 ++++---+--------------o- 0.783
Definition: TEC: Percentage ratio between the number of negative UOS and the number of UOS as per protocol
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
mutate(
Rd_paniB_2000 = count_matches(
use_pattern = usePatternUDS,
match_is = "-",
# Mixed results weeks count as half of a negative week
mixed_results_are = "*", mixed_weight = 0.5,
proportion = TRUE
)
) %>%
select(who, Rd_paniB_2000) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_paniB_2000)
## # A tibble: 10 × 3
## who usePatternUDS Rd_paniB_2000
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 0.875
## 3 13 ------------o-oooooooooo 0.542
## 4 17 --++*++++++-++++++-+++- 0.239
## 5 163 -o---o---o--o+---------- 0.792
## 6 210 -++++++++-+++----------- 0.542
## 7 233 *+++++++++++o++++++++++o 0.0208
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.571
## 10 2089 ++++---+--------------o- 0.75
Definition: Weekly proportion of positive UOS (intent-to-treat and completer analysis)
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
mutate(
udsPattern = recode_missing_visits(usePatternUDS)
) %>%
mutate(
petitjean2001_use = count_matches(
use_pattern = udsPattern,
match_is = "+",
mixed_results_are = "*",
proportion = TRUE
)
) %>%
mutate(
Rd_petitjean_2001 = 1 - petitjean2001_use
) %>%
select(who, Rd_petitjean_2001) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_petitjean_2001)
## # A tibble: 10 × 3
## who usePatternUDS Rd_petitjean_2001
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 0.875
## 3 13 ------------o-oooooooooo 0.542
## 4 17 --++*++++++-++++++-+++- 0.239
## 5 163 -o---o---o--o+---------- 0.792
## 6 210 -++++++++-+++----------- 0.542
## 7 233 *+++++++++++o++++++++++o 0.0208
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.571
## 10 2089 ++++---+--------------o- 0.75
Definition: “Mean intervention percent negative”: Percentage of negative UOS in the treatment phase
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
mutate(
Rd_preston_2000 = count_matches(
use_pattern = usePatternUDS,
match_is = "-",
# Mixed results weeks count as half of a negative week
mixed_results_are = "*", mixed_weight = 0.5,
# 13-week protocol used
end = 13,
proportion = TRUE
)
) %>%
select(who, Rd_preston_2000) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_preston_2000)
## # A tibble: 10 × 3
## who usePatternUDS Rd_preston_2000
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 1
## 3 13 ------------o-oooooooooo 0.923
## 4 17 --++*++++++-++++++-+++- 0.269
## 5 163 -o---o---o--o+---------- 0.692
## 6 210 -++++++++-+++----------- 0.154
## 7 233 *+++++++++++o++++++++++o 0.0385
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.462
## 10 2089 ++++---+--------------o- 0.615
Definition: Proportion of negative UOS; exclude missing UDS
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
# Exclude missing
mutate(
usePatternPresent = recode_missing_visits(
usePatternUDS,
missing_becomes = ""
)
) %>%
# Count negative
mutate(
Rd_schottenfeld_2005 = count_matches(
use_pattern = usePatternPresent,
match_is = "-",
# Mixed results weeks count as half of a negative week
mixed_results_are = "*", mixed_weight = 0.5,
proportion = TRUE
)
) %>%
select(who, Rd_schottenfeld_2005) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_schottenfeld_2005)
## # A tibble: 10 × 3
## who usePatternUDS Rd_schottenfeld_2005
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 1
## 3 13 ------------o-oooooooooo 1
## 4 17 --++*++++++-++++++-+++- 0.239
## 5 163 -o---o---o--o+---------- 0.95
## 6 210 -++++++++-+++----------- 0.542
## 7 233 *+++++++++++o++++++++++o 0.0227
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.769
## 10 2089 ++++---+--------------o- 0.783
Definition: Number of positive UOS at 120-day follow-up
This definition is a cohort-level definition, not an individual definition. The individual endpoint would be “was this participant abstinent from the substance of interest at the 120-day follow-up? (17 weeks from randomization). Our participants do not uniformly have 17 weeks of data, so we will assess them at week 15 instead. NOTE: while the authors classified their outcome as a”reduction” metric (and therefore we include it here in the “reduction” section of the outcomes library), we label this outcome with the prefix “Ab” for abstinence.
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
mutate(
schwartz2006_abs = count_matches(
use_pattern = usePatternUDS,
match_is = "-",
start = 15, end = 15,
mixed_results_are = "*"
)
) %>%
ungroup() %>%
mutate(
Ab_schwartz_2006 = schwartz2006_abs == 1
) %>%
select(who, Ab_schwartz_2006) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Ab_schwartz_2006)
## # A tibble: 10 × 3
## who usePatternUDS Ab_schwartz_2006
## <dbl> <chr> <lgl>
## 1 1 ooooooooooooooo FALSE
## 2 4 -------------------o-o-o TRUE
## 3 13 ------------o-oooooooooo FALSE
## 4 17 --++*++++++-++++++-+++- FALSE
## 5 163 -o---o---o--o+---------- TRUE
## 6 210 -++++++++-+++----------- TRUE
## 7 233 *+++++++++++o++++++++++o FALSE
## 8 242 ----------------------- TRUE
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o TRUE
## 10 2089 ++++---+--------------o- TRUE
Definition: Percentage of positive UOS; missing is ignored
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
# Count "+" UDS; 0 could be complete dropout or all negative
mutate(
shufman1994_useP = count_matches(
use_pattern = usePatternUDS,
match_is = "+",
mixed_results_are = "*",
proportion = TRUE
)
) %>%
mutate(Rd_shufman_1994 = 1 - shufman1994_useP) %>%
select(who, Rd_shufman_1994) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_shufman_1994)
## # A tibble: 10 × 3
## who usePatternUDS Rd_shufman_1994
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 1
## 2 4 -------------------o-o-o 1
## 3 13 ------------o-oooooooooo 1
## 4 17 --++*++++++-++++++-+++- 0.239
## 5 163 -o---o---o--o+---------- 0.958
## 6 210 -++++++++-+++----------- 0.542
## 7 233 *+++++++++++o++++++++++o 0.104
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.829
## 10 2089 ++++---+--------------o- 0.792
Definition: Monthly rates of positive UOS; missing is ignored
The paper is here.
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
# Ignore missing UDS
mutate(
udsPattern = recode_missing_visits(
use_pattern = usePatternUDS,
missing_becomes = ""
)
) %>%
# Count "+" UDS; 0 could be complete dropout or all negative
mutate(
soyka2008_use = count_matches(
use_pattern = udsPattern,
match_is = "+",
mixed_results_are = "*",
mixed_weight = 0.5,
proportion = TRUE
)
) %>%
mutate(Rd_soyka_2008 = 1 - soyka2008_use) %>%
ungroup() %>%
select(who, Rd_soyka_2008) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_soyka_2008)
## # A tibble: 10 × 3
## who usePatternUDS Rd_soyka_2008
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 1
## 2 4 -------------------o-o-o 1
## 3 13 ------------o-oooooooooo 1
## 4 17 --++*++++++-++++++-+++- 0.239
## 5 163 -o---o---o--o+---------- 0.95
## 6 210 -++++++++-+++----------- 0.542
## 7 233 *+++++++++++o++++++++++o 0.0227
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.769
## 10 2089 ++++---+--------------o- 0.783
Definition: Rate of positive UOS through the end of the stable dosing period; missing is not defined
Paper here
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
# Count "+" UDS; 0 could be complete dropout or all negative
mutate(
strain1993_use = count_matches(
use_pattern = usePatternUDS,
match_is = "+",
# The stable dosing period began in week 6
start = 6, end = 15,
mixed_results_are = "*",
proportion = TRUE
)
) %>%
mutate(Rd_strain_1993 = 1 - strain1993_use) %>%
select(who, Rd_strain_1993) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_strain_1993)
## # A tibble: 10 × 3
## who usePatternUDS Rd_strain_1993
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 1
## 2 4 -------------------o-o-o 1
## 3 13 ------------o-oooooooooo 1
## 4 17 --++*++++++-++++++-+++- 0.1
## 5 163 -o---o---o--o+---------- 0.9
## 6 210 -++++++++-+++----------- 0.3
## 7 233 *+++++++++++o++++++++++o 0.1
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.8
## 10 2089 ++++---+--------------o- 0.9
Definition: Overall rate of positive UOS; missing is ignored
Paper here
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
# Ignore missing
mutate(
udsPattern = recode_missing_visits(
use_pattern = usePatternUDS,
missing_becomes = ""
)
) %>%
# Count "+" UDS; 0 could be complete dropout or all negative
mutate(
strain1994_use = count_matches(
use_pattern = usePatternUDS,
match_is = "+",
mixed_results_are = "*",
proportion = TRUE
)
) %>%
mutate(Rd_strain_1994 = 1 - strain1994_use) %>%
select(who, Rd_strain_1994) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_strain_1994)
## # A tibble: 10 × 3
## who usePatternUDS Rd_strain_1994
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 1
## 2 4 -------------------o-o-o 1
## 3 13 ------------o-oooooooooo 1
## 4 17 --++*++++++-++++++-+++- 0.239
## 5 163 -o---o---o--o+---------- 0.958
## 6 210 -++++++++-+++----------- 0.542
## 7 233 *+++++++++++o++++++++++o 0.104
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.829
## 10 2089 ++++---+--------------o- 0.792
Definition: Percentage of positive UOS – Overall AND summarized in consecutive 2-week blocks; missing is ignored
Because the “two-weeks blocks” definition results in more than one value per participant, we do not provide it in our library. This definition is now identical to that of Strain, Stitzer, Liebson, & Bigelow (1994).
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
# Ignore missing
mutate(
udsPattern = recode_missing_visits(
use_pattern = usePatternUDS,
missing_becomes = ""
)
) %>%
# Count "+" UDS; 0 could be complete dropout or all negative
mutate(
strain1996_use = count_matches(
use_pattern = udsPattern,
match_is = "+",
mixed_results_are = "*",
proportion = TRUE
)
) %>%
mutate(Rd_strain_1996 = 1 - strain1996_use) %>%
select(who, Rd_strain_1996) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_strain_1996)
## # A tibble: 10 × 3
## who usePatternUDS Rd_strain_1996
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 1
## 2 4 -------------------o-o-o 1
## 3 13 ------------o-oooooooooo 1
## 4 17 --++*++++++-++++++-+++- 0.239
## 5 163 -o---o---o--o+---------- 0.95
## 6 210 -++++++++-+++----------- 0.542
## 7 233 *+++++++++++o++++++++++o 0.0227
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.769
## 10 2089 ++++---+--------------o- 0.783
Definition: Percentage of positive UOS
This paper gave no commentary on how the missing values would be processed, only that the statistical software SAS was capable of handling missing values. SAS, by default, excludes missing values from analyses. Therefore, this definition will also be identical to that of Strain, Stitzer, Liebson, & Bigelow (1994).
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
# Ignore missing
mutate(
udsPattern = recode_missing_visits(
use_pattern = usePatternUDS,
missing_becomes = ""
)
) %>%
# Count "+" UDS; 0 could be complete dropout or all negative
mutate(
strain1999_use = count_matches(
use_pattern = usePatternUDS,
match_is = "+",
mixed_results_are = "*",
proportion = TRUE
)
) %>%
mutate(Rd_strain_1999 = 1 - strain1999_use) %>%
select(who, Rd_strain_1999) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_strain_1999)
## # A tibble: 10 × 3
## who usePatternUDS Rd_strain_1999
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 1
## 2 4 -------------------o-o-o 1
## 3 13 ------------o-oooooooooo 1
## 4 17 --++*++++++-++++++-+++- 0.239
## 5 163 -o---o---o--o+---------- 0.958
## 6 210 -++++++++-+++----------- 0.542
## 7 233 *+++++++++++o++++++++++o 0.104
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.829
## 10 2089 ++++---+--------------o- 0.792
Definitions: ≥50% negative UOS during weeks 14-26
Our protocols do not uniformly contain 26 weeks of data, so we apply this definition as “the last 12 weeks of the protocol.”
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
mutate(
cleanProp = count_matches(
use_pattern = usePatternUDS,
match_is = "-",
# Mixed results weeks count as half of a negative week
mixed_results_are = "*", mixed_weight = 0.5,
# Syntax to select the LAST visits uses a negative sign; this means "12
# weeks before the end of the data" to "the last week of the data"
start = -12, end = -1,
proportion = TRUE
)
) %>%
mutate(Rd_strang_2010 = cleanProp >= 0.5) %>%
ungroup() %>%
select(who, Rd_strang_2010) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_strang_2010)
## # A tibble: 10 × 3
## who usePatternUDS Rd_strang_2010
## <dbl> <chr> <lgl>
## 1 1 ooooooooooooooo FALSE
## 2 4 -------------------o-o-o TRUE
## 3 13 ------------o-oooooooooo FALSE
## 4 17 --++*++++++-++++++-+++- FALSE
## 5 163 -o---o---o--o+---------- TRUE
## 6 210 -++++++++-+++----------- TRUE
## 7 233 *+++++++++++o++++++++++o FALSE
## 8 242 ----------------------- TRUE
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o FALSE
## 10 2089 ++++---+--------------o- TRUE
Definition: Proportion of negative UOS at the end of the 12‐week post-randomization time point
Paper here
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
mutate(
Rd_strang_2019 = count_matches(
use_pattern = usePatternUDS,
match_is = "-",
# Mixed results weeks count as half of a negative week
mixed_results_are = "*", mixed_weight = 0.5,
# Only look at the first 12 weeks after randomization
start = 1, end = 12,
proportion = TRUE
)
) %>%
select(who, Rd_strang_2019) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_strang_2019)
## # A tibble: 10 × 3
## who usePatternUDS Rd_strang_2019
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 1
## 3 13 ------------o-oooooooooo 1
## 4 17 --++*++++++-++++++-+++- 0.292
## 5 163 -o---o---o--o+---------- 0.75
## 6 210 -++++++++-+++----------- 0.167
## 7 233 *+++++++++++o++++++++++o 0.0417
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.5
## 10 2089 ++++---+--------------o- 0.583
Definition: Rate of negative UOS: Number of negative UOS divided by the total number of attended tests (group proportion)
Note that this definition as written is a group outcome, not a participant outcome. Therefore, we calculate this for each subject as the “rate of negative UOS for the time that the patient remained in the study.”
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
# How long was each subject retained?
mutate(lastWeek_idx = measure_retention(use_pattern = usePatternUDS)) %>%
mutate(
Rd_tanum_2017 = count_matches(
use_pattern = usePatternUDS,
match_is = "-",
# Mixed results weeks count as half of a negative week
mixed_results_are = "*", mixed_weight = 0.5,
start = 1, end = lastWeek_idx,
proportion = TRUE
)
) %>%
select(who, Rd_tanum_2017) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_tanum_2017)
## # A tibble: 10 × 3
## who usePatternUDS Rd_tanum_2017
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 0.913
## 3 13 ------------o-oooooooooo 0.929
## 4 17 --++*++++++-++++++-+++- 0.239
## 5 163 -o---o---o--o+---------- 0.792
## 6 210 -++++++++-+++----------- 0.542
## 7 233 *+++++++++++o++++++++++o 0.0217
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.588
## 10 2089 ++++---+--------------o- 0.75
Definition: Number of negative UOS per number of weeks of study participation
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
# Because we are measuring outcomes only while "participating", remove missing
# weeks from the use pattern
mutate(
usePatternPresent = recode_missing_visits(
usePatternUDS,
missing_becomes = ""
)
) %>%
mutate(
Rd_wolstein_2009 = count_matches(
use_pattern = usePatternPresent,
match_is = "-",
# Mixed results weeks count as half of a negative week
mixed_results_are = "*", mixed_weight = 0.5,
proportion = TRUE
)
) %>%
select(who, Rd_wolstein_2009) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_wolstein_2009)
## # A tibble: 10 × 3
## who usePatternUDS Rd_wolstein_2009
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 1
## 3 13 ------------o-oooooooooo 1
## 4 17 --++*++++++-++++++-+++- 0.239
## 5 163 -o---o---o--o+---------- 0.95
## 6 210 -++++++++-+++----------- 0.542
## 7 233 *+++++++++++o++++++++++o 0.0227
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 0.769
## 10 2089 ++++---+--------------o- 0.783
Definition: Percentage of positive UOS at weeks 4, 8, and 12
This paper contains rather exotic methods for missing value imputation, but the authors remark that setting “missing is positive” did not change their final results. We may include their imputation method in future versions of this code library.
### Define a Visit Pattern (Lattice) ###
woodyLattice_char <- collapse_lattice(lattice_patterns = "___o", times = 3)
woodyLattice_char
## [1] "___o___o___o"
### Calculate the Endpoint ###
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
# Only observe scheduled UDS
mutate(
udsLattice = view_by_lattice(
use_pattern = usePatternUDS,
lattice_pattern = woodyLattice_char
)
) %>%
# Remove the non-protocol weeks
mutate(
udsLattice2 = recode_missing_visits(
use_pattern = udsLattice,
missing_is = "_",
missing_becomes = ""
)
) %>%
# Mark missing UDS as "+"
mutate(
udsLattice3 = recode_missing_visits(use_pattern = udsLattice2)
) %>%
# Count "+" UDS; 0 could be complete dropout or all negative
mutate(
woody2008_use = count_matches(
use_pattern = udsLattice3,
match_is = "+",
mixed_results_are = "*",
proportion = TRUE
)
) %>%
mutate(Rd_woody_2008 = 1 - woody2008_use) %>%
select(who, Rd_woody_2008) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_woody_2008)
## # A tibble: 10 × 3
## who usePatternUDS Rd_woody_2008
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 1
## 3 13 ------------o-oooooooooo 1
## 4 17 --++*++++++-++++++-+++- 0.333
## 5 163 -o---o---o--o+---------- 1
## 6 210 -++++++++-+++----------- 0
## 7 233 *+++++++++++o++++++++++o 0
## 8 242 ----------------------- 1
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 1
## 10 2089 ++++---+--------------o- 0.333
Definition: Number of positive UOS; missing is ignored
outcomesRed_df <-
outcomesRed_df %>%
rowwise() %>%
# Ignore missing
mutate(
udsPattern = recode_missing_visits(
use_pattern = usePatternUDS,
missing_becomes = ""
)
) %>%
# Count "+" UDS; 0 could be complete dropout or all negative
mutate(
zaks1972_use = count_matches(
use_pattern = udsPattern,
match_is = "+",
mixed_results_are = "*"
)
) %>%
# For each participant, the "abstinent" metric is the number of total weeks
# of study participation - the number of positive weeks
mutate(Rd_zaks_1972 = str_length(udsPattern) - zaks1972_use) %>%
ungroup() %>%
select(who, Rd_zaks_1972) %>%
left_join(outcomesRed_df, ., by = "who")
outcomesRed_df %>%
filter(who %in% examplePeople_int) %>%
select(who, usePatternUDS, Rd_zaks_1972)
## # A tibble: 10 × 3
## who usePatternUDS Rd_zaks_1972
## <dbl> <chr> <dbl>
## 1 1 ooooooooooooooo 0
## 2 4 -------------------o-o-o 21
## 3 13 ------------o-oooooooooo 13
## 4 17 --++*++++++-++++++-+++- 5.5
## 5 163 -o---o---o--o+---------- 19
## 6 210 -++++++++-+++----------- 13
## 7 233 *+++++++++++o++++++++++o 0.5
## 8 242 ----------------------- 23
## 9 1103 ++--oo--o-+-+--o----------o-o-oo++o 20
## 10 2089 ++++---+--------------o- 18
Here is the information concerning the system configuration, packages, and their versions used in this computation:
## R version 4.4.2 (2024-10-31)
## Platform: x86_64-pc-linux-gnu
## Running under: Ubuntu 24.04.1 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.26.so; LAPACK version 3.12.0
##
## locale:
## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=en_US.UTF-8 LC_COLLATE=C
## [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
## [7] LC_PAPER=en_US.UTF-8 LC_NAME=C
## [9] LC_ADDRESS=C LC_TELEPHONE=C
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
##
## time zone: Etc/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.5 tidyr_1.3.1 tibble_3.2.1
## [9] ggplot2_3.5.1 tidyverse_2.0.0 kableExtra_1.4.0 readxl_1.4.3
## [13] CTNote_0.1.3 rmarkdown_2.29
##
## loaded via a namespace (and not attached):
## [1] sass_0.4.9 utf8_1.2.4 generics_0.1.3 xml2_1.3.6
## [5] lattice_0.22-6 stringi_1.8.4 hms_1.1.3 digest_0.6.37
## [9] magrittr_2.0.3 timechange_0.3.0 evaluate_1.0.1 grid_4.4.2
## [13] fastmap_1.2.0 Matrix_1.7-1 cellranger_1.1.0 jsonlite_1.8.9
## [17] survival_3.7-0 fansi_1.0.6 viridisLite_0.4.2 scales_1.3.0
## [21] jquerylib_0.1.4 cli_3.6.3 rlang_1.1.4 splines_4.4.2
## [25] munsell_0.5.1 withr_3.0.2 cachem_1.1.0 yaml_2.3.10
## [29] tools_4.4.2 tzdb_0.4.0 colorspace_2.1-1 buildtools_1.0.0
## [33] vctrs_0.6.5 R6_2.5.1 lifecycle_1.0.4 pkgconfig_2.0.3
## [37] bslib_0.8.0 pillar_1.9.0 gtable_0.3.6 glue_1.8.0
## [41] systemfonts_1.1.0 xfun_0.49 tidyselect_1.2.1 rstudioapi_0.17.1
## [45] sys_3.4.3 knitr_1.49 htmltools_0.5.8.1 svglite_2.1.3
## [49] maketools_1.3.1 compiler_4.4.2