Nothing
library(fdid)
# ===========================================================================
# CRAN-facing tests
# Tiny synthetic panel (40 units × 3 periods = 120 rows).
# Uses only the two fastest estimators (did, ols1) with no bootstrap.
# Designed to run in < 5 seconds on a single core.
# ===========================================================================
set.seed(42)
n_units <- 40
times <- 1:3
cran_data <- data.frame(
id = rep(seq_len(n_units), each = length(times)),
time = rep(times, times = n_units),
G = rep(rep(c(0L, 1L), n_units / 2), each = length(times)),
outcome = rnorm(n_units * length(times)),
covar1 = rnorm(n_units * length(times)),
covar2 = rnorm(n_units * length(times))
)
s_cran <- fdid_prepare(
data = cran_data,
Y_label = "outcome",
X_labels = c("covar1", "covar2"),
G_label = "G",
unit_label = "id",
time_label = "time"
)
test_that("[CRAN] fdid_prepare returns expected structure", {
expect_s3_class(s_cran, "tbl_df")
expect_true("G" %in% names(s_cran))
expect_true("unit" %in% names(s_cran))
expect_true(any(grepl("^Y_", names(s_cran))))
expect_true(any(grepl("^x", names(s_cran))))
})
test_that("[CRAN] fdid: did", {
res <- fdid(s_cran, tr_period = 2L, ref_period = 1L, method = "did", vartype = "robust")
expect_s3_class(res, "fdid")
expect_equal(res$method, "did")
expect_true(is.finite(res$est$event$Estimate))
})
test_that("[CRAN] fdid: ols1", {
res <- fdid(s_cran, tr_period = 2L, ref_period = 1L, method = "ols1", vartype = "robust")
expect_s3_class(res, "fdid")
expect_equal(res$method, "ols1")
expect_true(is.finite(res$est$event$Estimate))
})
test_that("[CRAN] fdid_list bundles results", {
r1 <- fdid(s_cran, tr_period = 2L, ref_period = 1L, method = "did", vartype = "robust")
r2 <- fdid(s_cran, tr_period = 2L, ref_period = 1L, method = "ols1", vartype = "robust")
fl <- fdid_list(r1, r2)
expect_s3_class(fl, "fdid_list")
expect_length(fl, 2L)
})
test_that("[CRAN] summary and print run without error", {
res <- fdid(s_cran, tr_period = 2L, ref_period = 1L, method = "did", vartype = "robust")
expect_output(summary(res))
expect_output(print(res))
})
test_that("[CRAN] plot.fdid: raw and dynamic run without error", {
res <- fdid(s_cran, tr_period = 2L, ref_period = 1L, method = "ols1", vartype = "robust")
expect_invisible(plot(res, type = "raw"))
expect_invisible(plot(res, type = "dynamic"))
})
# ===========================================================================
# Full internal tests (skipped on CRAN)
# Uses the real mortality dataset and all six estimators.
# ===========================================================================
data(fdid)
mortality$uniqueid <- paste(mortality$provid, mortality$countyid, sep = "-")
mortality$G <- ifelse(mortality$pczupu >= median(mortality$pczupu, na.rm = TRUE), 1, 0)
s <- fdid_prepare(
data = mortality,
Y_label = "mortality",
X_labels = c("avggrain", "lnpop"),
G_label = "G",
unit_label = "uniqueid",
time_label = "year"
)
TR <- 1958
REF <- 1957
# Helper: basic structural checks on any fdid result
check_fdid <- function(res, method_name) {
expect_s3_class(res, "fdid")
expect_named(res, c("est", "dynamic", "raw_means", "tr_period", "ref_period",
"entire_period", "method", "vartype", "times", "G", "ps",
"call", "target.pop"),
ignore.order = TRUE)
expect_equal(res$method, method_name)
expect_true(is.finite(res$est$event$Estimate),
label = paste(method_name, "event estimate is finite"))
expect_true(is.finite(res$est$event$Std.Error),
label = paste(method_name, "event SE is finite"))
expect_true(nrow(res$dynamic) > 0,
label = paste(method_name, "dynamic estimates non-empty"))
}
# ---------------------------------------------------------------------------
test_that("fdid_prepare returns expected structure", {
skip_on_cran()
expect_s3_class(s, "tbl_df")
expect_true("G" %in% names(s))
expect_true("unit" %in% names(s))
expect_true(any(grepl("^Y_", names(s))))
expect_true(any(grepl("^x", names(s))))
})
# ---------------------------------------------------------------------------
test_that("fdid: did", {
skip_on_cran()
res <- fdid(s, tr_period = TR, ref_period = REF, method = "did", vartype = "robust")
check_fdid(res, "did")
})
test_that("fdid: ols1", {
skip_on_cran()
res <- fdid(s, tr_period = TR, ref_period = REF, method = "ols1", vartype = "robust")
check_fdid(res, "ols1")
})
test_that("fdid: ols2", {
skip_on_cran()
res <- fdid(s, tr_period = TR, ref_period = REF, method = "ols2", vartype = "robust")
check_fdid(res, "ols2")
})
test_that("fdid: ebal (targets G=1)", {
skip_on_cran()
res <- fdid(s, tr_period = TR, ref_period = REF, method = "ebal",
vartype = "robust", target.pop = "1")
check_fdid(res, "ebal")
})
test_that("fdid: ipw", {
skip_on_cran()
res <- fdid(s, tr_period = TR, ref_period = REF, method = "ipw", vartype = "robust")
check_fdid(res, "ipw")
expect_false(is.null(res$ps), label = "ipw returns propensity scores")
})
test_that("fdid: aipw", {
skip_on_cran()
res <- fdid(s, tr_period = TR, ref_period = REF, method = "aipw", vartype = "robust")
check_fdid(res, "aipw")
expect_false(is.null(res$ps), label = "aipw returns propensity scores")
})
# ---------------------------------------------------------------------------
test_that("target.pop shifts estimates for ols2", {
skip_on_cran()
all_ <- fdid(s, tr_period = TR, ref_period = REF, method = "ols2",
vartype = "robust", target.pop = "all")
att <- fdid(s, tr_period = TR, ref_period = REF, method = "ols2",
vartype = "robust", target.pop = "1")
atc <- fdid(s, tr_period = TR, ref_period = REF, method = "ols2",
vartype = "robust", target.pop = "0")
# Estimates need not be identical across target populations
expect_false(isTRUE(all.equal(all_$est$event$Estimate, att$est$event$Estimate)) &&
isTRUE(all.equal(all_$est$event$Estimate, atc$est$event$Estimate)),
label = "ols2 target.pop changes the estimate")
})
# ---------------------------------------------------------------------------
test_that("did and ols1 are unaffected by target.pop", {
skip_on_cran()
r_all <- fdid(s, tr_period = TR, ref_period = REF, method = "did",
vartype = "robust", target.pop = "all")
r_att <- fdid(s, tr_period = TR, ref_period = REF, method = "did",
vartype = "robust", target.pop = "1")
expect_equal(r_all$est$event$Estimate, r_att$est$event$Estimate,
tolerance = 1e-10,
label = "did estimate same across target.pop")
})
# ---------------------------------------------------------------------------
test_that("entire_period restricts dynamic output", {
skip_on_cran()
res <- fdid(s, tr_period = TR, ref_period = REF, method = "ols1",
vartype = "robust", entire_period = c(1957, 1958, 1959))
expect_equal(sort(res$entire_period), c(1957, 1958, 1959))
expect_equal(nrow(res$dynamic), 3L)
})
# ---------------------------------------------------------------------------
test_that("fdid_list bundles multiple results", {
skip_on_cran()
r1 <- fdid(s, tr_period = TR, ref_period = REF, method = "did", vartype = "robust")
r2 <- fdid(s, tr_period = TR, ref_period = REF, method = "ols1", vartype = "robust")
fl <- fdid_list(r1, r2)
expect_s3_class(fl, "fdid_list")
expect_length(fl, 2L)
})
# ---------------------------------------------------------------------------
test_that("summary.fdid runs without error", {
skip_on_cran()
res <- fdid(s, tr_period = TR, ref_period = REF, method = "ols1", vartype = "robust")
expect_output(summary(res))
})
test_that("print.fdid runs without error", {
skip_on_cran()
res <- fdid(s, tr_period = TR, ref_period = REF, method = "ols1", vartype = "robust")
expect_output(print(res))
})
# ---------------------------------------------------------------------------
test_that("plot.fdid: raw and dynamic run without error", {
skip_on_cran()
res <- fdid(s, tr_period = TR, ref_period = REF, method = "ols1", vartype = "robust")
expect_invisible(plot(res, type = "raw"))
expect_invisible(plot(res, type = "dynamic"))
})
test_that("plot.fdid: overlap requires ipw/aipw", {
skip_on_cran()
res_aipw <- fdid(s, tr_period = TR, ref_period = REF, method = "aipw", vartype = "robust")
expect_invisible(plot(res_aipw, type = "overlap"))
})
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.