| Title: | Panel Fixed Effects Filtered and Variance Decomposition Estimation |
|---|---|
| Description: | Implements fixed effects estimators for time-invariant variables in panel data models. Provides three estimation methods: FEVD (Fixed Effects Vector Decomposition) from Plumper and Troeger (2007) <doi:10.1093/pan/mpm002>, and FEF (Fixed Effects Filtered) and FEF-IV (instrumental variables variant) from Pesaran and Zhou (2018) <doi:10.1080/07474938.2016.1222225>. All methods use the correct Pesaran-Zhou variance estimators that account for generated regressor uncertainty, avoiding the size distortions documented in the literature. |
| Authors: | Muhammad Alkhalaf [aut, cre, cph] (ORCID: <https://orcid.org/0009-0002-2677-9246>) |
| Maintainer: | Muhammad Alkhalaf <[email protected]> |
| License: | GPL-3 |
| Version: | 1.0.1 |
| Built: | 2026-05-25 06:44:52 UTC |
| Source: | https://github.com/muhammedalkhalaf/xtfifevd |
Computes the between-panel and within-panel standard deviations for specified variables, along with their ratio. This diagnostic helps assess whether FEVD/FEF methods may improve upon standard FE estimation.
bw_ratio(data, variables, id)bw_ratio(data, variables, id)
data |
A data frame containing the panel data. |
variables |
A character vector of variable names to analyze. |
id |
Character string naming the panel identifier variable. |
For truly time-invariant variables, the within-panel SD should be zero (or near-zero due to numerical precision), giving an infinite ratio.
According to Plümper and Troeger (2007), FEVD/FEF methods tend to improve upon standard FE when:
The between/within ratio exceeds approximately 1.7
The correlation between z and the unobserved unit effect is not too high
A data frame with columns:
Variable name
Between-panel standard deviation
Within-panel standard deviation
Ratio of between to within SD
Plumper, T., & Troeger, V. E. (2007). Efficient Estimation of Time-Invariant and Rarely Changing Variables in Finite Sample Panel Analyses with Unit Fixed Effects. Political Analysis, 15(2), 124-139. doi:10.1093/pan/mpm002
# Create example data set.seed(42) N <- 50 T <- 5 id <- rep(1:N, each = T) z_invariant <- rep(rnorm(N), each = T) # Truly time-invariant z_slow <- rep(rnorm(N), each = T) + rnorm(N * T, sd = 0.1) # Slowly varying x_varying <- rnorm(N * T) # Time-varying data <- data.frame(id = id, z_inv = z_invariant, z_slow = z_slow, x = x_varying) bw_ratio(data, c("z_inv", "z_slow", "x"), id = "id")# Create example data set.seed(42) N <- 50 T <- 5 id <- rep(1:N, each = T) z_invariant <- rep(rnorm(N), each = T) # Truly time-invariant z_slow <- rep(rnorm(N), each = T) + rnorm(N * T, sd = 0.1) # Slowly varying x_varying <- rnorm(N * T) # Time-varying data <- data.frame(id = id, z_inv = z_invariant, z_slow = z_slow, x = x_varying) bw_ratio(data, c("z_inv", "z_slow", "x"), id = "id")
Estimates panel models with time-invariant regressors using FEVD, FEF, or FEF-IV methods. Standard fixed effects estimation cannot identify coefficients on time-invariant variables; these methods decompose or filter the unit effects to recover these coefficients.
xtfifevd( formula, data, id, time, method = c("fevd", "fef", "fef_iv"), instruments = NULL, na.action = na.omit ) fevd(formula, data, id, time, na.action = na.omit) fef(formula, data, id, time, na.action = na.omit) fef_iv(formula, data, id, time, instruments, na.action = na.omit)xtfifevd( formula, data, id, time, method = c("fevd", "fef", "fef_iv"), instruments = NULL, na.action = na.omit ) fevd(formula, data, id, time, na.action = na.omit) fef(formula, data, id, time, na.action = na.omit) fef_iv(formula, data, id, time, instruments, na.action = na.omit)
formula |
A formula of the form |
data |
A data frame containing the variables. |
id |
Character string naming the panel (individual) identifier variable. |
time |
Character string naming the time identifier variable. |
method |
Estimation method: |
instruments |
For |
na.action |
How to handle missing values. Default is |
The panel model is:
where are time-varying regressors, are time-invariant
regressors, and are individual fixed effects.
Fixed effects regression of on yields consistent
and combined residuals .
Time-averaged residuals are regressed on :
FEF: OLS of on with intercept
FEF-IV: 2SLS using instruments
FEVD: Same as FEF, then Stage 3 pooled OLS (point estimates identical)
Uses Pesaran-Zhou (2016) Equation 17/51 which properly accounts for estimation uncertainty from Stage 1. The naive pooled OLS standard errors from FEVD Stage 3 are inconsistent and can understate true SEs by factors of 2-5x or more.
An object of class "xtfifevd" containing:
Named vector of all coefficients (beta, gamma, intercept)
Variance-covariance matrix using Pesaran-Zhou estimator
Coefficients on time-varying variables (from FE stage)
Coefficients on time-invariant variables
Overall intercept
Idiosyncratic residuals from FE stage
Fitted values
Variance of idiosyncratic error
Variance of unit effects
Total number of observations
Number of groups (panels)
Average time periods per panel
Estimation method used
The matched call
fevd: FEVD estimation (3-stage, Plümper-Troeger)
fef: FEF estimation (2-stage, Pesaran-Zhou)
fef_iv: FEF-IV estimation with instruments
Plumper, T., & Troeger, V. E. (2007). Efficient Estimation of Time-Invariant and Rarely Changing Variables in Finite Sample Panel Analyses with Unit Fixed Effects. Political Analysis, 15(2), 124-139. doi:10.1093/pan/mpm002
Pesaran, M. H., & Zhou, Q. (2018). Estimation of time-invariant effects in static panel data models. Econometric Reviews, 37(10), 1137-1171. doi:10.1080/07474938.2016.1222225
# Simulate panel data set.seed(123) N <- 100 # panels T <- 10 # time periods n <- N * T # Generate data id <- rep(1:N, each = T) time <- rep(1:T, N) alpha_i <- rep(rnorm(N), each = T) # Fixed effects z <- rep(rnorm(N), each = T) # Time-invariant x <- rnorm(n) # Time-varying y <- 1 + 2 * x + 0.5 * z + alpha_i + rnorm(n, sd = 0.5) data <- data.frame(id = id, time = time, y = y, x = x, z = z) # Estimate with different methods fit_fevd <- xtfifevd(y ~ x | z, data = data, id = "id", time = "time") summary(fit_fevd) fit_fef <- xtfifevd(y ~ x | z, data = data, id = "id", time = "time", method = "fef") summary(fit_fef)# Simulate panel data set.seed(123) N <- 100 # panels T <- 10 # time periods n <- N * T # Generate data id <- rep(1:N, each = T) time <- rep(1:T, N) alpha_i <- rep(rnorm(N), each = T) # Fixed effects z <- rep(rnorm(N), each = T) # Time-invariant x <- rnorm(n) # Time-varying y <- 1 + 2 * x + 0.5 * z + alpha_i + rnorm(n, sd = 0.5) data <- data.frame(id = id, time = time, y = y, x = x, z = z) # Estimate with different methods fit_fevd <- xtfifevd(y ~ x | z, data = data, id = "id", time = "time") summary(fit_fevd) fit_fef <- xtfifevd(y ~ x | z, data = data, id = "id", time = "time", method = "fef") summary(fit_fef)