romainkp / stremr

Streamlined Estimation for Static, Dynamic and Stochastic Treatment Regimes in Longitudinal Data

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

sequential randomization

benkeser opened this issue · comments

The trial is a sequentially randomized trial with possible re-randomization based on previous response. At baseline, participants are randomized 1:1:1 into three arms, texting intervention, mobile app intervention, and standard of care. At 3 month increments participants in the text and app arms who do not "improve" their risk behaviors are eligible for re-randomization into a third intervention, e-coaching.

Because it's a randomized trial, at each time I know the probability of receiving each treatment given the past. I don't necessarily have to input the known probabilities, but I can't figure out how to properly stratify the fitPropensity command and can't digest what the error messages are actually telling me.

Attached is an example data table.

  • ID = partic. id
  • covariate = a binary baseline covariate
  • Y = the outcome at month 12
  • txt = on the texting intervention
  • app = on the app intervention
  • t = time (0 = baseline, 3, 6, 9, 12 months)
  • monitor = whether they are seen at t + 3
  • risk = risk behavior score, if risk at t+3 is bigger than or equal to risk at t (and risk at t != 0) and -
  • txt == 1 | app == 1, then they are eligible at t+3 for rerandomizaiton to e-coaching. Y is the sum of risk at 3, 6, 9, and 12.
  • trt = multinomial treatment indicator 1 = txt, 2 = app
  • Y_scale = Y scaled by maximum value of Y
  • trt.setXX = treatment levels for rules I'm interested in (no int, all txt int, all app int, txt + e-coaching when risk doesn't improve, app + e-coaching when risk doesn't improve)
  • eligible = whether or not someone is eligible for re-randomization at t
  • ecoach = on the e-coach intervention
  • coach.tminus1 = on e-coach intervention at previous time point
  • cens = censoring = 0 for everyone, since it seemed like providing monitoring status made stremr happier than censoring + missing values

Here's what I've tried:

gform_MONITOR <- "monitor ~ risk + covariate"
# would perhaps prefer this to be intercept only, but ~1 syntax seems to piss everything off
gform_TRT <- "trt ~ risk"
stratify_TRT <- list(trt = c(
  "t == 0", # baseline randomization prob.
  "t == 3 & eligible == 1", # at time 3 prob. of getting e-coaching amongst those eligible (should be 1/2)
  "t == 6 & eligible == 1", # at time 6 prob. of getting e-coaching amongst those eligible (should be 1/2)
  "t == 9 & eligible == 1", # at time 9, etc... 
  "t == 3 & txt == 1 & eligible == 0", # at time 3, txt folks should stay on txt with prob. 1 if not eligible for e-coach
  "t == 6 & txt == 1 & eligible == 0", # at time 6, txt folks should stay on txt with prob. 1 if not eligible for e-coach
  "t == 9 & txt == 1 & eligible == 0", # etc...
  "t == 3 & app == 1 & eligible == 0", # ditto app people who are not eligible
  "t == 6 & app == 1 & eligible == 0", # etc 
  "t == 9 & app == 1 & eligible == 0", # etc
  "t == 3 & app == 0 & txt == 0", # ditto standard of care people, i.e. trt == 0
  "t == 6 & app == 0 & txt == 0", # etc
  "t == 9 & app == 0 & txt == 0", # etc
  "t == 6 & ecoach.tminus1 == 1",  # once you get to e-coaching, you stay on e-coaching with prob. 1
  "t == 9 & ecoach.tminus1 == 1"))

I'm just wondering how to properly specify these regressions and whether there is a way to make them intercept only or not.

testDT.RData.zip

Thanks for reporting. I believe the issue has to do with stratas for which trt variable is constant, but its neither 0 or 1 (exactly what the error message says). condensier doesn't know what to do in this case -- how is it supposed to factorize a multinomial variable when only one level of that variable has been provided? I believe its a fixable corner case in condensier. But I am not sure the results will have the right interpretation. The key issue is that stratas are higher level operation compared to the factorization of multinomial treatment. So, first the stratas are defined, each strata is outsourced and is treated as a completely separate regression problem. If the treatment variable in a particular strata happens to have more than 2 levels, it is then treated as a multinomial regression problem and is factorized and fitted using condensier. Otherwise its just a regular logistic regression.

