Skip to contents

A DesignSeqOneByOneKK21 variant that computes its per-covariate matching weights via forward stepwise selection (compute_weights_KK21stepwise()) instead of KK21's independent marginal-association regressions: covariates are added to a growing "selected" set one at a time, at each step choosing whichever remaining covariate has the largest absolute association statistic conditional on (i.e. in a model that also includes) the covariates already selected and the treatment-assignment column, rather than each covariate's association with the response considered in isolation. This targets the case where covariates are mutually correlated: KK21's marginal weights can assign similar high weight to several collinear prognostic covariates (effectively double-counting the same information), whereas the stepwise conditional weights down-weight a covariate once its explanatory content is already captured by previously selected covariates.

Weight computation. For each response type, a family-appropriate model (OLS/logistic/negative-binomial/beta/AFT survival/proportional-odds, matching the same response-type dispatch and *_use_speedup fast-path conventions as DesignSeqOneByOneKK21) is repeatedly refit, each time regressing the response on one candidate remaining covariate plus all previously selected covariates plus the treatment column ws; the candidate with the largest absolute association statistic is selected next and assigned that statistic as its weight, then removed from the candidate pool, and the process repeats until every covariate has been assigned a weight (an \(O(p^2)\) number of model fits per assignment call, for \(p\) covariates). If a candidate's model fit fails to converge (e.g. perfect separation or rank deficiency) partway through, the remaining not-yet-selected covariates' weights are left NA internally and then replaced with 0 (excluding them from the weighted matching distance) rather than propagating the failure.

Randomization draws. Because the stepwise models include the treatment column ws, the covariate weights (and therefore which subjects end up paired) depend in principle on the realized assignment path, even under the sharp null where the responses are fixed. Re-randomization for randomization tests and confidence intervals is therefore controlled by condition_on_ws_for_rand_tests:

  • TRUE (default): condition on the realized reservoir/pair structure exactly as DesignSeqOneByOneKK14 (and DesignSeqOneByOneKK21) do: each matched pair's assignments are flipped with probability 1/2 and reservoir subjects are redrawn independently with probability prob_T. This is fast but approximate, not exact: since w is randomized it should be (nearly) independent of the covariates, so partialling it out barely changes the conditional association statistics and the pair structure is almost always the same under a different assignment path. In simulation the resulting inference is very close to the exact replay.

  • FALSE: exact. Every randomization draw replays the entire sequential design from subject 1, refitting the stepwise weights at every step using only the responses available at that point, so pairs may form differently in each draw. This costs on the order of \(r \times n\) stepwise weight fits per set of \(r\) draws and is dramatically slower.

Everything else is inherited from KK21. Burn-in fallback to KK14, the bootstrapped acceptance-threshold test, matched-pair assignment, and the morrison/lambda/t_0_pct matching-schedule options are all unchanged from DesignSeqOneByOneKK21; only how the covariate weight vector is computed differs.

References

Kapelner, A., and Krieger, A. M. (2014). "Matching on-the-fly: Sequential allocation with higher power and efficiency." Biometrics, 70(2), 378-388, doi:10.1111/biom.12148 , for the base matching-on-the-fly algorithm; the outcome-weighted extension follows Kapelner and Krieger (2021), with this class using a forward-stepwise (rather than marginal) weight-estimation scheme. See also Morrison, T., and Owen, A. B. (2025) for the alternative morrison = TRUE threshold calibration referenced by the morrison argument.

Super classes

Design -> DesignSeqOneByOne -> DesignSeqOneByOneKK14 -> DesignSeqOneByOneKK21 -> DesignSeqOneByOneKK21stepwise

Methods

+ inherited public methods from DesignSeqOneByOneKK21
+ inherited public methods from DesignSeqOneByOneKK14
+ inherited public methods from DesignSeqOneByOne
+ inherited public methods from Design


DesignSeqOneByOneKK21stepwise$new()

Initialize a matching-on-the-fly sequential experimental design whose covariate matching weights are computed via forward stepwise selection (see class documentation), based on the stepwise version of Kapelner and Krieger (2021) with option to use matching parameters of Morrison and Owen (2025)

Usage

