Skip to contents

Provides how the small sample correction should be calculated in vcov.fixest/summary.fixest.

Usage

ssc(
  adj = TRUE,
  fixef.K = "nested",
  cluster.adj = TRUE,
  cluster.df = "min",
  t.df = "min",
  fixef.force_exact = FALSE
)

dof(
  adj = TRUE,
  fixef.K = "nested",
  cluster.adj = TRUE,
  cluster.df = "min",
  t.df = "min",
  fixef.force_exact = FALSE
)

setFixest_ssc(ssc.type = ssc())

getFixest_ssc()

Arguments

adj

Logical scalar, defaults to TRUE. Whether to apply a small sample adjustment of the form (n - 1) / (n - K), with K the number of estimated parameters. If FALSE, then no adjustment is made.

fixef.K

Character scalar equal to "nested" (default), "none" or "full". In the small sample adjustment, how to account for the fixed-effects parameters. If "none", the fixed-effects parameters are discarded, meaning the number of parameters (K) is only equal to the number of variables. If "full", then the number of parameters is equal to the number of variables plus the number of fixed-effects. Finally, if "nested", then the number of parameters is equal to the number of variables plus the number of fixed-effects that are not nested in the clusters used to cluster the standard-errors.

cluster.adj

Logical scalar, default is TRUE. How to make the small sample correction when clustering the standard-errors? If TRUE a G/(G-1) correction is performed with G the number of cluster values.

cluster.df

Either "conventional" or "min" (default). Only relevant when the variance-covariance matrix is two-way clustered (or higher). It governs how the small sample adjustment for the clusters is to be performed. [Sorry for the jargon that follows.] By default a unique adjustment is made, of the form G_min/(G_min-1) with G_min the smallest G_i. If cluster.df="conventional" then the i-th "sandwich" matrix is adjusted with G_i/(G_i-1) with G_i the number of unique clusters.

t.df

Either "conventional", "min" (default) or an integer scalar. Only relevant when the variance-covariance matrix is clustered. It governs how the p-values should be computed. By default, the degrees of freedom of the Student t distribution is equal to the minimum size of the clusters with which the VCOV has been clustered minus one. If t.df="conventional", then the degrees of freedom of the Student t distribution is equal to the number of observations minus the number of estimated variables. You can also pass a number to manually specify the DoF of the t-distribution.

fixef.force_exact

Logical, default is FALSE. If there are 2 or more fixed-effects, these fixed-effects they can be irregular, meaning they can provide the same information. If so, the "real" number of parameters should be lower than the total number of fixed-effects. If fixef.force_exact = TRUE, then fixef.fixest is first run to determine the exact number of parameters among the fixed-effects. Mostly, panels of the type individual-firm require fixef.force_exact = TRUE (but it adds computational costs).

ssc.type

An object of class ssc.type obtained with the function ssc.

Value

It returns a ssc.type object.

Details

The following vignette: On standard-errors, describes in details how the standard-errors are computed in fixest and how you can replicate standard-errors from other software.

Functions

  • dof(): This function is deprecated and will be removed at some point (in 6 months from August 2021). Exactly the same as ssc.

Author

Laurent Berge

Examples


#
# Equivalence with lm/glm standard-errors
#

# LM
# In the absence of fixed-effects,
# by default, the standard-errors are computed in the same way

res = feols(Petal.Length ~ Petal.Width + Species, iris)
res_lm = lm(Petal.Length ~ Petal.Width + Species, iris)
vcov(res) / vcov(res_lm)
#>                   (Intercept) Petal.Width Speciesversicolor Speciesvirginica
#> (Intercept)                 1           1                 1                1
#> Petal.Width                 1           1                 1                1
#> Speciesversicolor           1           1                 1                1
#> Speciesvirginica            1           1                 1                1

# GLM
# By default, there is no small sample adjustment in glm, as opposed to feglm.
# To get the same SEs, we need to use ssc(adj = FALSE)

res_pois = fepois(round(Petal.Length) ~ Petal.Width + Species, iris)
res_glm = glm(round(Petal.Length) ~ Petal.Width + Species, iris, family = poisson())
vcov(res_pois, ssc = ssc(adj = FALSE)) / vcov(res_glm)
#>                   (Intercept) Petal.Width Speciesversicolor Speciesvirginica
#> (Intercept)                 1           1                 1                1
#> Petal.Width                 1           1                 1                1
#> Speciesversicolor           1           1                 1                1
#> Speciesvirginica            1           1                 1                1

