The hardware and bandwidth for this mirror is donated by dogado GmbH, the Webhosting and Full Service-Cloud Provider. Check out our Wordpress Tutorial.
If you wish to report a bug, or if you are interested in having us mirror your free-software or open-source project, please feel free to contact us at mirror[@]dogado.de.

Control, A, B, and A+B Designs with Withdrawal and Carryover

Amanda Li

This vignette illustrates the component engine introduced in version 0.4.0. The schedule contains four assigned treatment states: Control, A, B, and A+B. Unlike a cumulative rollout, a component may be withdrawn and later restarted. The data-generating model can retain a prespecified residual component effect after withdrawal.

Schedule

The following example contains both Control -> A -> A+B -> B and Control -> B -> A+B paths. Numeric state codes are 0 for Control, 1 for A, 2 for B, and 3 for A+B.

library(stepwedgepower)

state <- rbind(
  S1 = c(0, 0, 1, 1, 3, 3, 2, 2, 2, 2),
  S2 = c(0, 0, 0, 1, 1, 3, 3, 2, 2, 2),
  S3 = c(0, 0, 2, 2, 3, 3, 3, 3, 3, 3),
  S4 = c(0, 0, 0, 2, 2, 3, 3, 3, 3, 3),
  S5 = c(0, 0, 1, 1, 1, 3, 3, 3, 3, 3),
  S6 = c(0, 0, 2, 2, 2, 3, 3, 3, 3, 3),
  S7 = c(0, 0, 0, 0, 0, 1, 1, 3, 2, 2),
  S8 = c(0, 0, 0, 0, 0, 2, 2, 3, 1, 1)
)

design <- sw_component_design(
  clusters_per_sequence = rep(5L, 8),
  state = state
)
design
#> <sw_component_design>
#>   8 sequences, 10 calendar periods, 40 clusters total
#>   clusters per sequence: 5, 5, 5, 5, 5, 5, 5, 5 
#>   observed cluster-periods: 400 of 400
#>   observed states present: Control, A, B, A+B 
#>   withdrawals: A = 3, B = 1; restarts: A = 0, B = 0
#>    Period 1 Period 2 Period 3 Period 4 Period 5 Period 6 Period 7 Period 8
#> S1 Control  Control  A        A        A+B      A+B      B        B       
#> S2 Control  Control  Control  A        A        A+B      A+B      B       
#> S3 Control  Control  B        B        A+B      A+B      A+B      A+B     
#> S4 Control  Control  Control  B        B        A+B      A+B      A+B     
#> S5 Control  Control  A        A        A        A+B      A+B      A+B     
#> S6 Control  Control  B        B        B        A+B      A+B      A+B     
#> S7 Control  Control  Control  Control  Control  A        A        A+B     
#> S8 Control  Control  Control  Control  Control  B        B        A+B     
#>    Period 9 Period 10
#> S1 B        B        
#> S2 B        B        
#> S3 A+B      A+B      
#> S4 A+B      A+B      
#> S5 A+B      A+B      
#> S6 A+B      A+B      
#> S7 B        B        
#> S8 A        A

The schedule is represented internally by separate binary assignment matrices for A and B. It is not treated as an ordinal 0–3 dose.

Effects, wash-in, and carryover

assumptions <- sw_component_assumptions(
  baseline_prob = 0.15,
  treatment_or_a = 1.35,
  treatment_or_b = 1.25,
  interaction_or = 1.10,
  delay_a = 1L,
  delay_b = 1L,
  carryover_periods_a = 2L,
  carryover_periods_b = 2L,
  carryover_weights_a = c(0.60, 0.30),
  carryover_weights_b = c(0.50, 0.25),
  restart_rule_a = "reset",
  restart_rule_b = "reset",
  interaction_mode = "effective_overlap",
  icc = 0.05,
  period_effects = log(seq(1.00, 1.10, length.out = ncol(state))),
  n_per_cluster_period = 25L
)
assumptions
#> <sw_component_assumptions>
#>   A vs Control: OR = 1.350; wash-in = 1 period(s)
#>   B vs Control: OR = 1.250; wash-in = 1 period(s)
#>   A-by-B interaction OR = 1.100; mode = effective_overlap
#>   A carryover weights: 0.600, 0.300 
#>   B carryover weights: 0.500, 0.250 
#>   restart rules: A = reset; B = reset
#>   cluster_sd = 0.416 (latent ICC = 0.050)
#>   baseline probabilities: 0.150 
#>   period effects (log-odds): 0.000, 0.011, 0.022, 0.033, 0.043, 0.054, 0.065, 0.075, 0.085, 0.095

