
A Sequential Permuted-Block Design with Randomly Varying Block Sizes
Source:R/design_seq_one_by_one_random_block_size.R
DesignSeqOneByOneRandomBlockSize.RdA DesignSeqOneByOne implementing permuted-block
randomization with randomly varying block size: subjects are assigned from a queue
of pre-shuffled treatment labels (a "block"), refilled with a fresh
sampled block whenever it empties. Each new block's size is
itself drawn uniformly at random from block_sizes (rather than being fixed),
and each block internally contains exactly round(block_size * prob_T) treated
and block_size - round(block_size * prob_T) control labels in random order.
Randomizing the block size (rather than using a single fixed block length, as in
classical permuted-block designs) is a standard clinical-trials safeguard against
selection bias: with a fixed, known block size, unblinded staff could
predict the last assignment(s) in a block from the ones already observed, whereas an
unpredictable block size makes this much harder while still guaranteeing
near-perfect treatment/control balance throughout enrollment (balance is exact at
every block boundary and never worse than one full block's imbalance in between). If
strata_cols is supplied, a separate independent sequence of blocks is
maintained per stratum (one queue per distinct combination of strata_cols
values), so balance holds within each stratum, not just overall.
Block-size / prob_T compatibility. Every entry of block_sizes
must yield an integer number of treated subjects when multiplied by prob_T
(checked at construction: abs(bs * prob_T - round(bs * prob_T)) <= 1e-10 for
every bs); a block size that would require a fractional number of treated
subjects is rejected.
Per-stratum queues. private$strata_states is a hashed environment
mapping each stratum key (or the literal key "overall" when
strata_cols is NULL) to the vector of not-yet-used assignments
remaining in that stratum's current block; assign_wt() pops the next
assignment from the relevant queue, refilling it with a freshly drawn block (random
size, randomly ordered) whenever it is empty.
Bootstrap. draw_bootstrap_indices() resamples within strata (via
stratified_bootstrap_indices_cpp()) when strata_cols is supplied, or
performs a plain i.i.d. nonparametric bootstrap over subjects otherwise.
References
Efron, B. (1971). "Forcing a sequential experiment to be balanced." Biometrika, 58(3), 403-417, doi:10.1093/biomet/58.3.403 , for sequential balanced-block randomization background. See also block randomisation for orientation on permuted-block designs and the selection-bias rationale for varying block size.
Super classes
Design -> DesignSeqOneByOne -> DesignSeqOneByOneRandomBlockSize
Methods
+ inherited public methods from DesignSeqOneByOne
+ inherited public methods from Design
Design$add_all_subject_responses()Design$add_one_subject_response()Design$any_censoring()Design$applicable_inference_class_names()Design$assert_all_responses_recorded()Design$assert_all_subjects_arrived()Design$assert_even_allocation()Design$assert_fixed_sample()Design$capabilities()Design$check_experiment_completed()Design$draw_ws_according_to_design()Design$duplicate()Design$get_X()Design$get_X_imp()Design$get_X_raw()Design$get_design_formula()Design$get_edi_version_created()Design$get_effective_dead()Design$get_effective_time()Design$get_missingness_method()Design$get_n()Design$get_ordinal_levels()Design$get_original_ordinal_levels()Design$get_prob_T()Design$get_response_type()Design$get_response_type_original()Design$get_t()Design$get_w()Design$get_y()Design$get_y_L()Design$get_y_R()Design$get_y_original()Design$has_general_censoring()Design$incompatible_inference_classes_due_to_design_structure()Design$is_a_bernoulli_capable()Design$is_a_cluster_capable()Design$is_a_kk_matching_capable()Design$is_blocking_design()Design$is_fixed_sample_size()Design$is_matching_design()Design$overwrite_all_subject_assignments()Design$prepare_for_resampling_replay()Design$randomization_family()Design$supports()Design$supports_randomization_draw()Design$supports_resampling()Design$supports_resampling_replay()Design$transform_y()Design$unavailable_inference_classes_due_to_missing_packages()Design$warm_all_subject_data_cache()
DesignSeqOneByOneRandomBlockSize$new()
Initialize a sequential permuted-block experimental design with randomly varying block size (see class documentation for the exact block-refill rule and its selection-bias rationale).
Usage
DesignSeqOneByOneRandomBlockSize$new(
strata_cols = NULL,
block_sizes = c(4, 6, 8),
response_type,
prob_T = 0.5,
include_is_missing_as_a_new_feature = TRUE,
n = NULL,
verbose = FALSE,
missingness_method = "impute",
design_formula = ~.,
seed = NULL
)Arguments
strata_colsA character vector of column names to use for stratification. If NULL, simple blocking is used.
block_sizesA vector of positive integers representing the possible block sizes to choose from. Each must be a multiple of the inverse of
prob_Tto ensure integer treatment/control counts.response_typeThe data type of response values which must be one of the following: "continuous", "incidence", "proportion", "count", "survival", "ordinal".
prob_TThe probability of the treatment assignment. This defaults to
0.5.include_is_missing_as_a_new_featureIf missing data is present in a variable, should we include another dummy variable for its missingness? Default is
TRUE.nThe sample size (if fixed). Default is
NULLfor not fixed.verboseA flag indicating whether messages should be displayed. Default is
FALSE.missingness_methodHow to handle missing values in covariates.
design_formulaA formula object.
seedInteger seed for reproducibility.
DesignSeqOneByOneRandomBlockSize$assign_wt()
Pop the next treatment assignment from the current subject's stratum block queue (see class documentation), refilling that queue with a freshly drawn random-size, randomly-ordered block first if it is empty.
Examples
seq_des = DesignSeqOneByOneRandomBlockSize$new(n = 6, response_type = 'continuous')
seq_des$add_one_subject_to_experiment_and_assign(data.frame(x1 = rnorm(1)))
#> [1] 0