Skip to contents

This function extracts the variance-covariance of estimated parameters from a model estimated with femlm, feols or feglm.

Usage

# S3 method for fixest
vcov(
  object,
  vcov = NULL,
  se = NULL,
  cluster,
  ssc = NULL,
  attr = FALSE,
  forceCovariance = FALSE,
  keepBounded = FALSE,
  nthreads = getFixest_nthreads(),
  vcov_fix = TRUE,
  ...
)

Arguments

object

A fixest object. Obtained using the functions femlm, feols or feglm.

vcov

Versatile argument to specify the VCOV. In general, it is either a character scalar equal to a VCOV type, either a formula of the form: vcov_type ~ variables. The VCOV types implemented are: "iid", "hetero" (or "HC1"), "cluster", "twoway", "NW" (or "newey_west"), "DK" (or "driscoll_kraay"), and "conley". It also accepts object from vcov_cluster, vcov_NW, NW, vcov_DK, DK, vcov_conley and conley. It also accepts covariance matrices computed externally. Finally it accepts functions to compute the covariances. See the vcov documentation in the vignette.

se

Character scalar. Which kind of standard error should be computed: “standard”, “hetero”, “cluster”, “twoway”, “threeway” or “fourway”? By default if there are clusters in the estimation: se = "cluster", otherwise se = "iid". Note that this argument is deprecated, you should use vcov instead.

cluster

Tells how to cluster the standard-errors (if clustering is requested). Can be either a list of vectors, a character vector of variable names, a formula or an integer vector. Assume we want to perform 2-way clustering over var1 and var2 contained in the data.frame base used for the estimation. All the following cluster arguments are valid and do the same thing: cluster = base[, c("var1", "var2")], cluster = c("var1", "var2"), cluster = ~var1+var2. If the two variables were used as fixed-effects in the estimation, you can leave it blank with vcov = "twoway" (assuming var1 [resp. var2] was the 1st [resp. 2nd] fixed-effect). You can interact two variables using ^ with the following syntax: cluster = ~var1^var2 or cluster = "var1^var2".

ssc

An object of class ssc.type obtained with the function ssc. Represents how the degree of freedom correction should be done.You must use the function ssc for this argument. The arguments and defaults of the function ssc are: adj = TRUE, fixef.K="nested", cluster.adj = TRUE, cluster.df = "min", t.df = "min", fixef.force_exact=FALSE). See the help of the function ssc for details.

attr

Logical, defaults to FALSE. Whether to include the attributes describing how the VCOV was computed.

forceCovariance

(Advanced users.) Logical, default is FALSE. In the peculiar case where the obtained Hessian is not invertible (usually because of collinearity of some variables), use this option to force the covariance matrix, by using a generalized inverse of the Hessian. This can be useful to spot where possible problems come from.

keepBounded

(Advanced users -- feNmlm with non-linear part and bounded coefficients only.) Logical, default is FALSE. If TRUE, then the bounded coefficients (if any) are treated as unrestricted coefficients and their S.E. is computed (otherwise it is not).

nthreads

The number of threads. Can be: a) an integer lower than, or equal to, the maximum number of threads; b) 0: meaning all available threads will be used; c) a number strictly between 0 and 1 which represents the fraction of all threads to use. The default is to use 50% of all threads. You can set permanently the number of threads used within this package using the function setFixest_nthreads.

vcov_fix

Logical scalar, default is TRUE. If the VCOV ends up not being positive definite, whether to "fix" it using an eigenvalue decomposition (a la Cameron, Gelbach & Miller 2011).

...

Other arguments to be passed to summary.fixest.

The computation of the VCOV matrix is first done in summary.fixest.

Value

It returns a \(K\times K\) square matrix where \(K\) is the number of variables of the fitted model. If attr = TRUE, this matrix has an attribute “type” specifying how this variance/covariance matrix has been computed.

Details

For an explanation on how the standard-errors are computed and what is the exact meaning of the arguments, please have a look at the dedicated vignette: On standard-errors.

References

Ding, Peng, 2021, "The Frisch–Waugh–Lovell theorem for standard errors." Statistics & Probability Letters 168.

See also

You can also compute VCOVs with the following functions: vcov_cluster, vcov_hac, vcov_conley.

See also the main estimation functions femlm, feols or feglm. summary.fixest, confint.fixest, resid.fixest, predict.fixest, fixef.fixest.

Author

Laurent Berge

Examples


# Load panel data
data(base_did)

# Simple estimation on a panel
est = feols(y ~ x1, base_did)

# ======== #
# IID VCOV #
# ======== #

# By default the VCOV assumes iid errors:
se(vcov(est))
#> (Intercept)          x1 
#>   0.1491554   0.0501191 

# You can make the call for an iid VCOV explicitly:
se(vcov(est, "iid"))
#> (Intercept)          x1 
#>   0.1491554   0.0501191 

#
# Heteroskedasticity-robust VCOV
#

# By default the VCOV assumes iid errors:
se(vcov(est, "hetero"))
#> (Intercept)          x1 
#>  0.14902573  0.05101605 