So can we first verify that this is indeed your intended behavior to fit a logistic regression for some strata where only a single level of trt is present? How should this level be coded for the relevant logistic regression, as 1 or 0?

I think it may be dangerous to fit the multinomial trt with many stratas in this way. The levels of the multinomial treatment are not being preserved across different stratas. For example consider the case where strata 1 contains the levels of trt equal to 0 and 1, while strata 2 contains the levels 1 and 2. The first strata fit is performed with a regular logistic regression model, since the outcome is just 0/1. The 2nd strata fit will re-code the levels (1/2) into bins (0/1), and will then also perform a single logistic regression fit. By themselves, the results of these fits are perfectly interpretable within each strata. What happens though when you try to combine these fits as propensity scores across all stratas? I am not sure, I can only image a total mess. It is much safer to go with multinomial coded as several binary treatment nodes, unless all of your stratas contain exactly the same levels.

Also, please confirm the replication code below, you can replicate the output by setting the verbose option. This is what I get when I run the regressions for treatment. Note that the counts for each strata and levels are also part of this verbose output. You can see how each strata here is a completely separate regression problem.

library("stremr")
library("sl3")
library("magrittr")
library("data.table")
library("testthat")

data.table::setDTthreads(1)
options(stremr.verbose = TRUE)
options(gridisl.verbose = TRUE)
options(sl3.verbose = TRUE)
options(condensier.verbose = TRUE)


## stratas that fail trt is always constant
testDT[t == 3 & app == 1 & eligible == 0, ]
    ID covariate  Y txt app t monitor risk trt Y_scale trt.set0 trt.set1 trt.set2 trt.set13 trt.set23 eligible ecoach ecoach.tminus1
 1:  9         0  7   0   1 3       1    1   2       0        0        1        2         1         2        0      0              0
 2: 14         1  0   0   1 3       1    0   2       0        0        1        2         1         2        0      0              0
 3: 16         1  0   0   1 3       1    0   2       0        0        1        2         1         2        0      0              0
 4: 27         1  0   0   1 3       1    0   2       0        0        1        2         1         2        0      0              0
 5: 30         0  0   0   1 3       1    0   2       0        0        1        2         1         2        0      0              0
 6: 38         0 17   0   1 3       1    2   2       0        0        1        2         1         2        0      0              0
 7: 41         0  0   0   1 3       1    0   2       0        0        1        2         1         2        0      0              0
 8: 46         0  0   0   1 3       1    0   2       0        0        1        2         1         2        0      0              0
 9: 49         1  0   0   1 3       0    5   2       0        0        1        2         1         2        0      0              0
10: 50         1  0   0   1 3       1    0   2       0        0        1        2         1         2        0      0              0
11: 51         1  0   0   1 3       1    0   2       0        0        1        2         1         2        0      0              0
12: 78         1 11   0   1 3       1    3   2       0        0        1        2         1         2        0      0              0
13: 92         0  0   0   1 3       0    0   2       0        0        1        2         1         2        0      0              0
14: 99         1 17   0   1 3       1    6   2       0        0        1        2         1         2        0      0              0

testDT <- data.table(testDT)
OData <- importData(testDT, ID = "ID", t = "t", covars = c("covariate"), TRT = "trt", OUTCOME = "Y_scale")
gform_TRT <- "trt ~ risk"
stratify_TRT <- list(trt = c(
  "t == 0", # baseline randomization prob.
  "t == 3 & eligible == 1", # at time 3 prob. of getting e-coaching amongst those eligible (should be 1/2)
  "t == 6 & eligible == 1", # at time 6 prob. of getting e-coaching amongst those eligible (should be 1/2)
  "t == 9 & eligible == 1", # at time 9, etc... 
  "t == 3 & txt == 1 & eligible == 0", # at time 3, txt folks should stay on txt with prob. 1 if not eligible for e-coach
  "t == 6 & txt == 1 & eligible == 0", # at time 6, txt folks should stay on txt with prob. 1 if not eligible for e-coach
  "t == 9 & txt == 1 & eligible == 0", # etc...
  "t == 3 & app == 1 & eligible == 0", # ditto app people who are not eligible
  "t == 6 & app == 1 & eligible == 0", # etc 
  "t == 9 & app == 1 & eligible == 0", # etc
  "t == 3 & app == 0 & txt == 0", # ditto standard of care people, i.e. trt == 0
  "t == 6 & app == 0 & txt == 0", # etc
  "t == 9 & app == 0 & txt == 0", # etc
  "t == 6 & ecoach.tminus1 == 1",  # once you get to e-coaching, you stay on e-coaching with prob. 1
  "t == 9 & ecoach.tminus1 == 1"))
