Search code examples
rplmstandard-error

how are the Degrees of freedom calculated in plm:::vcovDC.plm?


I use a fixed effect model with time and group fixed effects. Further, I want to calculate robust clustered standard errors. Therefore, I use coeftest(model, vcov = vcovDC(model))

I do not understand how the degrees of freedom are calculated for the provided t-statistics. Does it use the same degrees of freedom like the in the provided plm-fixed-effect model or are they adjusted. Probably my question is rather; are the degrees of freedom adjusted when one uses clustered standard errors for a two-way fixed effect model, or do they remain the same?


Solution

  • plm calculates an ordinary variance–covariance matrix (VCOV). When you use summary on your plm object (what you probably mean by "provided plm-fixed-effect model"), actually the plm:::summary.plm method is applied, which uses ordinary standard errors (SE) without degrees-of-freedom correction, until you change the vcov= argument defaulting to NULL to another VCOV calculated differently, e.g. with vcovCL or vcovDC.

    You can do lmtest::coeftest(fit, vcov.=...), or directly summary(fit, vcov=...), as I show you below in an example.

    Example

    library(plm)
    data(Cigar)
    fit <- plm(sales ~ price, data=Cigar, effect="twoways", model="within", 
               index=c("state", "year"))
    
    summary(fit)$coe   
    # same:
    summary(fit, vcov=NULL)$coe  ## default, ordinary SE
    #        Estimate Std. Error   t-value     Pr(>|t|)
    # price -1.084712 0.07554847 -14.35782 1.640552e-43
    

    Now, to get robust standard errors (without adjustment for clustering), we may use vcovCL and consider the type= argument. In ?sandwich::vcovCL we may read:

    HC0 applies no small sample bias adjustment. HC1 applies a degrees of freedom-based correction, (n-1)/(n-k) where n is the number of observations and k is the number of explanatory or predictor variables in the model.

    summary(fit, vcov=vcovHC)$coe
    # same:
    summary(fit, vcov=vcovHC(fit, type="HC0"))$coe  ## robust SE
    #        Estimate Std. Error   t-value     Pr(>|t|)
    # price -1.084712  0.2406786 -4.506889 7.168418e-06
    
    summary(fit, vcov=vcovHC(fit, type="HC1"))$coe  ## robust SE, df-corrected
    #        Estimate Std. Error   t-value    Pr(>|t|)
    # price -1.084712  0.2407658 -4.505256 7.22292e-06
    

    The same applies to vcovDC and its type= argument for robust standard errors, doubly adjusted for clustering on group and time:

    summary(fit, vcov=vcovDC(fit))$coe 
    # same:
    summary(fit, vcov=vcovDC(fit, type="HC0"))$coe  ## double-cluster-robust SE
    #        Estimate Std. Error  t-value     Pr(>|t|)
    # price -1.084712  0.2923507 -3.71031 0.0002157146
    
    summary(fit, vcov=vcovDC(fit, type="HC1"))$coe  ## double-cluster-robust SE, df-corrected 
    #        Estimate Std. Error   t-value     Pr(>|t|)
    # price -1.084712  0.2924567 -3.708966 0.0002168511