context("fixest")
skip_on_cran()
skip_if_not_installed("modeltests")
library(modeltests)
skip_if_not_installed("fixest")
fixest::setFixest_nthreads(1) # avoid warnings about requesting more threads
set.seed(27)
n <- 100
df <- data.frame(
id = sample(5, n, TRUE),
v1 = sample(5, n, TRUE),
v2 = sample(1e6, n, TRUE),
v3 = sample(round(runif(100, max = 100), 4), n, TRUE),
v4 = sample(round(runif(100, max = 100), 4), n, TRUE)
)
fit <- fixest::feols(v2 ~ v3, df)
fit2 <- fixest::feols(v2 ~ v3 | id + v1, df)
form <- v2 ~ v4
fit_form <- fixest::feols(form, df) # part of a regression test
test_that("fixest tidier arguments", {
check_arguments(tidy.fixest)
check_arguments(glance.fixest)
check_arguments(augment.fixest)
})
test_that("bug #1018: fixed effects but no regressors", {
mod <- fixest::feols(Sepal.Length ~ 1 | Species, data = iris)
check_tidy_output(tidy(mod))
check_glance_outputs(glance(mod))
})
test_that("tidy.fixest", {
td <- tidy(fit)
td2 <- tidy(fit2, conf.int = TRUE)
td3 <- tidy(fit2, conf.int = TRUE, se = "hetero")
td4 <- tidy(fit_form)
check_tidy_output(td)
check_tidy_output(td2)
check_tidy_output(td3)
check_tidy_output(td4)
check_dims(td, 2, 5)
})
test_that("glance.fixest", {
gl <- glance(fit)
gl2 <- glance(fit2)
check_glance_outputs(gl, gl2)
check_dims(gl, expected_cols = 9)
})
test_that("augment.fixest", {
check_augment_function(
aug = augment.fixest,
model = fit,
data = df,
newdata = df,
strict = FALSE
)
check_augment_function(
aug = augment.fixest,
model = fit2,
data = df,
newdata = df,
strict = FALSE
)
check_augment_function(
aug = augment.fixest,
model = fit_form,
data = df,
newdata = df,
strict = FALSE
)
})
test_that("all other fixest estimators run", {
skip_on_cran()
skip_on_ci()
form <- v2 ~ v4 | id
res_feglm <- fixest::feglm(form, data = df, family = "poisson")
res_fenegbin <- fixest::fenegbin(form, data = df)
res_feNmlm <- fixest::feNmlm(form, data = df)
res_femlm <- fixest::femlm(form, data = df)
res_fepois <- fixest::fepois(form, data = df)
# Tidy
check_tidy_output(tidy(res_feglm))
check_tidy_output(tidy(res_fenegbin))
check_tidy_output(tidy(res_feNmlm))
check_tidy_output(tidy(res_femlm))
check_tidy_output(tidy(res_fepois))
# Glance
check_glance_outputs(
glance(res_feglm),
glance(res_fenegbin),
glance(res_feNmlm),
glance(res_femlm),
glance(res_fepois)
)
# augment
# Note this this causes warnings with strict=TRUE because
# modeltests:::acceptable_augment_colnames calls model.frame, which doesn't
# work for fixest models.
check_augment_function(
aug = augment.fixest,
model = res_feglm,
data = df,
newdata = df,
strict = FALSE
)
check_augment_function(
aug = augment.fixest,
model = res_femlm,
data = df,
newdata = df,
strict = FALSE
)
augment_error <- "augment is only supported for fixest models estimated with feols, feglm, or femlm"
expect_error(augment(res_fenegbin, df), augment_error)
expect_error(augment(res_feNmlm, df), augment_error)
expect_error(augment(res_fepois, df), augment_error)
})
test_that("tidiers work with model results or summary of model results", {
skip_on_cran()
skip_on_ci()
# Default standard errors are clustered by `id`. Test against non-default
# independent, heteroskedastic ("hetero") standard errors.
fit2_summ <- summary(fit2, se = "hetero")
expect_equal(tidy(fit2, se = "hetero"), tidy(fit2_summ))
expect_equal(
tidy(fit2, se = "hetero", conf.int = TRUE),
tidy(fit2_summ, conf.int = TRUE)
)
expect_equal(glance(fit2, se = "hetero"), glance(fit2_summ))
expect_equal(augment(fit2, df, se = "hetero"), augment(fit2_summ, df))
# Repeat for feglm
res_glm <- fixest::feglm(v2 ~ v4 | id, data = df, family = "poisson")
res_glm_summ <- summary(fixest::feglm(v2 ~ v4 | id, data = df, family = "poisson"), se = "hetero")
expect_equal(tidy(res_glm, se = "hetero"), tidy(res_glm_summ))
expect_equal(
as.data.frame(tidy(res_glm, se = "hetero", conf.int = TRUE)),
as.data.frame(tidy(res_glm_summ, conf.int = TRUE))
)
expect_equal(glance(res_glm, se = "hetero"), glance(res_glm_summ))
expect_equal(augment(res_glm, df, se = "hetero"), augment(res_glm_summ, df))
# We rely on behavior from fixest where summary.fixest() doesn't change the
# `se` or `dof` arguments if they've already been set.
# Test that claim here. (Calling summary again does change other things, like
# the `summary_from_fit` flag, so we can't just expect_equal the whole object)
expect_false(is.null(fit2_summ$coeftable))
expect_equal(fit2_summ$coeftable, summary(fit2_summ)$coeftable)
expect_equal(summary(fit)$coeftable, summary(summary(fit))$coeftable)
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.