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.

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 = ~.,
  ...
)

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.

...

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()`
## ------------------------------------------------

if (FALSE) { # \dontrun{
seq_des = DesignSeqOneByOneKK21stepwise$new(n = 6, response_type = "continuous")
} # }