--- title: "Serial correlation (Perron and González-Coya, 2026)" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{Serial correlation (Perron and González-Coya, 2026)} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r, include = FALSE} knitr::opts_chunk$set(collapse = TRUE, comment = "#>") ``` ```{r setup} library(fgls) ``` ## The problem In \(y_t = x_t'\beta + u_t\) with autocorrelated errors, GLS (or its feasible version) is more efficient than OLS. The classic feasible version, Cochrane-Orcutt, estimates the error autocorrelation from OLS residuals. That is fine when the regressors are *exogenous*, uncorrelated with the errors at all leads and lags. Many time-series regressors are only *pre-determined*: they are uncorrelated with current and future innovations, but respond to past ones, as with policy variables, expectations and lagged prices. OLS is then inconsistent, and so is Cochrane-Orcutt, which inherits its residuals. ## The estimator The errors are approximated by an AR(k) process, \(u_t = \rho_1 u_{t-1} + \dots + \rho_k u_{t-k} + e_t\). Substituting \(u_t = y_t - x_t'\beta\) gives the **Durbin regression** $$y_t = \sum_{j=1}^k \rho_j y_{t-j} + x_t'\beta - \sum_{j=1}^k x_{t-j}'\delta_j + e_t ,$$ estimated by OLS. Every regressor of this equation is uncorrelated with the innovation \(e_t\) when \(x_t\) is pre-determined, so the coefficients on the lagged \(y\) estimate the \(\rho_j\) consistently. In `fgls`: 1. the order \(k\) minimizes BIC over \(0, \dots, k_{max}\), all orders being fitted on the same sample (eq. 14); 2. the data are quasi-differenced with the estimated filter, every column including the constant, and the first \(k\) observations are dropped; OLS on the filtered data gives \(\hat\beta\) (eq. 15). Lagged columns that duplicate other regressors (lags of the constant, of a linear trend, of periodic dummies) are dropped automatically from the Durbin regression. ## Table 1 of the paper ```{r table1} sim <- simulate_serial(500, seed = 7) # AR(1) 0.8, x_t = v_t + e_{t-1} fits <- list( OLS = ols_robust(y ~ x, data = sim), `Cochrane-Orcutt` = cochrane_orcutt(y ~ x, data = sim), Durbin = durbin_estimator(y ~ x, data = sim), FGLS = serial_fgls(y ~ x, data = sim), `GLS (known rho)` = infeasible_gls(y ~ x, data = sim, rho = 0.8) ) sapply(fits, function(f) coef(f)[["x"]]) ``` The true slope is 1. In the paper's Monte Carlo (10,000 replications) OLS has a bias of about 0.40, Cochrane-Orcutt about 0.03, and FGLS is as precise as the infeasible GLS; `vignette("validation")` reproduces these numbers with this package. ## Variance and inference Because \(\hat\rho\) is estimated, and the regressors may react to past innovations, the usual GLS variance (`vcov = "naive"`, eq. 27) understates the uncertainty of \(\hat\beta\). The default `vcov = "robust"` (eqs. 28--29) adds a correction built from the covariance between the filtered regressors and past residuals. It is valid whether the regressors are exogenous or merely pre-determined, and it is positive semidefinite by construction. ```{r variance} fit <- fits$FGLS cbind(robust = sqrt(diag(vcov(fit))), naive = sqrt(diag(vcov(fit, type = "naive")))) fit$nonexogeneity_share ``` `nonexogeneity_share` averages the relative increase of the robust over the naive variance across coefficients. Values near zero mean the regressors behave as exogenous. ## Lag selection ```{r ic} plot(fit, which = 3) fit$bic_path ``` `kmax` defaults to \(\lfloor 12 (T/200)^{1/4} \rfloor\) (12 at \(T = 200\), as in the paper's simulations) and is capped so that the Durbin regression uses at most half of the sample. `ar_order` fixes the order; `ic = "aic"` and `fgls_control(min_lags = "adjusted")` are alternatives. With several stochastic regressors, `fgls_control(ic_penalty = "params")` penalizes every coefficient a lag adds. ## Lagged dependent variables When lags of \(y\) are regressors, the Durbin coefficients on lagged \(y\) mix the dynamics of the model with those of the errors. Under the common-factor structure the AR coefficients can be recovered from the ratio of a lagged regressor's coefficient to its contemporaneous one (Wallis, 1967; Section 4.2 of the paper). Declare the lagged dependent variables: ```{r wallis} set.seed(3) n <- 400 w <- rnorm(n + 1) u <- as.numeric(stats::filter(rnorm(n + 1), 0.5, method = "recursive")) yy <- numeric(n + 1) for (t in 2:(n + 1)) yy[t] <- 0.4 * yy[t - 1] + 1 + w[t] + u[t] dyn <- data.frame(y = yy[-1], ylag = yy[-(n + 1)], w = w[-1]) fit_dyn <- serial_fgls(y ~ ylag + w, data = dyn, lagged_dep_vars = "ylag") coef(fit_dyn) fit_dyn$rho ``` Without the declaration, `fgls()` warns that a regressor looks like a lagged dependent variable. Once the selected AR order reaches the lag in question, the lagged \(y\) of the Durbin regression is collinear with that regressor, and the fit stops with an error asking for `lagged_dep_vars`; with the data above, `serial_fgls(y ~ ylag + w, data = dyn)` fails in this way. ## MA(1) errors For errors known to be MA(1), such as two-step-ahead forecast errors, the GMA estimator (Section 5) inverts the MA filter with the maximum-likelihood estimate of \(\theta\): ```{r gma} pred <- simulate_predictive(300, theta = -0.4, seed = 4) serial_fgls(y ~ x, data = pred, serial = "ma1") ``` ## Checking pre-determinedness `test_predetermined()` (experimental) is a variable-addition LM test for missing lags of the regressors (Remark 9 of the paper). A rejection suggests adding lags of the regressors to the model: ```{r predetermined} suppressWarnings(test_predetermined(y ~ x, data = sim)) ```