# Same example with the Gamma
res_gamma = feglm(round(Petal.Length) ~ Petal.Width + Species, iris, family = Gamma())
res_glm_gamma = glm(round(Petal.Length) ~ Petal.Width + Species, iris, family = Gamma())
vcov(res_gamma, ssc = ssc(adj = FALSE)) / vcov(res_glm_gamma)
#>                   (Intercept) Petal.Width Speciesversicolor Speciesvirginica
#> (Intercept)                 1           1                 1                1
#> Petal.Width                 1           1                 1                1
#> Speciesversicolor           1           1                 1                1
#> Speciesvirginica            1           1                 1                1

#
# Fixed-effects corrections
#

# We create "irregular" FEs
base = data.frame(x = rnorm(10))
base$y = base$x + rnorm(10)
base$fe1 = rep(1:3, c(4, 3, 3))
base$fe2 = rep(1:5, each = 2)

est = feols(y ~ x | fe1 + fe2, base)

# fe1: 3 FEs
# fe2: 5 FEs

#
# Clustered standard-errors: by fe1
#

# Default: fixef.K = "nested"
#  => adjustment K = 1 + 5 (i.e. x + fe2)
summary(est)
#> OLS estimation, Dep. Var.: y
#> Observations: 10 
#> Fixed-effects: fe1: 3,  fe2: 5
#> Standard-errors: Clustered (fe1) 
#>   Estimate Std. Error t value Pr(>|t|) 
#> x 0.517215   0.561305 0.92145  0.45409 
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> RMSE: 0.73031     Adj. R2: -1.26941
#>                 Within R2: 0.219994
attributes(vcov(est, attr = TRUE))[c("ssc", "dof.K")]
#> $ssc
#> $adj
#> [1] TRUE
#> 
#> $fixef.K
#> [1] "nested"
#> 
#> $cluster.adj
#> [1] TRUE
#> 
#> $cluster.df
#> [1] "min"
#> 
#> $t.df
#> [1] "min"
#> 
#> $fixef.force_exact
#> [1] FALSE
#> 
#> attr(,"class")
#> [1] "ssc.type"
#> 
#> $dof.K
#> [1] 6
#> 


# fixef.K = FALSE
#  => adjustment K = 1 (i.e. only x)
summary(est, ssc = ssc(fixef.K = "none"))
#> OLS estimation, Dep. Var.: y
#> Observations: 10 
#> Fixed-effects: fe1: 3,  fe2: 5
#> Standard-errors: Clustered (fe1) 
#>   Estimate Std. Error t value Pr(>|t|) 
#> x 0.517215   0.374204 1.38217  0.30104 
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> RMSE: 0.73031     Adj. R2: -1.26941
#>                 Within R2: 0.219994
attr(vcov(est, ssc = ssc(fixef.K = "none"), attr = TRUE), "dof.K")
#> [1] 1


# fixef.K = TRUE
#  => adjustment K = 1 + 3 + 5 - 1 (i.e. x + fe1 + fe2 - 1 restriction)
summary(est, ssc = ssc(fixef.K = "full"))
#> OLS estimation, Dep. Var.: y
#> Observations: 10 
#> Fixed-effects: fe1: 3,  fe2: 5
#> Standard-errors: Clustered (fe1) 
#>   Estimate Std. Error  t value Pr(>|t|) 
#> x 0.517215   0.793806 0.651563  0.58155 
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> RMSE: 0.73031     Adj. R2: -1.26941
#>                 Within R2: 0.219994
attr(vcov(est, ssc = ssc(fixef.K = "full"), attr = TRUE), "dof.K")
#> [1] 8


# fixef.K = TRUE & fixef.force_exact = TRUE
#  => adjustment K = 1 + 3 + 5 - 2 (i.e. x + fe1 + fe2 - 2 restrictions)
summary(est, ssc = ssc(fixef.K = "full", fixef.force_exact = TRUE))
#> OLS estimation, Dep. Var.: y
#> Observations: 10 
#> Fixed-effects: fe1: 3,  fe2: 5
#> Standard-errors: Clustered (fe1) 
#>   Estimate Std. Error  t value Pr(>|t|) 
#> x 0.517215    0.64814 0.797999  0.50857 
#> ---
#> Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#> RMSE: 0.73031     Adj. R2: -1.26941
#>                 Within R2: 0.219994
attr(vcov(est, ssc = ssc(fixef.K = "full", fixef.force_exact = TRUE), attr = TRUE), "dof.K")
#> [1] 7

# There are two restrictions:
attr(fixef(est), "references")
#> NOTE: The fixed-effects are not regular, they cannot be straightforwardly interpreted.
#> fe1 fe2 
#>   0   2 

#
# To permanently set the default ssc:
#

# eg no small sample adjustment:
setFixest_ssc(ssc(adj = FALSE))

# Factory default
setFixest_ssc()