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 functionsfemlm
,feols
orfeglm
.- 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 fromvcov_cluster
,vcov_NW
,NW
,vcov_DK
,DK
,vcov_conley
andconley
. It also accepts covariance matrices computed externally. Finally it accepts functions to compute the covariances. See thevcov
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"
, otherwisese = "iid"
. Note that this argument is deprecated, you should usevcov
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
andvar2
contained in the data.framebase
used for the estimation. All the followingcluster
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 withvcov = "twoway"
(assumingvar1
[resp.var2
] was the 1st [resp. 2nd] fixed-effect). You can interact two variables using^
with the following syntax:cluster = ~var1^var2
orcluster = "var1^var2"
.- ssc
An object of class
ssc.type
obtained with the functionssc
. Represents how the degree of freedom correction should be done.You must use the functionssc
for this argument. The arguments and defaults of the functionssc
are:adj = TRUE
,fixef.K="nested"
,cluster.adj = TRUE
,cluster.df = "min"
,t.df = "min"
,fixef.force_exact=FALSE)
. See the help of the functionssc
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 isFALSE
. IfTRUE
, 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
.
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