context("plm objects - random effects") set.seed(20190513) skip_if_not_installed("nlme") skip_if_not_installed("plm") library(nlme, quietly=TRUE) library(plm, quietly=TRUE) data("Grunfeld", package = "plm") data("Produc", package = "plm") # grun_re <- plm(inv ~ value + capital, data = Grunfeld, model="random") # Grunfeld$cluster <- sample(LETTERS[1:10], size = nrow(Grunfeld), replace=TRUE) # Grunfeld_scramble <- Grunfeld[sample(nrow(Grunfeld)),] CR_types <- paste0("CR",0:4) plm_individual <- plm(inv ~ value + capital, data = Grunfeld, model="random") obj <- plm_individual test_that("individual effects agree with gls", { icc <- with(plm_individual$ercomp, sigma2[["id"]] / (sigma2[["id"]] + sigma2[["idios"]])) gls_individual <- gls(inv ~ value + capital, data = Grunfeld, correlation = corCompSymm(value = icc, form = ~ 1 | firm, fixed=TRUE)) expect_equal(model_matrix(plm_individual), model_matrix(gls_individual)) expect_identical(nobs(plm_individual), nobs(gls_individual)) V_ratio <- Map("/", targetVariance(plm_individual, cluster = Grunfeld$firm), targetVariance(gls_individual, cluster = Grunfeld$firm)) expect_equal(lapply(V_ratio, min), lapply(V_ratio, max)) expect_equivalent(residuals_CS(plm_individual), residuals_CS(gls_individual)) CR_plm <- lapply(CR_types, function(x) vcovCR(plm_individual, type = x)) CR_gls <- lapply(CR_types, function(x) vcovCR(gls_individual, type = x)) expect_equivalent(CR_plm, CR_gls) test_plm <- lapply(CR_types, function(x) coef_test(plm_individual, vcov = x, test = "All", p_values = FALSE)[,-3]) test_gls <- lapply(CR_types, function(x) coef_test(gls_individual, vcov = x, test = "All", p_values = FALSE)[,-3]) expect_equivalent(test_plm, test_gls) }) plm_time <- plm(log(gsp) ~ log(pcap) + log(pc) + log(emp) + unemp, data = Produc, index = c("state","year"), effect = "time", model = "random") test_that("time effects agree with gls", { icc <- with(plm_time$ercomp, sigma2[[2]] / (sigma2[[2]] + sigma2[[1]])) gls_time <- gls(log(gsp) ~ log(pcap) + log(pc) + log(emp) + unemp, data = Produc, correlation = corCompSymm(value = icc, form = ~ 1 | year, fixed = TRUE)) expect_equal(model_matrix(plm_time), model_matrix(gls_time)) expect_identical(nobs(plm_time), nobs(gls_time)) expect_equivalent(residuals_CS(plm_time), residuals_CS(gls_time)) CR_plm <- lapply(CR_types, function(x) vcovCR(plm_time, type = x)) CR_gls <- lapply(CR_types, function(x) vcovCR(gls_time, type = x)) expect_equivalent(CR_plm, CR_gls) test_plm <- lapply(CR_types, function(x) coef_test(plm_time, vcov = x, test = "All", p_values = FALSE)[,-3]) test_gls <- lapply(CR_types, function(x) coef_test(gls_time, vcov = x, test = "All", p_values = FALSE)[,-3]) expect_equivalent(test_plm, test_gls) }) plm_twoways <- plm(log(gsp) ~ log(pcap) + log(pc) + log(emp) + unemp, data = Produc, index = c("state","year"), effect = "twoways", model = "random") test_that("two-way effects throws error", { expect_error(vcovCR(plm_twoways, type = "CR2")) }) plm_nested <- plm(log(gsp) ~ log(pcap) + log(pc) + log(emp) + unemp, data = Produc, index = c("state","year","region"), effect = "nested", model = "random") test_that("nested effects agree with lmer", { skip_if_not_installed("lme4") library(lme4, quietly=TRUE) Produc_sort_order <- with(Produc, order(region, state)) plm_nested$ercomp$sigma2 lmer_nested_fit <- lmer(log(gsp) ~ log(pcap) + log(pc) + log(emp) + unemp + (1 | region / state), data = Produc) theta <- getME(lmer_nested_fit, "theta") theta[1:2] <- with(plm_nested$ercomp, sqrt(sigma2[2:3] / sigma2[1])) lmer_nested <- update(lmer_nested_fit, start = theta, control = lmerControl(optimizer = NULL)) expect_equivalent(model_matrix(plm_nested), model_matrix(lmer_nested)[Produc_sort_order,]) expect_identical(nobs(plm_nested), nobs(lmer_nested)) expect_equivalent(targetVariance(plm_nested, cluster = findCluster.plm(plm_nested)), targetVariance(lmer_nested, cluster = Produc$region)) expect_equivalent(weightMatrix(plm_nested, cluster = findCluster.plm(plm_nested)), weightMatrix(lmer_nested, cluster = Produc$region), tol = 1e-6) CR_plm <- lapply(CR_types, function(x) vcovCR(plm_nested, type = x)) CR_lmer <- lapply(CR_types, function(x) vcovCR(lmer_nested, type = x)) expect_equivalent(CR_plm, CR_lmer) test_plm <- lapply(CR_types, function(x) coef_test(plm_nested, vcov = x, test = "All", p_values = FALSE)[,-3]) test_lmer <- lapply(CR_types, function(x) coef_test(lmer_nested, vcov = x, test = "All", p_values = FALSE)[,-3]) compare_ttests(test_plm, test_lmer, tol = 1e-5) }) test_that("bread works", { expect_true(check_bread(plm_individual, cluster = findCluster.plm(plm_individual), y = plm_individual$model$inv)) expect_true(check_bread(plm_time, cluster = findCluster.plm(plm_time), y = plm_time$model$"log(gsp)")) expect_true(check_bread(plm_nested, cluster = findCluster.plm(plm_nested), y = plm_nested$model$"log(gsp)")) }) test_that("CR0 and CR1S agree with arellano vcov", { expect_equivalent(vcovHC(plm_individual, method="arellano", type = "HC0", cluster = "group"), as.matrix(vcovCR(plm_individual, type = "CR0"))) expect_equivalent(vcovHC(plm_individual, method="arellano", type = "sss", cluster = "group"), as.matrix(vcovCR(plm_individual, type = "CR1S"))) expect_equivalent(vcovHC(plm_time, method="arellano", type = "HC0", cluster = "time"), as.matrix(vcovCR(plm_time, type = "CR0"))) expect_equivalent(vcovHC(plm_time, method="arellano", type = "sss", cluster = "time"), as.matrix(vcovCR(plm_time, type = "CR1S"))) # Can't replicate vcovHC because plm isn't clustering correctly. # expect_equivalent(vcovHC(plm_nested, method="arellano", type = "HC0", cluster = "group"), # as.matrix(vcovCR(plm_nested, type = "CR0"))) # expect_equivalent(vcovHC(plm_nested, method="arellano", type = "sss", cluster = "group"), # as.matrix(vcovCR(plm_nested, type = "CR1S"))) }) test_that("vcovCR options work for CR2", { CR2_iv <- vcovCR(plm_individual, type = "CR2") expect_equal(vcovCR(plm_individual, cluster = Grunfeld$firm, type = "CR2"), CR2_iv) expect_equal(vcovCR(plm_individual, type = "CR2", inverse_var = TRUE), CR2_iv) tgt <- targetVariance(plm_individual, cluster = Grunfeld$firm) expect_equivalent(vcovCR(plm_individual, type = "CR2", target = tgt, inverse_var = TRUE), CR2_iv) CR2_not <- vcovCR(plm_individual, type = "CR2", inverse_var = FALSE) expect_equivalent(CR2_not, CR2_iv) expect_equal(vcovCR(plm_individual, cluster = Grunfeld$firm, type = "CR2", inverse_var = FALSE), CR2_not) expect_equal(vcovCR(plm_individual, type = "CR2", target = tgt), CR2_not) expect_equal(vcovCR(plm_individual, type = "CR2", target = tgt, inverse_var = FALSE), CR2_not) }) test_that("vcovCR options work for CR4", { CR4_iv <- vcovCR(plm_individual, type = "CR4") expect_equal(vcovCR(plm_individual, cluster = Grunfeld$firm, type = "CR4"), CR4_iv) expect_equal(vcovCR(plm_individual, type = "CR4", inverse_var = TRUE), CR4_iv) tgt <- targetVariance(plm_individual, cluster = Grunfeld$firm) expect_equivalent(vcovCR(plm_individual, type = "CR4", target = tgt, inverse_var = TRUE), CR4_iv) CR4_not <- vcovCR(plm_individual, type = "CR4", inverse_var = FALSE) expect_equivalent(CR4_not, CR4_iv) expect_equal(vcovCR(plm_individual, cluster = Grunfeld$firm, type = "CR4", inverse_var = FALSE), CR4_not) expect_equal(vcovCR(plm_individual, type = "CR4", target = tgt), CR4_not) expect_equal(vcovCR(plm_individual, type = "CR4", target = tgt, inverse_var = FALSE), CR4_not) }) test_that("CR2 and CR4 are target-unbiased", { expect_true(check_CR(plm_individual, vcov = "CR2")) expect_true(check_CR(plm_individual, vcov = "CR4")) expect_true(check_CR(plm_time, vcov = "CR2")) expect_true(check_CR(plm_time, vcov = "CR4")) expect_true(check_CR(plm_nested, vcov = "CR2")) expect_true(check_CR(plm_nested, vcov = "CR4")) }) test_that("vcovCR works when clustering at a level above the random effects.", { data("Wages", package = "plm") Wages$ID <- rep(1:595, each = 7) Wages$period <- rep(1:7, times = 595) Wages$Grp <- rep(1:119, each = 7 * 5) plm_ID <- plm(lwage ~ wks + south + smsa + married + exp, data = Wages, index = c("ID","period","Grp"), model="random") ICC <- with(plm_ID$ercomp, sigma2[2] / sum(sigma2)) gls_ID <- gls(lwage ~ wks + south + smsa + married + exp, data = Wages, correlation = corCompSymm(value = ICC, form = ~ 1 | ID, fixed = TRUE)) plm_vcov_ID <- lapply(CR_types, function(x) vcovCR(plm_ID, type = x)) gls_vcov_ID <- lapply(CR_types, function(x) vcovCR(gls_ID, type = x)) expect_equivalent(plm_vcov_ID, gls_vcov_ID) plm_vcov_grp <- lapply(CR_types, function(x) vcovCR(plm_ID, cluster = Wages$Grp, type = x)) plm_vcov_group <- lapply(CR_types, function(x) vcovCR(plm_ID, cluster = "group", type = x)) expect_equal(plm_vcov_grp, plm_vcov_group) gls_vcov_grp <- lapply(CR_types, function(x) vcovCR(gls_ID, cluster = Wages$Grp, type = x)) expect_equivalent(plm_vcov_group, gls_vcov_grp) plm_ID <- plm(log(gsp) ~ log(pcap) + log(pc) + log(emp) + unemp, data = Produc, index = c("state","year","region"), effect = "individual", model = "random") ICC <- with(plm_ID$ercomp, sigma2[2] / sum(sigma2)) gls_ID <- gls(log(gsp) ~ log(pcap) + log(pc) + log(emp) + unemp, data = Produc, correlation = corCompSymm(value = ICC, form = ~ 1 | state, fixed = TRUE)) plm_vcov_grp <- lapply(CR_types, function(x) vcovCR(plm_ID, cluster = Produc$region, type = x)) plm_vcov_group <- lapply(CR_types, function(x) vcovCR(plm_ID, cluster = "group", type = x)) expect_equal(plm_vcov_grp, plm_vcov_group) gls_vcov_grp <- lapply(CR_types, function(x) vcovCR(gls_ID, cluster = Produc$region, type = x)) expect_equivalent(plm_vcov_grp, gls_vcov_grp) })