OData <- fitPropensity(OData, gform_TRT = gform_TRT, stratify_TRT = stratify_TRT)
[1] "New 'ModelCategorical' regression defined:"
[1] "P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 0;\\ N: NA"
[1] "New 'ModelCategorical' regression defined:"
[1] "P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 3 & eligible == 1;\\ N: NA"
[1] "New 'ModelCategorical' regression defined:"
[1] "P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 6 & eligible == 1;\\ N: NA"
[1] "New 'ModelCategorical' regression defined:"
[1] "P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 9 & eligible == 1;\\ N: NA"
[1] "New 'ModelCategorical' regression defined:"
[1] "P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 3 & txt == 1 & eligible == 0;\\ N: NA"
[1] "New 'ModelCategorical' regression defined:"
[1] "P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 6 & txt == 1 & eligible == 0;\\ N: NA"
[1] "New 'ModelCategorical' regression defined:"
[1] "P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 9 & txt == 1 & eligible == 0;\\ N: NA"
[1] "New 'ModelCategorical' regression defined:"
[1] "P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 3 & app == 1 & eligible == 0;\\ N: NA"
[1] "New 'ModelCategorical' regression defined:"
[1] "P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 6 & app == 1 & eligible == 0;\\ N: NA"
[1] "New 'ModelCategorical' regression defined:"
[1] "P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 9 & app == 1 & eligible == 0;\\ N: NA"
[1] "New 'ModelCategorical' regression defined:"
[1] "P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 3 & app == 0 & txt == 0;\\ N: NA"
[1] "New 'ModelCategorical' regression defined:"
[1] "P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 6 & app == 0 & txt == 0;\\ N: NA"
[1] "New 'ModelCategorical' regression defined:"
[1] "P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 9 & app == 0 & txt == 0;\\ N: NA"
[1] "New 'ModelCategorical' regression defined:"
[1] "P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 6 & ecoach.tminus1 == 1;\\ N: NA"
[1] "New 'ModelCategorical' regression defined:"
[1] "P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 9 & ecoach.tminus1 == 1;\\ N: NA"
[1] "fitting the model: P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 0;\\ N: NA"
[1] "#----------------------------------------------------------------------------------"
[1] "New instance of SummariesModel:"
[1] "#----------------------------------------------------------------------------------"
[1] "Outcomes: trt"
[1] "Predictors: risk"
[1] "No. of regressions: 1"
[1] "All outcomes binary? FALSE"
[1] "#----------------------------------------------------------------------------------"
[1] "CategorSummaryModel outcome: trt"
[1] "#----------------------------------------------------------------------------------"
[1] "New instance of SummariesModel:"
[1] "#----------------------------------------------------------------------------------"
[1] "Outcomes: trt_B.1, trt_B.2, trt_B.3"
[1] "Predictors: risk"
[1] "No. of regressions: 3"
[1] "All outcomes binary? TRUE"
[1] "#----------------------------------------------------------------------------------"
[1] "New BinOutModel instance:"
[1] "P(trt_B.1|risk)"
[1] "New BinOutModel instance:"
[1] "P(trt_B.2|risk)"
[1] "New BinOutModel instance:"
[1] "P(trt_B.3|risk)"
[1] "performing fitting for categorical outcome: trt"
[1] "freq counts by bin for categorical outcome: "

 0  1  2 
38 34 28 
[1] "binned dataset: "
     sA trt_B.1 trt_B.2 trt_B.3