# => note that it also accepts vcov = "White" and vcov = "HC1" as aliases.

# =============== #
# Clustered VCOVs #
# =============== #

# To cluster the VCOV, you can use a formula of the form cluster ~ var1 + var2 etc
# Let's cluster by the panel ID:
se(vcov(est, cluster ~ id))
#> (Intercept)          x1 
#>   0.1943525   0.0467892 

# Alternative ways:

# -> cluster is implicitly assumed when a one-sided formula is provided
se(vcov(est, ~ id))
#> (Intercept)          x1 
#>   0.1943525   0.0467892 

# -> using the argument cluster instead of vcov
se(vcov(est, cluster = ~ id))
#> (Intercept)          x1 
#>   0.1943525   0.0467892 

# For two-/three- way clustering, just add more variables:
se(vcov(est, ~ id + period))
#> (Intercept)          x1 
#>  0.61496508  0.04721779 

# -------------------|
# Implicit deduction |
# -------------------|
# When the estimation contains FEs, the dimension on which to cluster
# is directly inferred from the FEs used in the estimation, so you don't need
# to explicitly add them.

est_fe = feols(y ~ x1 | id + period, base_did)

# Clustered along "id"
se(vcov(est_fe, "cluster"))
#>         x1 
#> 0.04578726 

# Clustered along "id" and "period"
se(vcov(est_fe, "twoway"))
#>         x1 
#> 0.03417711 


# =========== #
# Panel VCOVs #
# =========== #

# ---------------------|
# Newey West (NW) VCOV |
# ---------------------|
# To obtain NW VCOVs, use a formula of the form NW ~ id + period
se(vcov(est, NW ~ id + period))
#> (Intercept)          x1 
#>  0.17411100  0.05269927 

# If you want to change the lag:
se(vcov(est, NW(3) ~ id + period))
#> (Intercept)          x1 
#>  0.19450009  0.05104156 

# Alternative way:

# -> using the vcov_NW function
se(vcov(est, vcov_NW(unit = "id", time = "period", lag = 3)))
#> (Intercept)          x1 
#>  0.19450009  0.05104156 

# -------------------------|
# Driscoll-Kraay (DK) VCOV |
# -------------------------|
# To obtain DK VCOVs, use a formula of the form DK ~ period

se(vcov(est, DK ~ period))
#> (Intercept)          x1 
#>  0.78953790  0.03611533 

# If you want to change the lag:
se(vcov(est, DK(3) ~ period))
#> (Intercept)          x1 
#>  0.97148590  0.02841491 

# Alternative way:

# -> using the vcov_DK function
se(vcov(est, vcov_DK(time = "period", lag = 3)))
#> (Intercept)          x1 
#>  0.97148590  0.02841491 

# -------------------|
# Implicit deduction |
# -------------------|
# When the estimation contains a panel identifier, you don't need
# to re-write them later on

est_panel = feols(y ~ x1, base_did, panel.id = ~id + period)

# Both methods, NM and DK, now work automatically
se(vcov(est_panel, "NW"))
#> (Intercept)          x1 
#>  0.17411100  0.05269927 
se(vcov(est_panel, "DK"))
#> (Intercept)          x1 
#>  0.78953790  0.03611533 


# =================================== #
# VCOVs robust to spatial correlation #
# =================================== #

data(quakes)
est_geo = feols(depth ~ mag, quakes)

# ------------|
# Conley VCOV |
# ------------|
# To obtain a Conley VCOV, use a formula of the form conley(cutoff) ~ lat + lon
# with lat/lon the latitude/longitude variable names in the data set
se(vcov(est_geo, conley(100) ~ lat + long))
#> (Intercept)         mag 
#>   108.90052    19.23233 

# Alternative way:

# -> using the vcov_DK function
se(vcov(est_geo, vcov_conley(lat = "lat", lon = "long", cutoff = 100)))
#> (Intercept)         mag 
#>   108.90052    19.23233 

# -------------------|
# Implicit deduction |
# -------------------|
# By default the latitude and longitude are directly fetched in the data based
# on pattern matching. So you don't have to specify them.
# Furhter, an automatic cutoff is deduced by default.

# The following works:
se(vcov(est_geo, "conley"))
#> (Intercept)         mag 
#>   110.67271    20.17456 


# ======================== #
# Small Sample Corrections #
# ======================== #

# You can change the way the small sample corrections are done with the argument ssc.
# The argument ssc must be created by the ssc function
se(vcov(est, ssc = ssc(adj = FALSE)))
#> (Intercept)          x1 
#>  0.14908629  0.05009587 

# You can add directly the call to ssc in the vcov formula.
# You need to add it like a variable:
se(vcov(est, iid ~ ssc(adj = FALSE)))
#> (Intercept)          x1 
#>  0.14908629  0.05009587 
se(vcov(est, DK ~ period + ssc(adj = FALSE)))
#> (Intercept)          x1 
#>  0.78917195  0.03609859