DesignSeqOneByOneKK21stepwise$new(
  response_type,
  prob_T = 0.5,
  include_is_missing_as_a_new_feature = TRUE,
  n = NULL,
  verbose = FALSE,
  lambda = NULL,
  t_0_pct = NULL,
  morrison = FALSE,
  p = NULL,
  num_boot = NULL,
  count_use_speedup = TRUE,
  proportion_use_speedup = TRUE,
  survival_use_speedup_for_no_censoring = TRUE,
  ordinal_use_speedup = TRUE,
  missingness_method = "impute",
  design_formula = ~.,
  condition_on_ws_for_rand_tests = TRUE,
  ...
)

Arguments

response_type

The data type of response values which must be one of the following: "continuous", "incidence", "proportion", "count", "survival". This package will enforce that all added responses via the add_one_subject_response method will be of the appropriate type.

prob_T

The probability of the treatment assignment. This defaults to 0.5.

include_is_missing_as_a_new_feature

If missing data is present in a variable, should we include another dummy variable for its missingness in addition to imputing its value? If the feature is type factor, instead of creating a new column, we allow missingness to be its own level. The default is TRUE.

n

The sample size (if fixed). Default is NULL for not fixed.

verbose

A flag indicating whether messages should be displayed to the user. Default is FALSE.

lambda

The quantile cutoff of the subject distance distribution for determining matches. If unspecified and morrison = FALSE, default is 10%.

t_0_pct

The percentage of total sample size n where matching begins. If unspecified and morrison = FALSE, default is 35%.

morrison

Default is FALSE which implies matching via the KK14 algorithm using lambda and t_0_pct matching. If TRUE, we use Morrison and Owen (2025)'s formula for lambda which differs in the fixed n versus variable n settings and matching begins immediately with no wait for a certain reservoir size like in KK14.

p

The number of covariate features. Must be specified when morrison = TRUE otherwise do not specify this argument.

num_boot

the number of bootstrap samples taken to approximate the subject-distance distribution. Default is 500.

count_use_speedup

Should we speed up the estimation of the weights in the response = count case via a continuous regression on log(y + 1). instead of a negative binomial regression each time? This is at the expense of the weights being less accurate. Default is TRUE.

proportion_use_speedup

Should we speed up the estimation of the weights in the response = proportion case via a continuous regression on log(y / (1 - y)) instead of a beta regression each time? This is at the expense of the weights being less accurate. Default is TRUE.

survival_use_speedup_for_no_censoring

Should we speed up the estimation of the weights in the response = survival case via a continuous regression on log(y) instead of a Weibull AFT regression each time, but only when there is no censoring in the data collected so far? This is at the expense of the weights being less accurate when censoring is present. Default is TRUE.

ordinal_use_speedup

Should we speed up the estimation of the weights in the response = ordinal case via a continuous regression on the ordinal levels coerced to numeric. instead of a proportional odds model each time? This is at the expense of the weights being less accurate. Default is TRUE.

missingness_method

How to handle missing values in covariates.

design_formula

A formula object.

condition_on_ws_for_rand_tests

Should randomization draws (used by randomization tests and randomization confidence intervals) condition on the realized reservoir/matched-pair structure, as in KK14? If TRUE (default), each draw flips each matched pair and redraws the reservoir; this is fast but approximate, because the stepwise weights condition on the treatment column so the pairs could in principle differ under another assignment path (since w is randomized it should be independent of the covariates, and in simulation the approximation is very close). If FALSE, each draw replays the entire sequential design, refitting the stepwise weights at every step; this is exact but much slower. See the class documentation for details.

...

Extra arguments passed to the DesignSeqOneByOneKK21 superclass.

Returns

A new `DesignSeqOneByOneKK21stepwise` object

Examples

seq_des = DesignSeqOneByOneKK21stepwise$new(n = 6, response_type = "continuous")


DesignSeqOneByOneKK21stepwise$clone()

The objects of this class are cloneable with this method.

Usage

DesignSeqOneByOneKK21stepwise$clone(deep = FALSE)

Arguments

deep

Whether to make a deep clone.

Examples

seq_des = DesignSeqOneByOneKK21stepwise$new(n = 6, response_type = 'continuous')
seq_des$add_one_subject_to_experiment_and_assign(data.frame(x1 = rnorm(1)))
#> [1] 1

## ------------------------------------------------
## Method `DesignSeqOneByOneKK21stepwise$new()`
## ------------------------------------------------

seq_des = DesignSeqOneByOneKK21stepwise$new(n = 6, response_type = "continuous")