[1,]  1       0       1      NA
[2,]  2       0       0      NA
[3,]  0       1      NA      NA
[4,]  2       0       0      NA
[5,]  0       1      NA      NA
[1] "calling  sl3::Lrnr_glm_fast$train"
[1] "Lrnr_glm_fast_TRUE_Cholesky"
Generalized Linear Model of class 'speedglm':
Coefficients:
     risk  intercept  
  0.07955   -0.76958  

[1] "calling  sl3::Lrnr_glm_fast$train"
[1] "Lrnr_glm_fast_TRUE_Cholesky"
Generalized Linear Model of class 'speedglm':
Coefficients:
     risk  intercept  
  0.05136    0.02777  

[1] "calling  sl3::Lrnr_glm_fast$train"
[1] "Lrnr_glm_fast_TRUE_Cholesky"
fit for trt var succeeded...
[1] "fitting the model: P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 3 & eligible == 1;\\ N: NA"
[1] "#----------------------------------------------------------------------------------"
[1] "New instance of SummariesModel:"
[1] "#----------------------------------------------------------------------------------"
[1] "Outcomes: trt"
[1] "Predictors: risk"
[1] "No. of regressions: 1"
[1] "All outcomes binary? FALSE"
[1] "#----------------------------------------------------------------------------------"
[1] "CategorSummaryModel outcome: trt"
[1] "#----------------------------------------------------------------------------------"
[1] "New instance of SummariesModel:"
[1] "#----------------------------------------------------------------------------------"
[1] "Outcomes: trt_B.1, trt_B.2, trt_B.3"
[1] "Predictors: risk"
[1] "No. of regressions: 3"
[1] "All outcomes binary? TRUE"
[1] "#----------------------------------------------------------------------------------"
[1] "New BinOutModel instance:"
[1] "P(trt_B.1|risk)"
[1] "New BinOutModel instance:"
[1] "P(trt_B.2|risk)"
[1] "New BinOutModel instance:"
[1] "P(trt_B.3|risk)"
[1] "performing fitting for categorical outcome: trt"
[1] "freq counts by bin for categorical outcome: "

 1  2  3 
 7  3 12 
[1] "binned dataset: "
     sA trt_B.1 trt_B.2 trt_B.3
[1,]  3       0       0      NA
[2,]  2       0       1      NA
[3,]  2       0       1      NA
[4,]  1       1      NA      NA
[5,]  3       0       0      NA
[1] "calling  sl3::Lrnr_glm_fast$train"
[1] "Lrnr_glm_fast_TRUE_Cholesky"
Generalized Linear Model of class 'speedglm':
Coefficients:
     risk  intercept  
 -0.05436   -0.49279  

[1] "calling  sl3::Lrnr_glm_fast$train"
[1] "Lrnr_glm_fast_TRUE_Cholesky"
Generalized Linear Model of class 'speedglm':
Coefficients:
     risk  intercept  
  0.02312   -1.50766  

[1] "calling  sl3::Lrnr_glm_fast$train"
[1] "Lrnr_glm_fast_TRUE_Cholesky"
fit for trt var succeeded...
[1] "fitting the model: P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 6 & eligible == 1;\\ N: NA"
[1] "#----------------------------------------------------------------------------------"
[1] "New instance of SummariesModel:"
[1] "#----------------------------------------------------------------------------------"
[1] "Outcomes: trt"
[1] "Predictors: risk"
[1] "No. of regressions: 1"
[1] "All outcomes binary? FALSE"
[1] "#----------------------------------------------------------------------------------"
[1] "CategorSummaryModel outcome: trt"
[1] "#----------------------------------------------------------------------------------"
[1] "New instance of SummariesModel:"
[1] "#----------------------------------------------------------------------------------"
[1] "Outcomes: trt_B.1, trt_B.2, trt_B.3"
[1] "Predictors: risk"
[1] "No. of regressions: 3"
[1] "All outcomes binary? TRUE"
[1] "#----------------------------------------------------------------------------------"
[1] "New BinOutModel instance:"
[1] "P(trt_B.1|risk)"
[1] "New BinOutModel instance:"
[1] "P(trt_B.2|risk)"
[1] "New BinOutModel instance:"
[1] "P(trt_B.3|risk)"
[1] "performing fitting for categorical outcome: trt"
[1] "freq counts by bin for categorical outcome: "

