
Lin (2013) Covariate-Adjusted OLS Inference for Continuous Responses
Source:R/inference_continuous_lin.R
InferenceContinLin.RdFits Lin's (2013) covariate-adjusted linear estimator for continuous
responses: OLS of \(Y_i\) on \([1, W_i, X_i^c, W_i X_i^c]\), where
\(X_i^c = X_i - \bar X\) are covariates centered at their sample means
and \(W_i X_i^c\) are treatment-by-centered-covariate interactions
(omitted when there are no covariates, reducing to plain OLS with
\(\hat\beta_T\) the simple mean difference). Centering makes
\(\hat\beta_T\) interpretable as the average treatment effect regardless
of whether interactions are included, following the design-based
reinterpretation of Freedman's critique of ANCOVA in randomized
experiments. Standard errors use the HC2 heteroskedasticity-consistent
(Huber-White-type) covariance estimator (ols_hc2_post_fit_cpp),
not classical OLS SEs assuming homoskedasticity — this is the estimator
Lin (2013) recommends since it remains conservative under treatment-effect
heterogeneity, unlike the classical or HC0 sandwich variants.
likelihood_tier = "full": Wald, score, gradient, and
likelihood-ratio tests are all available, with the parametric-likelihood
bootstrap using the OLS Gaussian-errors model
(\(Y_i \mid x_i \sim N(x_i^\top \beta, \sigma^2)\)) as the generative
null even though the design-based HC2 standard error does not itself
assume homoskedastic Gaussian errors — the likelihood-ratio/score/gradient
machinery is a secondary, model-based inference path alongside the primary
HC2-Wald and randomization paths. Validity of \(\hat\beta_T\) as an
average-treatment-effect estimator relies on randomization (of \(W\)),
not on any particular outcome model; the working linear model need not be
correctly specified.
References
Lin, W. (2013). "Agnostic notes on regression adjustments to experimental data: Reexamining Freedman's critique." The Annals of Applied Statistics, 7(1), 295-318, doi:10.1214/12-AOAS583 .
See also
InferenceContinOLS for the
uncentered, non-interacted OLS estimator this class generalizes.
Super class
Inference -> InferenceContinLin
Methods
+ inherited public methods from Inference
Inference$capabilities()Inference$compute_exact_confidence_interval()Inference$compute_exact_two_sided_pval_for_treatment_effect()Inference$duplicate()Inference$get_analysis_data()Inference$get_covariates()Inference$get_design_object()Inference$get_model_formula()Inference$get_nonestimable_reason()Inference$get_nonestimable_stage()Inference$get_optimization_alg()Inference$get_response()Inference$get_response_type()Inference$get_treatment()Inference$is_nonestimable()Inference$set_optimization_alg()Inference$set_seed()Inference$supports()
InferenceContinLin$new()
Initialize inference for Lin's (2013) covariate-adjusted OLS
estimator (intercept, treatment, centered covariates, and
treatment-by-centered-covariate interactions); see
InferenceContinLin for the model
form. Does not fit the model; the fit is deferred to the first call to
compute_estimate() or a method that requires it.
Usage
InferenceContinLin$new(
des_obj,
model_formula = NULL,
verbose = FALSE,
harden = TRUE,
smart_cold_start_default = NULL
)Arguments
des_objA completed
Designobject with a continuous response.model_formulaOptional formula for covariate adjustment. If
NULL(default), the formula from the design object is used and its pre-computed design matrix is reused. If a formula is provided, a new design matrix is constructed from the design's imputed covariates.verboseWhether to print progress messages.
hardenFlag for consistent API.
smart_cold_start_defaultFlag for consistent API.
InferenceContinLin$compute_estimate()
Fits Lin's covariate-adjusted OLS model
(stats's lm.fit on the centered-covariate design
matrix) and returns \(\hat\beta_T\), the estimated average treatment
effect. A design matrix that is rank-deficient or has fewer usable rows
than columns, or a fit with non-finite coefficients, is cached as
nonestimable rather than returned.
InferenceContinLin$compute_estimate_with_bootstrap_weights()
Refits Lin's model with subject/block-level weights applied
to a weighted least-squares fit (stats::lm.wfit) — Bayesian-bootstrap
or nonparametric-bootstrap draw weights, expanded to row level via
private$expand_subject_or_block_weights_to_row_weights() — and
returns the reweighted estimate \(\hat\beta_T^{(w)}\). When
estimate_only = FALSE, also computes a weighted-residual variance
estimate (not the HC2 estimator used by
compute_asymp_confidence_interval()) for internal bootstrap
diagnostics. Rows with non-finite or non-positive weight, or non-finite
response, are dropped from the weighted fit; if no rows remain, or the
fit fails, the estimate is NA.
InferenceContinLin$compute_asymp_confidence_interval()
Wald confidence interval for \(\beta_T\) using the HC2
heteroskedasticity-robust standard error
(ols_hc2_post_fit_cpp); see
InferenceAsymp for the shared
\(t\)/\(z\) interval contract. Fits the model first if not already
cached.
InferenceContinLin$compute_asymp_two_sided_pval()
Two-sided Wald test of \(H_0: \beta_T = \code{delta}\)
using the HC2 heteroskedasticity-robust standard error; see
InferenceAsymp for the shared
\(t\)/\(z\) test contract. Fits the model first if not already
cached.
Examples
# \donttest{
seq_des = DesignSeqOneByOneBernoulli$new(n = 10, response_type = 'continuous')
for (i in 1:10) {
seq_des$add_one_subject_to_experiment_and_assign(data.frame(x1 = rnorm(1)))
}
seq_des$add_all_subject_responses(rnorm(10))
inf = InferenceContinLin$new(seq_des)
inf$compute_estimate()
#> [1] 0.1163216
# }