fgls() fits a linear regression by feasible generalized least squares,
correcting for serially correlated errors (Perron and González-Coya, 2026),
for heteroskedasticity of unknown form (González-Coya and Perron, 2024), or
for both (the "F-CH" estimator of Supplement S-4 of the 2026 paper).
serial_fgls() and lasso_fgls() are shortcuts for the two single
corrections.
Usage
fgls(
formula,
data,
subset,
na.action = stats::na.fail,
serial = c("auto", "fixed", "ma1", "none"),
hetero = c("lasso", "svr", "wls_s1", "wls_s2", "known", "none"),
vcov = c("robust", "naive", "nonrobust", "HC0", "HC1", "HC2", "HC3", "bootstrap"),
z = "auto",
ar_order = NULL,
kmax = NULL,
ic = c("bic", "aic"),
lagged_dep_vars = NULL,
wallis_regressor = "auto",
exog = c("predetermined", "exogenous"),
first_stage_correction = NULL,
variance = NULL,
delta = 0.1,
psi_grid = c(0, 0.25, 0.5, 0.75, 1, 2),
cv_folds = 10L,
lambda_rule = c("min", "1se"),
weight_clip = NULL,
seed = NULL,
use_t = FALSE,
time = NULL,
allow_gaps = FALSE,
check_stationarity = FALSE,
control = fgls_control(),
contrasts = NULL,
model = TRUE,
weights,
...
)Arguments
- formula
A model formula, as in
stats::lm(). Include an intercept unless the model truly has none.- data
A data frame, a list, a
ts/mtsobject, or a 'zoo'/'xts' object containing the variables in the formula. Rows must be in time order (unlessserial = "none").- subset
Optional expression selecting rows, evaluated in
data. For time series without a time index (time, or a ts/zoodata) the selected rows must be an increasing block of consecutive rows (e.g.subset = 51:200): repeated or reversed rows are an error, and so are skipped rows unlessallow_gaps = TRUE.- na.action
stats::na.fail()(default) stops on missing values;stats::na.omit()orstats::na.exclude()drop them. For time series only leading and trailing missing values can be dropped. Withna.exclude,residuals()andfitted()are padded withNAto the rows selected bysubset, as forstats::lm().- serial
Serial-correlation correction:
"auto"(AR order by BIC, default),"fixed"(usear_order),"ma1"(GMA for MA(1) errors; it does not takear_order,kmaxorlagged_dep_vars) or"none".- hetero
Skedastic-function estimator:
"lasso"(adaptive Lasso, default),"svr"(support vector regression, requires 'e1071'),"wls_s1"/"wls_s2"(the parametric fits of Romano and Wolf, 2017, on \(\log z\) or \(z\)),"known"(variances given invariance) or"none"."wls_s1"takes logs, so it needs strictly positive candidate covariates given explicitly inz(e.g.z = "x"for a positive regressorx); the cosine terms of the defaultz = "auto"are usually negative somewhere, which is an error.- vcov
Variance estimator; the default
"robust"is PG26 eq. (29) with the serial correction only, GP24 eqs. (6) and (8) with the heteroskedasticity correction only, and Supplement eqs. (A.4)–(A.5) with both. The types available depend on the corrections:serial only (
hetero = "none"):"robust","naive"(PG26 eq. 27, exogenous regressors only),"HC0"–"HC3"and"bootstrap"(sieve bootstrap); withserial = "ma1"only"robust";heteroskedasticity only (
serial = "none"):"robust","nonrobust","HC0"–"HC3"and"bootstrap"(wild bootstrap);both (the default):
"robust","HC0","HC3"and"bootstrap"(sieve bootstrap).
Any other choice is an error. See
vcov.fgls().- z
Candidate covariates of the skedastic function:
"auto"(default) builds \(\{x, x^2, \log x, (\log x)^2, \cos x, \cos 2x\}\) from every non-constant regressor (seemake_dictionary()); a character vector of regressor names; a one-sided formula evaluated indata(e.g.~ x + I(x^2) + w); or a numeric matrix / data frame with one row per row ofdata. Withhetero = "wls_s1"all candidates must be strictly positive, so give them explicitly, e.g.z = "x"orz = ~ x + I(x^2)for a positive regressorx.- ar_order
Fixed AR order (implies
serial = "fixed").- kmax
Largest AR order considered:
NULL(default, \(\lfloor 12 (T/200)^{1/4} \rfloor\)), an integer, or"theory"(\(\lfloor (T/\ln T)^{1/3} \rfloor\)). It is capped so that the Durbin regression uses at most half of the sample as regressors.- ic
Lag-order criterion:
"bic"(default) or"aic".- lagged_dep_vars
Names (or positions) of model-matrix columns that are lags of the dependent variable (not available with
serial = "ma1").- wallis_regressor
Regressor used for the Wallis recovery of the AR coefficients:
"auto"(largest Durbin \(|t|\)),"median", or a name.- exog
Assumption on the regressors:
"predetermined"(default) or"exogenous". Estimates do not depend on it; it sets the default offirst_stage_correctionand the notes of the summary.- first_stage_correction
Add the first-stage (Durbin) term of PG26 eq. (29) to the variance of the combined estimator. Default
TRUEwhenexog = "predetermined".- variance
Known error variances for
hetero = "known": a numeric vector with one value per row ofdata, whose values are selected bysubsetandna.actiontogether with the rows of the data (a vector with one value per observation used is also accepted); or a function of the model matrix returning one value per observation used.- delta
Floor in \(\log\max(\hat u_t^2, \delta^2)\), in the units of the response (default 0.1, as in the paper).
- psi_grid
Exponents \(\psi\) of the adaptive weights; 0 is the plain Lasso.
- cv_folds
Number of cross-validation folds (default 10).
- lambda_rule
Penalty at the minimum of the cross-validation error (
"min", default) or the largest penalty within one standard error of it ("1se").- weight_clip
Optional quantiles
c(lo, hi)at which the fitted log-variance is winsorized, e.g.c(0.01, 0.99).- seed
Optional seed for the cross-validation folds and the bootstrap. The session's random number generator state is restored afterwards.
- use_t
Use Student-t (
n_eff - qdegrees of freedom) instead of normal inference.- time
Time index for data frames: the name of a
Date,POSIXctor numeric column ofdata, or a vector with one value per row. It is used to check that rows are sorted and have no gaps, and must have no missing values in the sample. Convert character dates first, e.g. withas.Date()orzoo::as.yearmon().- allow_gaps
Accept a time index with gaps, or a
subsetthat skips rows (lags are then positional), with a warning.- check_stationarity
Screen the response and the regressors with augmented Dickey-Fuller tests and warn when a unit root is not rejected.
- control
Advanced options, see
fgls_control().- contrasts
Optional list of contrasts for factors, as in
stats::lm().- model
Keep the model frame in the result.
- weights
Not supported: FGLS estimates its own weights. Use
hetero = "known"withvariancefor known variances.- ...
Not used; unknown arguments are an error.
Value
An object of class "fgls", a list with components including
coefficients,vcovEstimates and their covariance matrix.
residuals,fitted.values\(y_t - x_t'\hat\beta\) and \(x_t'\hat\beta\) on the full sample.
innovationsResiduals of the final (filtered and/or weighted) regression.
ar_order,rho,bic_path,nonexogeneity_shareSerial block (
NULLwithout serial correction); more inserial.skedastic,weightsHeteroskedasticity block: selected covariates, coefficients, \(\psi\), \(\lambda\), degrees of freedom, fitted variances;
weightsare \(1/\hat v_t\). For the Lasso,skedastic$lambdais the selected penalty on the scale of 'glmnet', whose objective is that of GP24 eq. (4) divided by the number of observations \(n\) of the skedastic regression, andskedastic$lambda_paper\(= n \lambda\) is the same penalty on the scale of eq. (4). Both refer to the standardized candidate covariates.stagesIntermediate estimators (
stages$serialis F-C). They are"fgls"objects with the same methods as the final fit;vcov(fit$stages$serial, type =)accepts"robust","HC0"and"HC3".nobs,n_effNumber of observations and of observations in the final regression (\(T - k^*\)).
Use the methods summary(), coef(), vcov(), confint(),
predict(), residuals(), plot() and compare_fgls().
Serial correlation (PG26)
The errors are approximated by an AR(k) process. Its coefficients are the
coefficients on the lagged dependent variable in the Durbin regression of
\(y_t\) on \(y_{t-1}, \dots, y_{t-k}\), \(x_t, \dots, x_{t-k}\)
(eq. 14), and \(k\) is chosen by BIC over \(0, \dots, k_{max}\) on a
common sample. The data are then quasi-differenced and the model is
estimated by OLS on the filtered data (eq. 15), dropping the first \(k\)
observations. Unlike Cochrane-Orcutt, this is consistent when the
regressors are only pre-determined (uncorrelated with current and future
innovations) rather than strictly exogenous. The default variance
(vcov = "robust", eqs. 28–29) accounts for the estimation of the filter
and is valid in both cases; vcov = "naive" (eq. 27) is valid only for
exogenous regressors. The share by which the robust variance exceeds the
naive one is reported as nonexogeneity_share. If the selected order is 0,
FGLS equals OLS.
Heteroskedasticity (GP24)
The log of the squared OLS residuals (floored at delta^2) is regressed on
candidate covariates \(z_t\) by an adaptive Lasso: a ridge first step
gives weights \(|\hat\gamma_j|^{-\psi}\), and the penalty \(\lambda\) and
the exponent \(\psi\) are chosen jointly by 10-fold cross-validation with
the same folds for every \(\psi\). The exponentiated fit gives the
weights of a weighted least-squares regression. Inference uses a sandwich
variance with the bias correction of eq. (8), so it stays valid when the
skedastic model is wrong. If the Lasso selects no covariate the weights are
constant and FGLS equals OLS (no loss under homoskedasticity).
Both (Supplement S-4)
With serial != "none" and hetero != "none" the serial correction is
applied first ("F-C"), the skedastic function is fitted to the residuals of
the quasi-differenced regression with candidate covariates built from the
unfiltered regressors, and the quasi-differenced regression is
re-estimated by weighted least squares ("F-CH"). The F-C stage is kept in
fit$stages$serial.
Choosing options
Time series with possibly autocorrelated errors and no concern about heteroskedasticity:
hetero = "none"(orserial_fgls()).Cross-sectional data:
serial = "none"(orlasso_fgls()). Rows can be in any order.Lagged dependent variables among the regressors must be declared in
lagged_dep_vars; the AR coefficients are then recovered by the Wallis ratio (PG26 Section 4.2).Errors known to be MA(1), e.g. multi-step forecast errors:
serial = "ma1"(GMA estimator, PG26 Section 5).With several stochastic regressors the BIC that penalizes only the AR order can select
kmax; usecontrol = fgls_control(ic_penalty = "params").Results involving cross-validation depend on the random folds: set
seedfor reproducibility.
References
Perron, P. and González-Coya, E. (2026). Feasible GLS for time series regression. Journal of Econometrics, 258, 106346. doi:10.1016/j.jeconom.2026.106346
González-Coya, E. and Perron, P. (2024). Estimation in the presence of heteroskedasticity of unknown form: a Lasso-based approach. Journal of Econometric Methods, 13(1), 29–48. doi:10.1515/jem-2023-0007
Romano, J. P. and Wolf, M. (2017). Resurrecting weighted least squares. Journal of Econometrics, 197(1), 1–19. doi:10.1016/j.jeconom.2016.10.003
See also
Other fgls:
compare_fgls(),
fgls-methods,
fgls_control(),
lasso_fgls(),
plot.fgls(),
serial_fgls(),
summary.fgls()
Examples
# Serial correlation with a non-exogenous regressor (PG26 Table 1 design)
sim <- simulate_serial(300, seed = 1)
fit <- fgls(y ~ x, data = sim, hetero = "none")
summary(fit)
#>
#> Call:
#> fgls(formula = y ~ x, data = sim, hetero = "none")
#>
#> Method: FGLS (serial)
#> Covariance: robust
#> Observations: 300 (effective 299)
#> Inference: normal
#> AR order k*: 1 [BIC, kmax = 13]
#> AR coefficients: 0.7654
#> Non-exogeneity share: 0.012
#>
#> Coefficients:
#> Estimate Std. Error z value Pr(>|z|)
#> (Intercept) 1.18739 0.23736 5.002 5.66e-07 ***
#> x 0.98640 0.03202 30.809 < 2e-16 ***
#> ---
#> Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
#>
#> Notes:
#> [1] Covariance: PG26 eq. (29), robust to non-exogenous (pre-determined)
#> regressors.
#> [2] Collinear lagged columns dropped from the Durbin regression:
#> L1.(Intercept).
#>
# Heteroskedasticity of unknown form (GP24)
het <- simulate_hetero(200, skedastic = "log2", seed = 2)
fit2 <- fgls(y ~ x, data = het, serial = "none", seed = 1)
fit2$skedastic$selected
#> [1] "log(x)" "cos(x)"
# Both (Supplement S-4)
both <- simulate_combined(200, ar = 0.5, skedastic = "x2", seed = 3)
fit3 <- fgls(y ~ x, data = both, seed = 1)
compare_fgls(fit3$stages$serial, fit3)
#> term statistic F-C (serial) F-CH (serial+hetero)
#> 1 (Intercept) estimate 1.3723275 1.5934094
#> 2 (Intercept) std.error 0.5413481 0.4430785
#> 3 (Intercept) ci.width 2.1220455 1.7368357
#> 4 x estimate 0.9130718 0.8100948
#> 5 x std.error 0.2611294 0.2123379
#> 6 x ci.width 1.0236086 0.8323494