1 2 3 
1 2 4 
[1] "binned dataset: "
     sA trt_B.1 trt_B.2 trt_B.3
[1,]  3       0       0      NA
[2,]  3       0       0      NA
[3,]  3       0       0      NA
[4,]  2       0       1      NA
[5,]  1       1      NA      NA
[1] "calling  sl3::Lrnr_glm_fast$train"
[1] "Lrnr_glm_fast_TRUE_Cholesky"
Generalized Linear Model of class 'speedglm':
Coefficients:
     risk  intercept  
  -0.2545    -0.5450  

[1] "calling  sl3::Lrnr_glm_fast$train"
[1] "Lrnr_glm_fast_TRUE_Cholesky"
Generalized Linear Model of class 'speedglm':
Coefficients:
     risk  intercept  
  -0.3021     0.9257  

[1] "calling  sl3::Lrnr_glm_fast$train"
[1] "Lrnr_glm_fast_TRUE_Cholesky"
fit for trt var succeeded...
[1] "fitting the model: P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 9 & eligible == 1;\\ N: NA"
[1] "#----------------------------------------------------------------------------------"
[1] "New instance of SummariesModel:"
[1] "#----------------------------------------------------------------------------------"
[1] "Outcomes: trt"
[1] "Predictors: risk"
[1] "No. of regressions: 1"
[1] "All outcomes binary? FALSE"
[1] "#----------------------------------------------------------------------------------"
[1] "CategorSummaryModel outcome: trt"
[1] "#----------------------------------------------------------------------------------"
[1] "New instance of SummariesModel:"
[1] "#----------------------------------------------------------------------------------"
[1] "Outcomes: trt_B.1, trt_B.2, trt_B.3"
[1] "Predictors: risk"
[1] "No. of regressions: 3"
[1] "All outcomes binary? TRUE"
[1] "#----------------------------------------------------------------------------------"
[1] "New BinOutModel instance:"
[1] "P(trt_B.1|risk)"
[1] "New BinOutModel instance:"
[1] "P(trt_B.2|risk)"
[1] "New BinOutModel instance:"
[1] "P(trt_B.3|risk)"
[1] "performing fitting for categorical outcome: trt"
[1] "freq counts by bin for categorical outcome: "

1 2 3 
1 2 1 
[1] "binned dataset: "
     sA trt_B.1 trt_B.2 trt_B.3
[1,]  2       0       1      NA
[2,]  2       0       1      NA
[3,]  1       1      NA      NA
[4,]  3       0       0      NA
[1] "calling  sl3::Lrnr_glm_fast$train"
[1] "Lrnr_glm_fast_TRUE_Cholesky"
Generalized Linear Model of class 'speedglm':
Coefficients:
     risk  intercept  
    46.72    -256.95  

[1] "calling  sl3::Lrnr_glm_fast$train"
[1] "Lrnr_glm_fast_TRUE_Cholesky"
Generalized Linear Model of class 'speedglm':
Coefficients:
     risk  intercept  
    47.13    -212.09  

[1] "calling  sl3::Lrnr_glm_fast$train"
[1] "Lrnr_glm_fast_TRUE_Cholesky"
fit for trt var succeeded...
[1] "fitting the model: P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 3 & txt == 1 & eligible == 0;\\ N: NA"
[1] "#----------------------------------------------------------------------------------"
[1] "New instance of SummariesModel:"
[1] "#----------------------------------------------------------------------------------"
[1] "Outcomes: trt"
[1] "Predictors: risk"
[1] "No. of regressions: 1"
[1] "All outcomes binary? TRUE"
[1] "#----------------------------------------------------------------------------------"
[1] "New BinOutModel instance:"
[1] "P(trt|risk)"
[1] "calling  sl3::Lrnr_glm_fast$train"
[1] "Lrnr_glm_fast_TRUE_Cholesky"
Generalized Linear Model of class 'speedglm':
Coefficients:
     risk  intercept  
