Skip to contents

A fixed-sample-size DesignFixed that (1) partitions the \(n\) subjects into \(n/2\) disjoint matched pairs by solving a non-bipartite (optimal) pairwise-matching problem on a covariate distance matrix, minimizing the total within-pair distance across all pairs, then (2) randomizes treatment within each pair independently: for pair \(k\), one of its two members is assigned to treatment and the other to control with probability \(1/2\) each, independently across pairs. This is the classical matched-pair randomized design (a special case of blocking with block size 2), which guarantees exact covariate balance within every pair (up to the matching algorithm's distance metric) while preserving randomization-based inference validity, in contrast to DesignFixedGreedyDOptimal, which balance the covariates in aggregate via an optimality criterion but do not guarantee pairwise closeness of any two subjects.

Matching algorithm. Pairing is computed once (lazily, on first call to draw_ws_raw()/assign_w_to_all_subjects(), via private$ensure_matching_structure_computed()) by compute_binary_match_structure(), which forms an \(n \times n\) pairwise distance matrix — squared Mahalanobis distance if mahal_match = TRUE (the default; using the sample covariance of the covariates, ridge-regularized if singular), or squared Euclidean distance otherwise — and solves the minimum-weight non-bipartite perfect matching on that distance matrix via nonbimatch (nbpMatching, a Suggests-only dependency; loading is deferred until matching is actually needed, so pre-computed w vectors injected via m never require it). For a single covariate (\(p = 1\)), pairing instead reduces to simply sorting subjects by that covariate and pairing consecutive subjects, since the non-bipartite matching problem is trivial in one dimension. The resulting pairing is cached in private$bms/private$m for the lifetime of the design object (or until explicitly reset via set_m()) and is not recomputed per draw.

Within-pair randomization. Given the fixed pairing, each replicate allocation (see draw_binary_match_assignments_cpp()) independently flips, for every pair, which of its two members is treated (an independent fair coin flip per pair per replicate, using a splitmix64-seeded Mersenne Twister per replicate column for reproducible parallel draws); this guarantees exactly \(n/2\) treated subjects overall (only prob_T = 0.5 is supported; the constructor errors otherwise). Passing a pre-computed m to the constructor supplies the matched-pair structure directly (each pair ID occurring in exactly 2 rows), bypassing the matching computation entirely while keeping the same within-pair randomization.

No-covariate fallback. If no covariates are available at draw time (private$m is NULL, e.g. matching hasn't run and no explicit m was supplied), draw_ws_raw() falls back to an unmatched balanced complete randomization (a uniformly random permutation of \(n/2\) ones and \(n/2\) zeros), since there is no covariate information to match on.

Batch pregeneration. draw_binary_match_assignments_cpp()'s output is trusted unvalidated – it guarantees exactly n x r valid \(\{0,1\}\) columns with \(n/2\) treated subjects per column by construction (see fix_design_hierarchy.md, "AllocationMatrixValidation"). supports_batch_w_pregeneration() returns TRUE so that the calling framework generates all replicate w vectors for a simulation cell in one batch (amortizing the one-time nbpMatching matching cost across all replicates of that cell) rather than recomputing the matching structure per replicate.

References

Greevy, R., Lu, B., Silber, J. H., and Rosenbaum, P. (2004). "Optimal multivariate matching before randomization." Biostatistics, 5(2), 263-275, doi:10.1093/biostatistics/5.2.263 , for optimal non-bipartite matched-pair designs prior to randomization. See also matched pair and Mahalanobis distance for orientation.

Super classes

Design -> DesignFixed -> DesignFixedBinaryMatch

Methods

+ inherited public methods from DesignFixed
+ inherited public methods from Design


DesignFixedBinaryMatch$is_a_kk_matching_capable()

Characterization: this design computes its matched-pair structure on the fly from covariates (see class documentation), so it is KK matching-capable by construction.

Usage

DesignFixedBinaryMatch$is_a_kk_matching_capable()

Returns

Always TRUE for this class.


DesignFixedBinaryMatch$supports_batch_w_pregeneration()

Returns TRUE so the calling framework pre-generates all replicate w vectors for a simulation cell in one batch, paying the one-time nbpMatching non-bipartite matching cost once per cell and reusing the resulting pairing across all replicates, rather than recomputing it per replicate.

Usage

DesignFixedBinaryMatch$supports_batch_w_pregeneration()

Returns

Always TRUE for this class.


DesignFixedBinaryMatch$new()

Initialize a binary (non-bipartite) matched-pair fixed experimental design. Matching itself is deferred until the first draw (see class documentation); this constructor only records configuration and, if m is supplied, installs the explicit pairing immediately.

Usage

DesignFixedBinaryMatch$new(
  response_type,
  prob_T = 0.5,
  mahal_match = TRUE,
  include_is_missing_as_a_new_feature = TRUE,
  n = NULL,
  m = NULL,
  verbose = FALSE,
  missingness_method = "impute",
  design_formula = ~.,
  seed = NULL
)

Arguments

response_type

The data type of response values.

prob_T

The probability of the treatment assignment. Must be 0.5, since within-pair randomization only supports an even 1-treated/1-control split per pair.

mahal_match

Match using squared Mahalanobis distance (accounting for covariate correlation/scale) if TRUE (default), else squared Euclidean distance on the raw covariate matrix.

include_is_missing_as_a_new_feature

Flag for missingness indicators.

n

The sample size.

m

Optional integer vector of explicit matched-pair identifiers, one per subject. If supplied, `n` must also be supplied, `length(m)` must equal `n`, all values must be positive, and each pair ID must occur exactly twice. This bypasses the package-computed matching step.

verbose

Flag for verbosity.

missingness_method

How to handle missing values in covariates.

design_formula

A formula object.

seed

Integer seed for reproducibility.

Returns

A new `DesignFixedBinaryMatch` object


DesignFixedBinaryMatch$assign_w_to_all_subjects()

Assign treatment to all subjects (see DesignFixed$assign_w_to_all_subjects() for the general contract). Before delegating, this override ensures the matched-pair structure is computed (private$ensure_matching_structure_computed()) even when w_precomputed is supplied and draw_ws_according_to_design() is therefore never called — downstream code (e.g. blocked/matched-pair inference) still needs private$m to be populated regardless of how w was obtained.

Usage

DesignFixedBinaryMatch$assign_w_to_all_subjects(w_precomputed = NULL)

Arguments

w_precomputed

Optional {0,1} numeric vector of length n. If supplied, it is used directly as the treatment allocation instead of drawing a fresh within-pair-randomized allocation.


DesignFixedBinaryMatch$clone()

The objects of this class are cloneable with this method.

Usage

DesignFixedBinaryMatch$clone(deep = FALSE)

Arguments

deep

Whether to make a deep clone.

Examples

des = DesignFixedBinaryMatch$new(n = 10, response_type = 'continuous')
des$add_all_subjects_to_experiment(data.frame(x1 = rnorm(10)))
des$assign_w_to_all_subjects()