plm: using fixef() to manually calculate fitted values for a fixed effects twoways model

后端 未结 4 954
北恋
北恋 2021-02-19 21:44

Please note: I am trying to get the code to work with both time & individual fixed effects, and an unbalanced dataset. The sample code below works

4条回答
  •  日久生厌
    2021-02-19 22:33

    I'm getting pretty close with Helix123's suggestion to subtract the within_intercept (it gets included in each of the two fixed effects, so you need to correct for that).

    There's a very suggestive pattern in my reconstruction errors: individual a is always off by -0.004858712 (for every time period). Individuals b, c, d are always off by 0.002839703 for every time period except in period 4 (where there is no observation for a), where they're off by -0.010981192.

    Any ideas? It looks like the individual fixed effects are thrown off by unbalancing. Rerunning it balanced works correctly.

    Full code:

    DT <- data.table(CJ(id=c("a","b","c","d"), time=c(1:10)))
    DT[, x1:=rnorm(40)]
    DT[, x2:=rnorm(40)]
    DT[, y:= x1 + 2*x2 + rnorm(40)/10]
    DT <- DT[!(id=="a" & time==4)] # just to make it an unbalanced panel
    setkey(DT, id, time)
    
    plmFEit <- plm(formula=y ~ x1 + x2,
                   data=DT,
                   index=c("id","time"),
                   effect="twoways",
                   model="within")
    
    summary(plmFEit)
    
    DT[, resids := residuals(plmFEit)]
    
    FEI <- data.table(as.matrix(fixef(plmFEit, effect="individual", type="level")), keep.rownames=TRUE) # as.matrix needed to preserve the names?
    setnames(FEI, c("id","fei"))
    setkey(FEI, id)
    setkey(DT, id)
    DT <- DT[FEI] # merge the fei into the data, each id gets a single number for every row
    
    FET <- data.table(as.matrix(fixef(plmFEit, effect="time", type="level")), keep.rownames=TRUE) # as.matrix needed to preserve the names?
    setnames(FET, c("time","fet"))
    FET[, time := as.integer(time)] # fixef returns time as character
    setkey(FET, time)
    setkey(DT, time)
    DT <- DT[FET] # merge the fet into the data, each time gets a single number for every row
    
    DT[, fitted.calc := plmFEit$coefficients[[1]] * x1 + plmFEit$coefficients[[2]] * x2 +
         fei + fet - within_intercept(plmFEit)]
    
    DT[, myresids := y - fitted.calc]
    DT[, myerr := resids - myresids]
    

提交回复
热议问题