Learn R Programming

HOIFCar (version 1.1.1)

fit.adj2.adj2c.CAR: Covariate-Adjusted Treatment Effect Estimation under Covariate-Adaptive randomization

Description

Implements HOIF-inspired debiased estimators for average treatment effect (ATE) or treatment effect on the treatment/control arm with variance estimation using estimated asymptotic variance. Designed for randomized experiments with moderately high-dimensional covariates.

Usage

fit.adj2.adj2c.CAR(Y, X, S, A, intercept = TRUE, pi1 = NULL, target = "ATE")

Value

A list containing two named vectors, including point estimates and variance estimates:

tau_vec

Point estimates:

  • adj2: Point estimation of the HOIF-inspired debiased estimator (Gu et al., 2025).

  • adj2c: Same as adj2, but incorporating the centering step from Zhao et al. (2024) and Lu et al. (2023).

var_vec

Variance estimates:

  • adj2: Variance for adj2 via the sample variance of its asymptotic variance formula.

  • adj2c: Variance for adj2c via the sample variance of its asymptotic variance formula.

Arguments

Y

Numeric vector of length n containing observed responses.

X

Numeric matrix (n x p) of covariates. Centering is required. May include intercept column.

S

Vector of length n denoting strata used in randomization procedure. Either a factor or an integer-valued numeric vector indexed from 1 to K.

A

Binary vector of length n indicating treatment assignment (1 = treatment, 0 = control).

intercept

Logical. If TRUE (default), X already contains intercept. Set FALSE if X does not contain intercept.

pi1

The assignment probability for the randomization assignment. If `NULL` (the default), the empirical assignment probability is used. Should be a vector with length K (Number of strata).

target

A character string specifying the target estimand. Must be one of: - `"ATE"` (default): Average Treatment Effect (difference between treatment and control arms). - `"EY1"`: Expected outcome under treatment (estimates the effect for the treated group). - `"EY0"`: Expected outcome under control (estimates the effect for the control group).

References

Gu, Y., Liu, L. and Ma, W. (2025) Assumption-lean covariate adjustment under covariate adaptive randomization when p = o (n). arXiv preprint, arXiv:2512.20046, tools:::Rd_expr_doi("10.48550/arXiv.2512.20046").
Lu, X., Yang, F. and Wang, Y. (2023) Debiased regression adjustment in completely randomized experiments with moderately high-dimensional covariates. arXiv preprint, arXiv:2309.02073, tools:::Rd_expr_doi("10.48550/arXiv.2309.02073").
Zhao, S., Wang, X., Liu, L. and Zhang, X. (2024) Covariate Adjustment in Randomized Experiments Motivated by Higher-Order Influence Functions. arXiv preprint, arXiv:2411.08491, tools:::Rd_expr_doi("10.48550/arXiv.2411.08491").

Examples

Run this code

set.seed(120)
alpha0 <- 0.1;
n <- 400;
S <- as.factor(sample(c("0-30","31-50",">50"),n,replace = TRUE,prob=c(0.2,0.4,0.4)))
ns_min = min(table(S))

p0 <- ceiling(ns_min * alpha0)
beta0_full <- 1 / (1:p0) ^ (1 / 2) * (-1) ^ c(1:p0)
beta <- beta0_full / norm(beta0_full,type='2')

Sigma_true <- matrix(0, nrow = p0, ncol = p0)
for (i in 1:p0) {
  for (j in 1:p0) {
    Sigma_true[i, j] <- 0.1 ** (abs(i - j))
  }
}

X <- mvtnorm::rmvt(n, sigma = Sigma_true, df = 3)

lp0 <- X %*% beta
delta_X <- 1  -  1/4 * X[, 2] -  1/8 * X[, 3]
lp1 <- lp0 + delta_X

Y0 <- lp0 + rnorm(n)
Y1 <- lp1 + rnorm(n)


pi1 <- 1 / 2

# We use stratified block randomization as an example. Simple randomization
# is also valid by setting S = rep(1,n) and A = rbinom(n,1,pi1)

sbr <- function(S,nA,p,block_size=10){
  N <- length(S)
  B <- block_size
  A <- rep(0,N)
  nS <- length(unique(S))
  for(s in 1:nS){
    ind_s <- which(S==s)
    n_s <- length(ind_s)
    A_s <- rep(0,n_s)
    numB <- floor(n_s/B)
    rem <- n_s - numB*B
    size_A <- B*p[s]
    if(numB==0){
      size_rem = floor(rem*p[s])
      size_rem[1] = rem - sum(size_rem[-1])
      A_s[(B*numB+1):n_s] <- sample(rep(0:(nA-1),size_rem),size=rem,replace = FALSE)
    }else{
      for(i in 1:numB){
        A_s[(B*(i-1)+1):(B*i)] <- sample(rep(0:(nA-1),size_A),size=B,replace = FALSE)
      }
      if(rem>0){
        size_rem = floor(rem*p[s])
        size_rem[1] = rem - sum(size_rem[-1])
        A_s[(B*numB+1):n_s] <- sample(rep(0:(nA-1),size_rem),size=rem,replace = FALSE)
      }
    }
    A[ind_s] <- A_s
  }
  return(A)
}


A <- sbr(as.numeric(S),2,rep(pi1,3),block_size = 4)

Y <- A * Y1 + (1 - A) * Y0

Xc <- cbind(1, scale(X, scale = FALSE))
result.adj2.adj2c.car.ate.ls <- fit.adj2.adj2c.CAR(Y, Xc,S, A, intercept = TRUE,
                                                   target = 'ATE')
result.adj2.adj2c.car.ate.ls
result.adj2.adj2c.car.treat.ls <- fit.adj2.adj2c.CAR(Y, Xc,S, A, intercept = TRUE,
                                                     target = 'EY1')
result.adj2.adj2c.car.treat.ls
result.adj2.adj2c.car.control.ls <- fit.adj2.adj2c.CAR(Y, Xc,S, A, intercept = TRUE,
                                                       target = 'EY0')
result.adj2.adj2c.car.control.ls

Run the code above in your browser using DataLab