A one-period delay means that a component first contributes its full effect in the second consecutive assigned period. After A is withdrawn, 60 percent and 30 percent of its full log-odds effect persist for two periods. With interaction_mode = "effective_overlap", the interaction weight is the product of the effective A and B weights, so interaction carryover is possible while both effective components overlap.

Design audit

audit <- audit_component_design(design, assumptions)
audit
#> <sw_component_audit>
#>   observed-data fixed-effect rank: 13 of 13 (full)
#>   observed cluster-periods: 400 of 400; missing: 0
#>   requested contrasts:
#>       contrast              label estimable
#>   A_vs_control       A vs Control      TRUE
#>   B_vs_control       B vs Control      TRUE
#>         B_vs_A             B vs A      TRUE
#>  AB_vs_control     A+B vs Control      TRUE
#>        AB_vs_A           A+B vs A      TRUE
#>        AB_vs_B           A+B vs B      TRUE
#>    interaction A-by-B interaction      TRUE
#>   withdrawals: A = 3, B = 1; restarts: A = 0, B = 0
#>   no structural cautions detected

The audit checks the rank of the intended fixed-effect model and formal estimability of seven standard contrasts. It also reports concurrent state comparisons and notes any withdrawal for which immediate washout has been assumed.

One simulated trial

one_trial <- simulate_component_swcrt(design, assumptions, seed = 123)
fit <- fit_component_model(
  one_trial,
  multiplicity = "holm",
  multiplicity_family = c("A_vs_control", "B_vs_control", "interaction")
)
fit$contrasts
#>        contrast              label    estimate  std_error    z_value
#> 1  A_vs_control       A vs Control  0.28167648 0.12624162  2.2312489
#> 2  B_vs_control       B vs Control  0.24813868 0.13065804  1.8991459
#> 3        B_vs_A             B vs A -0.03353779 0.10279759 -0.3262507
#> 4 AB_vs_control     A+B vs Control  0.74970708 0.16120443  4.6506604
#> 5       AB_vs_A           A+B vs A  0.46803060 0.12204672  3.8348480
#> 6       AB_vs_B           A+B vs B  0.50156840 0.09744417  5.1472385
#> 7   interaction A-by-B interaction  0.21989192 0.14437806  1.5230286
#>        p_value     conf_low conf_high odds_ratio p_adjusted reject
#> 1 2.566465e-02  0.034247446 0.5291055  1.3253499 0.07699394   TRUE
#> 2 5.754530e-02 -0.007946378 0.5042237  1.2816377 0.11509060  FALSE
#> 3 7.442346e-01 -0.235017370 0.1679418  0.9670184         NA  FALSE
#> 4 3.308737e-06  0.433752196 1.0656620  2.1163800         NA   TRUE
#> 5 1.256420e-04  0.228823437 0.7072378  1.5968463         NA   TRUE
#> 6 2.643491e-07  0.310581328 0.6925555  1.6513091         NA   TRUE
#> 7 1.277515e-01 -0.063083881 0.5028677  1.2459421 0.12775154  FALSE
#>   reject_adjusted
#> 1           FALSE
#> 2           FALSE
#> 3              NA
#> 4              NA
#> 5              NA
#> 6              NA
#> 7           FALSE

The standard contrasts are:

The interaction coefficient is the departure from additivity on the log-odds scale. A B-only state is required to separate the B main effect from the interaction when the interaction is fitted.

Power and global-null calibration

A short exploratory run is shown below. A final analysis should use a simulation count chosen from a prespecified Monte Carlo precision target and should also run the global-null design through type1_component_swcrt().

power <- power_component_swcrt(
  design,
  assumptions,
  nsim = 5000,
  multiplicity = "holm",
  multiplicity_family = c("A_vs_control", "B_vs_control", "interaction"),
  nAGQ = 1,
  n_cores = 4,
  seed = 2026
)
summary(power)
power$fit_diagnostics
power$replicate_diagnostics

type1 <- type1_component_swcrt(
  design,
  assumptions,
  nsim = 5000,
  multiplicity = "holm",
  multiplicity_family = c("A_vs_control", "B_vs_control", "interaction"),
  nAGQ = 1,
  n_cores = 4,
  seed = 22026
)
summary(type1)

The primary fit statuses are hard GLMM error, nonconverged fit, converged fit with a non-finite requested contrast, and successful fit. Singular fit is a separate, non-exclusive property.

Both conditional power and failure-aware power are reported. Their difference shows how much the apparent operating performance depends on excluding failed or non-estimable analyses.

These binaries (installable software) and packages are in development.
They may not be fully stable and should be used with caution. We make no claims about them.
Health stats visible at Monitor.