1.058e-10  2.557e+01  

[1] "fitting the model: P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 6 & txt == 1 & eligible == 0;\\ N: NA"
[1] "#----------------------------------------------------------------------------------"
[1] "New instance of SummariesModel:"
[1] "#----------------------------------------------------------------------------------"
[1] "Outcomes: trt"
[1] "Predictors: risk"
[1] "No. of regressions: 1"
[1] "All outcomes binary? TRUE"
[1] "#----------------------------------------------------------------------------------"
[1] "New BinOutModel instance:"
[1] "P(trt|risk)"
[1] "calling  sl3::Lrnr_glm_fast$train"
[1] "Lrnr_glm_fast_TRUE_Cholesky"
Generalized Linear Model of class 'speedglm':
Coefficients:
     risk  intercept  
    1.817     -2.799  

[1] "fitting the model: P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 9 & txt == 1 & eligible == 0;\\ N: NA"
[1] "#----------------------------------------------------------------------------------"
[1] "New instance of SummariesModel:"
[1] "#----------------------------------------------------------------------------------"
[1] "Outcomes: trt"
[1] "Predictors: risk"
[1] "No. of regressions: 1"
[1] "All outcomes binary? TRUE"
[1] "#----------------------------------------------------------------------------------"
[1] "New BinOutModel instance:"
[1] "P(trt|risk)"
[1] "calling  sl3::Lrnr_glm_fast$train"
[1] "Lrnr_glm_fast_TRUE_Cholesky"
Generalized Linear Model of class 'speedglm':
Coefficients:
     risk  intercept  
   19.855     -1.609  

[1] "fitting the model: P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 3 & app == 1 & eligible == 0;\\ N: NA"
[1] "#----------------------------------------------------------------------------------"
[1] "New instance of SummariesModel:"
[1] "#----------------------------------------------------------------------------------"
[1] "Outcomes: trt"
[1] "Predictors: risk"
[1] "No. of regressions: 1"
[1] "All outcomes binary? TRUE"
[1] "#----------------------------------------------------------------------------------"
[1] "New BinOutModel instance:"
[1] "P(trt|risk)"
[1] "calling  sl3::Lrnr_glm_fast$train"
speedglm::speedglm.wfit failed, falling back on stats:glm.fit; Error in eval(family$initialize) : y values must be 0 <= y <= 1

Failed on Lrnr_glm_fast_TRUE_Cholesky
Error in eval(family$initialize) : y values must be 0 <= y <= 1
learner sl3::Lrnr_glm_fast$train failed, trying private$fallback_learner; 
[1] "Error in eval(family$initialize) : y values must be 0 <= y <= 1\n"
attr(,"class")
[1] "try-error"
attr(,"condition")
<simpleError in eval(family$initialize): y values must be 0 <= y <= 1>
Failed on Lrnr_glm_fast_TRUE_Cholesky_binomial
Failed on Lrnr_condensier_c("equal.mass", "equal.len", "dhist")_5_20_FALSE_NA_FALSE_NULL
Error in args$family$family : $ operator is invalid for atomic vectors

sl3 error debugging info:
[1] "Error in args$family$family : $ operator is invalid for atomic vectors\n"
attr(,"class")
[1] "try-error"
attr(,"condition")
<simpleError in args$family$family: $ operator is invalid for atomic vectors>
...trying to run Lrnr_glm_fast as a backup...
[1] "fitting the model: P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 6 & app == 1 & eligible == 0;\\ N: NA"
[1] "#----------------------------------------------------------------------------------"
[1] "New instance of SummariesModel:"
[1] "#----------------------------------------------------------------------------------"
[1] "Outcomes: trt"
[1] "Predictors: risk"
[1] "No. of regressions: 1"
[1] "All outcomes binary? TRUE"
[1] "#----------------------------------------------------------------------------------"
[1] "New BinOutModel instance:"
[1] "P(trt|risk)"
[1] "calling  sl3::Lrnr_glm_fast$train"
[1] "Lrnr_glm_fast_TRUE_Cholesky"
Generalized Linear Model of class 'speedglm':
Coefficients:
     risk  intercept  
   0.4113    -1.5238  

