test_that("test heteroskedastic boottest against fixest", {
#' @srrstats {G5.4} **Correctness tests** *to test that statistical algorithms
#' produce expected results to some fixed test data sets (potentially through
#' comparisons using binding frameworks such as
#' [RStata](https://github.com/lbraglia/RStata)).* Several correctness
#' tests are implemented. First, it is tested if the non-bootstrapped
#' t-statistics
#' produced via boottest() *exactly* match those computed by the fixest package
#' (see test_tstat_equivalence). Second, `fwildclusterboot` is heavily tested
#' against `WildBootTests.jl` - see "test-r-vs-julia". Last, multiple R
#' implementations of the WCB are tested against each other.
set.seed(96578)
dqrng::dqset.seed(9568)
data1 <<- fwildclusterboot:::create_data(
N = 1000,
N_G1 = 1000,
icc1 = 0.5,
N_G2 = 10,
icc2 = 0.01,
numb_fe1 = 10,
numb_fe2 = 10,
seed = 2293
)
lm_fit <- lm(proposition_vote ~ treatment + ideology1 + log_income,
data = data1
)
feols_fit <- fixest::feols(
proposition_vote ~ treatment + ideology1 + log_income,
data = data1
)
felm_fit <- lfe::felm(proposition_vote ~ treatment + ideology1 + log_income,
data = data1
)
# Test 1: heteroskedadestic wild bootstrap
set.seed(96578)
dqrng::dqset.seed(9568)
boot_lm <- boottest(lm_fit,
param = "treatment",
B = 999,
ssc = boot_ssc(adj = FALSE, cluster.adj = FALSE),
nthreads = 1,
type = "webb"
)
set.seed(96578)
dqrng::dqset.seed(9568)
boot_lm2 <- boottest(lm_fit,
param = "treatment",
B = 999,
ssc = boot_ssc(adj = FALSE, cluster.adj = FALSE),
nthreads = 1,
type = "webb"
)
set.seed(96578)
dqrng::dqset.seed(9568)
boot_feols <- boottest(feols_fit,
param = "treatment",
B = 9999,
ssc = boot_ssc(adj = FALSE, cluster.adj = FALSE),
nthreads = 1
)
set.seed(96578)
dqrng::dqset.seed(9568)
boot_felm <- boottest(felm_fit,
param = "treatment",
B = 9999,
ssc = boot_ssc(adj = FALSE, cluster.adj = FALSE),
nthreads = 1
)
# 2.155239
res <- broom::tidy(
lmtest::coeftest(
lm_fit,
sandwich::vcovHC(lm_fit, type = "HC0")
)
)[2, 4:5]
expect_equal(res$statistic, boot_lm$t_stat)
expect_equal(res$statistic, boot_feols$t_stat)
expect_equal(res$statistic, boot_felm$t_stat)
expect_equal(res$p.value, boot_lm$p_val, tolerance = 0.05)
expect_equal(res$p.value, boot_feols$p_val, tolerance = 0.05)
expect_equal(res$p.value, boot_felm$p_val, tolerance = 0.05)
# HC1
boot_lm <- boottest(lm_fit,
param = "treatment",
B = 9999,
ssc = boot_ssc(adj = TRUE, cluster.adj = FALSE),
nthreads = 1
)
boot_feols <- boottest(feols_fit,
param = "treatment",
B = 9999,
ssc = boot_ssc(adj = TRUE, cluster.adj = FALSE),
nthreads = 1
)
boot_felm <- boottest(felm_fit,
param = "treatment",
B = 9999,
ssc = boot_ssc(adj = TRUE, cluster.adj = FALSE),
nthreads = 1
)
res <- broom::tidy(
lmtest::coeftest(
lm_fit,
sandwich::vcovHC(lm_fit, type = "HC1")
)
)[2, 4:5]
k <- length(coef(lm_fit))
N <- nobs(lm_fit)
# HC1 in sandwich : t / sqrt(n / (n -k))
# in fwildclusterboot: t / sqrt((n-1) / n-k)
ssc_corr <- (N - 1) / N
expect_equal(res$statistic / sqrt(ssc_corr), boot_lm$t_stat)
expect_equal(res$statistic / sqrt(ssc_corr), boot_feols$t_stat)
expect_equal(res$statistic / sqrt(ssc_corr), boot_felm$t_stat)
expect_equal(res$p.value, pval(boot_lm), tolerance = 0.05)
expect_equal(res$p.value, pval(boot_feols), tolerance = 0.05)
expect_equal(res$p.value, pval(boot_felm), tolerance = 0.05)
# test oneway clustering
boot_lm1 <- boottest(feols_fit,
param = "treatment",
clustid = "group_id1",
B = 2999,
engine = "R-lean",
nthreads = 1,
ssc = boot_ssc(
adj = FALSE,
cluster.adj = FALSE
)
)
boot_lm2 <- boottest(lm_fit,
param = "treatment",
clustid = "group_id1",
B = 2999,
engine = "R",
nthreads = 1,
ssc = boot_ssc(
adj = FALSE,
cluster.adj = FALSE
)
)
# pracma::toc()
expect_equal(pval(boot_lm1), pval(boot_lm2), tolerance = 0.05)
expect_equal(teststat(boot_lm1), teststat(boot_lm2))
boot_lm1 <- boottest(feols_fit,
param = "treatment",
clustid = "group_id1",
B = 9999,
engine = "R-lean",
nthreads = 1
)
boot_lm2 <- boottest(feols_fit,
param = "treatment",
clustid = "group_id1",
B = 9999,
engine = "R",
nthreads = 1
)
expect_equal(pval(boot_lm1), pval(boot_lm2), tolerance = 0.05)
expect_equal(teststat(boot_lm1), teststat(boot_lm2))
# test for non-standard hypotheses
})
test_that("heteroskedastic multi-param tests", {
N <- 2000
seed <- 7896
data1 <<- fwildclusterboot:::create_data(
N = N,
N_G1 = 8,
icc1 = 0.5,
N_G2 = 20,
icc2 = 0.2,
numb_fe1 = 10,
numb_fe2 = 10,
seed = seed,
weights = 1:N / N
)
lm_fit <- lm(proposition_vote ~ treatment + log_income,
data = data1
)
boot <- suppressWarnings(
boottest(
lm_fit,
B = 999,
param = c("treatment", "log_income"),
R = c(-0.1, 0.1),
r = -0.1,
conf_int = FALSE,
ssc = boot_ssc(adj = FALSE, cluster.adj = FALSE)
)
)
X <- model.matrix(lm_fit)
u <- resid(lm_fit)
y <- model.response(model.frame(lm_fit))
Omega <- diag(tcrossprod(u))
tXX <- solve(crossprod(X))
N <- nobs(lm_fit)
vcov <- tXX %*% (t(X) %*% diag(Omega) %*% X) %*% tXX
R <- c(0, -0.1, 0.1)
r <- -0.1
beta <- coef(lm_fit)
t <- (R %*% beta - r) / sqrt(t(R) %*% vcov %*% R)
expect_equal(c(t), teststat(boot))
})
test_that("heteroskedastic 11 vs 21 vs 31", {
lm_fit <-
lm(
proposition_vote ~ treatment + ideology1 + log_income,
data = fwildclusterboot:::create_data(
N = 1000,
N_G1 = 20,
icc1 = 0.81,
N_G2 = 10,
icc2 = 0.01,
numb_fe1 = 10,
numb_fe2 = 10,
seed = 12412
)
)
fit11 <-
boottest(
lm_fit,
param = "treatment",
bootstrap_type = "11",
B = 9999,
)
fit12 <-
boottest(
lm_fit,
param = "treatment",
bootstrap_type = "21",
B = 9999,
)
fit13 <-
boottest(
lm_fit,
param = "treatment",
bootstrap_type = "31",
B = 9999,
)
expect_equal(teststat(fit11), teststat(fit12))
expect_equal(teststat(fit12), teststat(fit13))
expect_equal(pval(fit11), pval(fit12), tolerance = 0.02)
expect_equal(pval(fit12), pval(fit13), tolerance = 0.02)
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.