De-biased inference for the best subgroup over a large enumerated family
Source:R/guohe_algorithm3.R
guohe_algorithm3.RdFinite realization of Algorithm 3 of Guo and He (2021): the candidate family is supplied as materialized 0/1 membership columns, the most extreme oriented effect is selected, and its selection optimism is removed by a pair (case) bootstrap with deterministic shrinkage offsets computed against the global maximum. Survival, binary, and continuous outcomes are supported.
Usage
guohe_algorithm3(
data,
outcome = c("survival", "binary", "continuous"),
treatment,
candidates,
time = NULL,
event = NULL,
y = NULL,
orient = -1,
B = 2000L,
r = 0.03,
level = 0.05,
seed = NULL,
min_events = 5L,
diagnostics = TRUE,
parallel = FALSE,
adjust_covariates = NULL,
fast = NULL
)Arguments
- data
A data frame.
- outcome
One of
"survival","binary","continuous".- treatment
Name of the 0/1 treatment column.
- candidates
Character vector of names of 0/1 membership columns forming the enumerated family.
- time, event
Survival only: names of the time and event columns.
- y
Binary or continuous only: name of the outcome column.
- orient
Either
-1or+1; sign orienting the effect of interest.- B
Number of bootstrap resamples.
- r
Shrinkage tuning parameter, strictly between 0 and 0.5. Guo and He's Algorithm 2 gives a cross-validated choice; a fixed small value is used here.
- level
One-sided level; the two-sided interval has coverage
1 - level.- seed
Optional integer for reproducible resampling.
- min_events
Minimum events (survival) or minimum per-arm count for a candidate to be estimable.
- diagnostics
Logical; if
TRUE, record per-resample estimability.- parallel
Logical; if
TRUE, distribute the bootstrap model fitting withfuture.apply. Requires afuture::plan()to have been set by the caller. Results are identical toparallel = FALSEfor the sameseed, because resample indices are drawn serially before any distribution. Do NOT enable this inside an already-parallel outer loop.- adjust_covariates
This option is implemented but has not been tested against the manuscript analyses or the simulation studies of León and Anderson (2026a, 2026b), which use the unadjusted treatment-only fits. Optional character vector of covariate names for the within-subgroup model, matching the argument of the same name in
forestsearch()'s.estimate_or()/.make_lm_estimator(). DefaultNULLis the unadjusted model. Supplying it DISABLES the closed-form fast path, because an adjusted coefficient is a partial regression coefficient, not a 2x2 log-odds-ratio or a difference of arm means.NOTE:
forestsearch()has a SECOND adjustment axis,ps_adjust_method("iptw"weighted fitting,"dr_gcomp"Bang-Robins G-computation). Those modes are not implemented in this comparator, and the closed forms would be invalid under them too – IPTW fits a weighted logistic, and DR reports a marginal log-OR from G-computed probabilities; neither equals the 2x2 statistic. If the comparator is extended to those modes, thefast_okgate must be extended with them.- fast
Logical or
NULL. Closed-form evaluation of the within-subgroup effect, available only for UNADJUSTED binary and continuous outcomes. These are EXACT, not approximations: with a single binary covariate the logistic model is saturated, so its MLE is the 2x2 log-odds-ratio, and the Gaussian coefficient is the difference of arm means.NULL(default) auto-enables it whenever it is valid.TRUEerrors if the configuration makes it invalid (survival, or anyadjust_covariates), rather than silently falling back.
Value
An object of class "guohe_a3": a list with the selected candidate
(selected), the naive and de-biased effects on the reporting scale
(naive, debiased), the one-sided bound of Guo and He's Algorithm 3 (bound_one_sided,
with its conservative side in bound_side), the two-sided
quantile-inversion interval (ci_two_sided), the heuristic Wald interval
(ci_wald), and bookkeeping fields (n, B, B_requested, r,
level, n_candidates, n_estimable, fast, lean_cox,
adjust_covariates, and, when diagnostics = TRUE, the per-candidate
resample drop_rate).
Details
Membership is computed once on the full data and carried through the bootstrap; cut points are NOT re-derived per resample. This is required by the method (the index set is held fixed) and is what makes the comparison against multiplier resampling like-for-like; regenerating the family per resample is the full-bootstrap object instead.
The oriented score is orient * b, with b the within-subgroup treatment
coefficient on the natural scale. orient = -1 treats a protective ratio
(HR or OR below 1) as the effect of interest, matching Guo and He's MONET1
convention; orient = +1 treats a harmful ratio as the effect of interest,
which is the setting for a forest-search harm subgroup.
This is an independent implementation of the published method, validated by reproducing the simulation study of Section 5 of Guo and He (2021).
References
Guo, X. and He, X. (2021). Inference on Selected Subgroups in Clinical Trials. Journal of the American Statistical Association, 116(535), 1498–1506. doi:10.1080/01621459.2020.1740096
Examples
set.seed(1)
n <- 160
df <- data.frame(
treat = rbinom(n, 1, 0.5),
y = rbinom(n, 1, 0.3),
g1 = rbinom(n, 1, 0.5),
g2 = rbinom(n, 1, 0.5),
g3 = rbinom(n, 1, 0.5)
)
fit <- guohe_algorithm3(
df, outcome = "binary", treatment = "treat",
candidates = c("g1", "g2", "g3"), y = "y",
orient = +1, B = 50, seed = 2
)
fit
#> Guo-He Algorithm 3 (enumerated family) [binary, orient = +1]
#> family : 3 candidates (3 estimable), n = 160
#> selected : g2
#> naive odds ratio : 0.8418
#> de-biased odds ratio : 0.6606
#> lower bound (one-sided, 0.950) : 0.2934 [Guo-He bound]
#> two-sided CI (0.95, quantile inversion): (0.2527, 1.6409) [EXTENSION]
#> Wald CI (0.95, Zhao-style) : (0.2424, 1.8001) [HEURISTIC]
#> B = 50, r = 0.030
#> resample drop-out: none