[1] "fitting the model: P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 9 & app == 1 & eligible == 0;\\ N: NA"
[1] "#----------------------------------------------------------------------------------"
[1] "New instance of SummariesModel:"
[1] "#----------------------------------------------------------------------------------"
[1] "Outcomes: trt"
[1] "Predictors: risk"
[1] "No. of regressions: 1"
[1] "All outcomes binary? TRUE"
[1] "#----------------------------------------------------------------------------------"
[1] "New BinOutModel instance:"
[1] "P(trt|risk)"
[1] "calling  sl3::Lrnr_glm_fast$train"
[1] "Lrnr_glm_fast_TRUE_Cholesky"
Generalized Linear Model of class 'speedglm':
Coefficients:
     risk  intercept  
   19.753     -1.099  

[1] "fitting the model: P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 3 & app == 0 & txt == 0;\\ N: NA"
[1] "#----------------------------------------------------------------------------------"
[1] "New instance of SummariesModel:"
[1] "#----------------------------------------------------------------------------------"
[1] "Outcomes: trt"
[1] "Predictors: risk"
[1] "No. of regressions: 1"
[1] "All outcomes binary? TRUE"
[1] "#----------------------------------------------------------------------------------"
[1] "New BinOutModel instance:"
[1] "P(trt|risk)"
[1] "calling  sl3::Lrnr_glm_fast$train"
[1] "Lrnr_glm_fast_TRUE_Cholesky"
Generalized Linear Model of class 'speedglm':
Coefficients:
      risk   intercept  
-7.771e-15  -2.657e+01  

[1] "fitting the model: P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 6 & app == 0 & txt == 0;\\ N: NA"
[1] "#----------------------------------------------------------------------------------"
[1] "New instance of SummariesModel:"
[1] "#----------------------------------------------------------------------------------"
[1] "Outcomes: trt"
[1] "Predictors: risk"
[1] "No. of regressions: 1"
[1] "All outcomes binary? TRUE"
[1] "#----------------------------------------------------------------------------------"
[1] "New BinOutModel instance:"
[1] "P(trt|risk)"
[1] "calling  sl3::Lrnr_glm_fast$train"
[1] "Lrnr_glm_fast_TRUE_Cholesky"
Generalized Linear Model of class 'speedglm':
Coefficients:
      risk   intercept  
 1.258e-15  -2.557e+01  

[1] "fitting the model: P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 9 & app == 0 & txt == 0;\\ N: NA"
[1] "#----------------------------------------------------------------------------------"
[1] "New instance of SummariesModel:"
[1] "#----------------------------------------------------------------------------------"
[1] "Outcomes: trt"
[1] "Predictors: risk"
[1] "No. of regressions: 1"
[1] "All outcomes binary? TRUE"
[1] "#----------------------------------------------------------------------------------"
[1] "New BinOutModel instance:"
[1] "P(trt|risk)"
[1] "calling  sl3::Lrnr_glm_fast$train"
[1] "Lrnr_glm_fast_TRUE_Cholesky"
Generalized Linear Model of class 'speedglm':
Coefficients:
      risk   intercept  
 2.926e-15  -2.557e+01  

[1] "fitting the model: P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 6 & ecoach.tminus1 == 1;\\ N: NA"
[1] "#----------------------------------------------------------------------------------"
[1] "New instance of SummariesModel:"
[1] "#----------------------------------------------------------------------------------"
[1] "Outcomes: trt"
[1] "Predictors: risk"
[1] "No. of regressions: 1"
[1] "All outcomes binary? TRUE"
[1] "#----------------------------------------------------------------------------------"
[1] "New BinOutModel instance:"
[1] "P(trt|risk)"
[1] "calling  sl3::Lrnr_glm_fast$train"
speedglm::speedglm.wfit failed, falling back on stats:glm.fit; Error in eval(family$initialize) : y values must be 0 <= y <= 1

