Skip to content

Instantly share code, notes, and snippets.

@carlislerainey
Created February 26, 2026 16:38
Show Gist options
  • Select an option

  • Save carlislerainey/18d718cde4120e1d2936e9c2d5ef90c3 to your computer and use it in GitHub Desktop.

Select an option

Save carlislerainey/18d718cde4120e1d2936e9c2d5ef90c3 to your computer and use it in GitHub Desktop.
Undercoverage due to SOP
# Coverage of the narrowest 10% of 90% CIs (HC2 SEs, Wald)
# Normal-linear model, N = 20, balanced assignment to treatment/control
library(sandwich)
set.seed(1234)
n_sims <- 10000
n <- 20
beta <- 0.5 # true treatment effect
treatment <- rep(0:1, each = n / 2)
z_crit <- qnorm(0.95)
# storage
est <- ci_lower <- ci_upper <- ci_width <- numeric(n_sims)
for (i in seq_len(n_sims)) {
y <- beta * treatment + rnorm(n)
fit <- lm(y ~ treatment)
# HC2 standard error for treatment coefficient
se_hc2 <- sqrt(vcovHC(fit, type = "HC2")[2, 2])
# Wald 90% CI
est[i] <- coef(fit)["treatment"]
ci_lower[i] <- est[i] - z_crit * se_hc2
ci_upper[i] <- est[i] + z_crit * se_hc2
ci_width[i] <- 2 * z_crit * se_hc2
}
covers <- (ci_lower <= beta) & (ci_upper >= beta)
# overall coverage
cat("Overall coverage:", mean(covers), "\n")
# narrowest 10%
cutoff <- quantile(ci_width, 0.10)
narrow <- ci_width <= cutoff
cat("Narrowest 10% coverage:", mean(covers[narrow]), "\n")
cat("N in narrowest 10%:", sum(narrow), "\n")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment