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
This works for an unbalanced data with effect="individual"
and time dummies y ~ x +factor(year)
:
fitted <- pmodel.response(plm.model)-residuals(plm.model)
Edit: adapted to two-ways unbalanced model, needs plm version >= 2.4-0
Is this what you wanted? Extract the fixed effects by fixef
. Here is an example for the Grunfeld data on an unbalanced two-way model (works the same for the balanced two-way model):
gtw_u <- plm(inv ~ value + capital, data = Grunfeld[-200, ], effect = "twoways")
yhat <- as.numeric(gtw_u$model[ , 1] - gtw_u$residuals) # reference
pred_beta <- as.numeric(tcrossprod(coef(gtw_u), as.matrix(gtw_u$model[ , -1])))
pred_effs <- as.numeric(fixef(gtw_u, "twoways")) # sum of ind and time effects
all.equal(pred_effs + pred_beta, yhat) # TRUE -> matches fitted values (yhat)
If you want to split the sum of individual and time effects (given by effect = "twoways"
) in its components, you will need to choose a reference and two come naturally to mind which are both given below:
# Splits of summed up individual and time effects:
# use one "level" and one "dfirst"
ii <- index(gtw_u)[[1L]]; it <- index(gtw_u)[[2L]]
eff_id_dfirst <- c(0, as.numeric(fixef(gtw_u, "individual", "dfirst")))[ii]
eff_ti_dfirst <- c(0, as.numeric(fixef(gtw_u, "time", "dfirst")))[it]
eff_id_level <- as.numeric(fixef(gtw_u, "individual"))[ii]
eff_ti_level <- as.numeric(fixef(gtw_u, "time"))[it]
all.equal(pred_effs, eff_id_level + eff_ti_dfirst) # TRUE
all.equal(pred_effs, eff_id_dfirst + eff_ti_level) # TRUE
(This is based on the man page of fixef, ?fixef
. There it is also shown how the (balanced and unbalanced) one-way model is to be handled).
I found this that can help you, since the lm() solution was not working in my case (I got different coefficients comparing to the plm package)
Therefore, it is just about applying the suggestions by the authors of the plm package here http://r.789695.n4.nabble.com/fitted-from-plm-td3003924.html
So what I did is just to apply
plm.object <- plm(y ~ lag(y, 1) + z +z2, data = mdt, model= "within", effect="twoways")
fitted <- as.numeric(plm.object$model[[1]] - plm.object$residuals)
where I need the as.numeric function since I need to use it as a vector to plug in for further manipulations. I also want to point out that if your model has a lagged dependent variable on the right hand side, the solution above with as.numeric provides a vector already NET of the missing values because of the lag. For me this is exactly what I needed to.
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]