Failed on Lrnr_glm_fast_TRUE_Cholesky
Error in eval(family$initialize) : y values must be 0 <= y <= 1
learner sl3::Lrnr_glm_fast$train failed, trying private$fallback_learner; 
[1] "Error in eval(family$initialize) : y values must be 0 <= y <= 1\n"
attr(,"class")
[1] "try-error"
attr(,"condition")
<simpleError in eval(family$initialize): y values must be 0 <= y <= 1>
Failed on Lrnr_glm_fast_TRUE_Cholesky_binomial
Failed on Lrnr_condensier_c("equal.mass", "equal.len", "dhist")_5_20_FALSE_NA_FALSE_NULL
Error in args$family$family : $ operator is invalid for atomic vectors

sl3 error debugging info:
[1] "Error in args$family$family : $ operator is invalid for atomic vectors\n"
attr(,"class")
[1] "try-error"
attr(,"condition")
<simpleError in args$family$family: $ operator is invalid for atomic vectors>
...trying to run Lrnr_glm_fast as a backup...
[1] "fitting the model: P(trt|risk);\\ outvar.class: categorical;\\ Stratify: t == 9 & ecoach.tminus1 == 1;\\ N: NA"
[1] "#----------------------------------------------------------------------------------"
[1] "New instance of SummariesModel:"
[1] "#----------------------------------------------------------------------------------"
[1] "Outcomes: trt"
[1] "Predictors: risk"
[1] "No. of regressions: 1"
[1] "All outcomes binary? TRUE"
[1] "#----------------------------------------------------------------------------------"
[1] "New BinOutModel instance:"
[1] "P(trt|risk)"
[1] "calling  sl3::Lrnr_glm_fast$train"
speedglm::speedglm.wfit failed, falling back on stats:glm.fit; Error in eval(family$initialize) : y values must be 0 <= y <= 1

Failed on Lrnr_glm_fast_TRUE_Cholesky
Error in eval(family$initialize) : y values must be 0 <= y <= 1
learner sl3::Lrnr_glm_fast$train failed, trying private$fallback_learner; 
[1] "Error in eval(family$initialize) : y values must be 0 <= y <= 1\n"
attr(,"class")
[1] "try-error"
attr(,"condition")
<simpleError in eval(family$initialize): y values must be 0 <= y <= 1>
Failed on Lrnr_glm_fast_TRUE_Cholesky_binomial
Failed on Lrnr_condensier_c("equal.mass", "equal.len", "dhist")_5_20_FALSE_NA_FALSE_NULL
Error in args$family$family : $ operator is invalid for atomic vectors

sl3 error debugging info:
[1] "Error in args$family$family : $ operator is invalid for atomic vectors\n"
attr(,"class")
[1] "try-error"
attr(,"condition")
<simpleError in args$family$family: $ operator is invalid for atomic vectors>
...trying to run Lrnr_glm_fast as a backup...
fit for trt var succeeded...
[1] "performing prediction for categorical outcome: trt"
[1] "performing prediction for categorical outcome: trt"
[1] "performing prediction for categorical outcome: trt"
[1] "performing prediction for categorical outcome: trt"

Thanks for working on this.

Yes, it's a weird edge case, because basically I need it to estimate a propensity that is known to equal 1 irrespective of past covariates. This is why I thought intercept-only models were the way to go. For example, the group defined by this subsetting [t == 3 & app == 1 & eligible == 0, ] are people who are not eligible for re-randomization. That is, given their past risk behaviors, we know they will receive app with probability 1. Ditto the [t == 3 & txt == 1 & eligible == 0, ] folks; we know they will receive txt with probability 1.

I need to spend a little more time parsing the verbose output you provided.

Would it be better to use the txt, app, and e-coach columns as several binary treatment columns, rather than going for the multinomial?

It would be more tedious to code it, but is probably safer. That way you can be absolutely sure that all levels are represented the same way across all stratas. Alternatively, it is probably not too hard to come up with a patch for condensier to always interpret a single level outcome as 1. Then the entire propensity score routine should run fine.

Also, you should be able to use an intercept model, although maybe sl3 is having an issue with that. Would you mind posting the error in the verbose model? Alternative, you could just introduce a dummy variable set to constant 1 and use that as predictor. Wont be pretty, but it will work and do the right thing.