Nothing
## ---------------------------------------------------------
## Normalization regression test
## Verifies that sigma2 (est.fect) is consistent with and
## without normalize=TRUE (the sigma2 normalization bug fix)
## ---------------------------------------------------------
test_that("sigma2 is consistent with and without normalization (FE)", {
skip_on_cran()
set.seed(6001)
N <- 30
TT <- 15
T0 <- 10
Ntr <- 10
tau <- 3.0
alpha_i <- rnorm(N, 0, 1)
xi_t <- rnorm(TT, 0, 0.5)
Y_vec <- numeric(N * TT)
D_vec <- integer(N * TT)
id_vec <- integer(N * TT)
time_vec <- integer(N * TT)
idx <- 1
for (i in 1:N) {
for (t in 1:TT) {
treated <- (i <= Ntr) && (t > T0)
D_vec[idx] <- as.integer(treated)
eps <- rnorm(1, 0, 1)
Y_vec[idx] <- alpha_i[i] + xi_t[t] + tau * D_vec[idx] + eps
id_vec[idx] <- i
time_vec[idx] <- t
idx <- idx + 1
}
}
simdf <- data.frame(
id = id_vec,
time = time_vec,
Y = Y_vec,
D = D_vec
)
out_raw <- suppressWarnings(fect::fect(
Y ~ D,
data = simdf,
index = c("id", "time"),
method = "fe",
force = "two-way",
normalize = FALSE,
se = FALSE,
parallel = FALSE
))
out_norm <- suppressWarnings(fect::fect(
Y ~ D,
data = simdf,
index = c("id", "time"),
method = "fe",
force = "two-way",
normalize = TRUE,
se = FALSE,
parallel = FALSE
))
## ATT should be essentially the same
expect_equal(out_raw$att.avg, out_norm$att.avg, tolerance = 0.01,
label = "ATT should match with/without normalization")
## sigma2.fect should be close (within 10% relative error)
## This is the regression test for the normalization bug fix
if (!is.null(out_raw$sigma2.fect) && !is.null(out_norm$sigma2.fect)) {
rel_diff <- abs(out_raw$sigma2.fect - out_norm$sigma2.fect) /
max(abs(out_raw$sigma2.fect), 1e-10)
expect_lt(rel_diff, 0.1,
label = paste0("sigma2.fect relative difference = ",
round(rel_diff, 6),
" (raw=", round(out_raw$sigma2.fect, 4),
", norm=", round(out_norm$sigma2.fect, 4), ")"))
}
})
test_that("sigma2 is consistent with and without normalization (IFE)", {
skip_on_cran()
set.seed(6002)
N <- 30
TT <- 15
T0 <- 10
Ntr <- 10
tau <- 2.0
alpha_i <- rnorm(N, 0, 1)
xi_t <- rnorm(TT, 0, 0.5)
lambda_i <- rnorm(N, 0, 0.5)
f_t <- rnorm(TT, 0, 0.5)
Y_vec <- numeric(N * TT)
D_vec <- integer(N * TT)
id_vec <- integer(N * TT)
time_vec <- integer(N * TT)
idx <- 1
for (i in 1:N) {
for (t in 1:TT) {
treated <- (i <= Ntr) && (t > T0)
D_vec[idx] <- as.integer(treated)
eps <- rnorm(1, 0, 1)
Y_vec[idx] <- alpha_i[i] + xi_t[t] +
lambda_i[i] * f_t[t] +
tau * D_vec[idx] + eps
id_vec[idx] <- i
time_vec[idx] <- t
idx <- idx + 1
}
}
simdf <- data.frame(
id = id_vec,
time = time_vec,
Y = Y_vec,
D = D_vec
)
out_raw <- suppressWarnings(fect::fect(
Y ~ D,
data = simdf,
index = c("id", "time"),
method = "ife",
r = 1,
CV = FALSE,
force = "two-way",
normalize = FALSE,
se = FALSE,
parallel = FALSE
))
out_norm <- suppressWarnings(fect::fect(
Y ~ D,
data = simdf,
index = c("id", "time"),
method = "ife",
r = 1,
CV = FALSE,
force = "two-way",
normalize = TRUE,
se = FALSE,
parallel = FALSE
))
## ATT should be essentially the same
expect_equal(out_raw$att.avg, out_norm$att.avg, tolerance = 0.05,
label = "IFE ATT should match with/without normalization")
## sigma2.fect should be close
if (!is.null(out_raw$sigma2.fect) && !is.null(out_norm$sigma2.fect)) {
rel_diff <- abs(out_raw$sigma2.fect - out_norm$sigma2.fect) /
max(abs(out_raw$sigma2.fect), 1e-10)
expect_lt(rel_diff, 0.15,
label = paste0("IFE sigma2.fect relative difference = ",
round(rel_diff, 6)))
}
})
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.