Provides how the degrees of freedom should be calculated in vcov.fixest/summary.fixest.

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

setFixest_dof(dof.type = dof())

getFixest_dof

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" or "min" (default). 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. 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.

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).

dof.type

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

Format

An object of class function of length 1.

Value

It returns a dof.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.

See also

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 dof(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, dof = dof(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, dof = dof(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.079171 0.281686 0.281061 0.805072 #> --- #> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 #> RMSE: 0.873241 Adj. R2: -1.7512 #> Within R2: 0.003658
attributes(vcov(est, attr = TRUE))[c("dof.type", "dof.K")]
#> $dof.type #> [1] "dof(adj = TRUE, fixef.K = 'nested', cluster.adj = TRUE, cluster.df = 'min', t.df = 'min', fixef.force_exact = FALSE)" #> #> $dof.K #> [1] 6 #>
# fixef.K = FALSE # => adjustment K = 1 (i.e. only x) summary(est, dof = dof(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.079171 0.187791 0.421592 0.714314 #> --- #> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 #> RMSE: 0.873241 Adj. R2: -1.7512 #> Within R2: 0.003658
attr(vcov(est, dof = dof(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, dof = dof(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.079171 0.398364 0.19874 0.860837 #> --- #> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 #> RMSE: 0.873241 Adj. R2: -1.7512 #> Within R2: 0.003658
attr(vcov(est, dof = dof(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, dof = dof(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.079171 0.325263 0.243406 0.83038 #> --- #> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1 #> RMSE: 0.873241 Adj. R2: -1.7512 #> Within R2: 0.003658
attr(vcov(est, dof = dof(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 dof: # # eg no small sample adjustment: setFixest_dof(dof(adj = FALSE)) # Factory default setFixest_dof()