Computes the clustered VCOV of fixest
objects.
Arguments
- x
A
fixest
object.- cluster
Either i) a character vector giving the names of the variables onto which to cluster, or ii) a formula giving those names, or iii) a vector/list/data.frame giving the hard values of the clusters. Note that in cases i) and ii) the variables are fetched directly in the data set used for the estimation.
- ssc
An object returned by the function
ssc
. It specifies how to perform the small sample correction.- 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).
Value
If the first argument is a fixest
object, then a VCOV is returned (i.e. a symmetric matrix).
If the first argument is not a fixest
object, then a) implicitly the arguments are shifted to
the left (i.e. vcov_cluster(~var1 + var2)
is equivalent to
vcov_cluster(cluster = ~var1 + var2)
) and b) a VCOV-request is returned and NOT a VCOV.
That VCOV-request can then be used in the argument vcov
of various fixest
functions (e.g. vcov.fixest
or even in the estimation calls).
References
Cameron AC, Gelbach JB, Miller DL (2011). "Robust Inference with Multiway Clustering." Journal of Business & Economic Statistics, 29(2), 238-249. doi:10.1198/jbes.2010.07136.
Examples
base = iris
names(base) = c("y", "x1", "x2", "x3", "species")
base$clu = rep(1:5, 30)
est = feols(y ~ x1, base)
# VCOV: using a formula giving the name of the clusters
vcov_cluster(est, ~species + clu)
#> (Intercept) x1
#> (Intercept) 0.6046144 -0.2634955
#> x1 -0.2634955 0.1235058
# works as well with a character vector
vcov_cluster(est, c("species", "clu"))
#> (Intercept) x1
#> (Intercept) 0.6046144 -0.2634955
#> x1 -0.2634955 0.1235058
# you can also combine the two with '^'
vcov_cluster(est, ~species^clu)
#> (Intercept) x1
#> (Intercept) 0.27358801 -0.09893941
#> x1 -0.09893941 0.03852919
#
# Using VCOV requests
#
# per se: pretty useless...
vcov_cluster(~species)
#> ~species
#> <environment: 0x000001cf44a26a58>
# ...but VCOV-requests can be used at estimation time:
# it may be more explicit than...
feols(y ~ x1, base, vcov = vcov_cluster("species"))
#> OLS estimation, Dep. Var.: y
#> Observations: 150
#> Standard-errors: Clustered (species)
#> Estimate Std. Error t value Pr(>|t|)
#> (Intercept) 6.526223 0.939312 6.947878 0.020093 *
#> x1 -0.223361 0.406738 -0.549152 0.638023
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> RMSE: 0.819578 Adj. R2: 0.007159
# ...the equivalent, built-in way:
feols(y ~ x1, base, vcov = ~species)
#> OLS estimation, Dep. Var.: y
#> Observations: 150
#> Standard-errors: Clustered (species)
#> Estimate Std. Error t value Pr(>|t|)
#> (Intercept) 6.526223 0.939312 6.947878 0.020093 *
#> x1 -0.223361 0.406738 -0.549152 0.638023
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> RMSE: 0.819578 Adj. R2: 0.007159
# The argument vcov does not accept hard values,
# so you can feed them with a VCOV-request:
feols(y ~ x1, base, vcov = vcov_cluster(rep(1:5, 30)))
#> OLS estimation, Dep. Var.: y
#> Observations: 150
#> Standard-errors: Clustered (rep(1:5, 30))
#> Estimate Std. Error t value Pr(>|t|)
#> (Intercept) 6.526223 0.296270 22.02795 2.5137e-05 ***
#> x1 -0.223361 0.100044 -2.23263 8.9350e-02 .
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> RMSE: 0.819578 Adj. R2: 0.007159