[英]plm: using fixef() to manually calculate fitted values for a fixed effects twoways model
請注意:我試圖讓代碼同時處理時間和個人固定效應以及不平衡的數據集。 下面的示例代碼適用於平衡數據集。
也請參閱下面的編輯
我正在嘗試使用plm
包手動計算固定效應模型(具有個體效應和時間效應)的擬合值。 這更像是一個練習,以確認我了解模型和包的機制,我知道我可以從plm
對象,從兩個相關問題( 此處和此處)中獲取擬合值本身。
從plm
小插圖 (p.2),底層模型是:
y _it = alpha + beta _transposed * x _it + ( mu _i + lambda _t + epsilon _it)
其中 mu_i 是誤差項的單個分量(又名“個體效應”),而 lambda_t 是“時間效應”。
可以通過使用fixef()
提取固定效應,我想我可以使用它們(與自變量一起)來計算模型的擬合值,使用(使用兩個自變量)以這種方式:
擬合_it = alpha + beta _1 * x1 + beta _2 * x2 + mu _i + lambda _t
這就是我失敗的地方——我得到的值遠不及擬合值(我得到的是模型對象中實際值和殘差之間的差異)。 一方面,我在任何地方都看不到alpha
。 我嘗試將固定效果顯示為與第一個、平均值等的差異,但沒有成功。
我缺少什么? 這很可能是對模型的誤解,或者是代碼中的錯誤,恐怕……提前致謝。
PS:其中一個相關問題暗示pmodel.response()
應該與我的問題有關(以及沒有plm.fit
函數的原因),但它的幫助頁面並不能幫助我理解該函數的實際作用,我找不到任何示例來解釋它產生的結果。
謝謝!
我所做的示例代碼:
library(data.table); library(plm)
set.seed(100)
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)
summary(plmFEit <- plm(data=DT, id=c("id","time"), formula=y ~ x1 + x2, model="within", effect="twoways"))
# Extract the fitted values from the plm object
FV <- data.table(plmFEit$model, residuals=as.numeric(plmFEit$residuals))
FV[, y := as.numeric(y)]
FV[, x1 := as.numeric(x1)]
FV[, x2 := as.numeric(x2)]
DT <- merge(x=DT, y=FV, by=c("y","x1","x2"), all=TRUE)
DT[, fitted.plm := as.numeric(y) - as.numeric(residuals)]
FEI <- data.table(as.matrix(fixef(object=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(object=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
# calculate the fitted values (called calc to distinguish from those from plm)
DT[, fitted.calc := as.numeric(coef(plmFEit)[1] * x1 + coef(plmFEit)[2]*x2 + fei + fet)]
DT[, diff := as.numeric(fitted.plm - fitted.calc)]
all.equal(DT$fitted.plm, DT$fitted.calc)
我的會話如下:
R version 3.2.2 (2015-08-14)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 8 x64 (build 9200)
locale:
[1] LC_COLLATE=English_United States.1252 LC_CTYPE=English_United States.1252 LC_MONETARY=English_United States.1252 LC_NUMERIC=C
[5] LC_TIME=English_United States.1252
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] plm_1.4-0 Formula_1.2-1 RJSONIO_1.3-0 jsonlite_0.9.17 readxl_0.1.0.9000 data.table_1.9.7 bit64_0.9-5 bit_1.1-12 RevoUtilsMath_3.2.2
loaded via a namespace (and not attached):
[1] bdsmatrix_1.3-2 Rcpp_0.12.1 lattice_0.20-33 zoo_1.7-12 MASS_7.3-44 grid_3.2.2 chron_2.3-47 nlme_3.1-122 curl_0.9.3 rstudioapi_0.3.1 sandwich_2.3-4
[12] tools_3.2.2
編輯:(2015-02-22)由於這引起了一些興趣,我將嘗試進一步澄清。 我試圖擬合一個“固定效應”模型(又名“內部”或“最小二乘虛擬變量”,正如plm 包小插圖在第 3 頁上的段落中所稱的那樣)——相同的斜率,不同的截距。
這與在為time
和id
添加虛擬變量后運行普通 OLS 回歸相同。 使用下面的代碼,我可以使用 base lm()
從plm
包中復制擬合值。 對於假人,很明顯 id 和 time 的第一個元素是要比較的組。 我仍然不能做的是如何使用plm
包的功能來做同樣的事情,我可以使用lm()
輕松完成。
# fit the same with lm() and match the fitted values to those from plm()
lmF <- lm(data = DT, formula = y ~ x1 + x2 + factor(time) + factor(id))
time.lm <- coef(lmF)[grep(x = names(coef(lmF)), pattern = "time", fixed = TRUE)]
time.lm <- c(0, unname(time.lm)) # no need for names, the position index corresponds to time
id.lm <- coef(lmF)[grep(x = names(coef(lmF)), pattern = "id", fixed = TRUE)]
id.lm <- c(0, unname(id.lm))
names(id.lm) <- c("a","b","c","d") # set names so that individual values can be looked up below when generating the fit
DT[, by=list(id, time), fitted.lm := coef(lmF)[["(Intercept)"]] + coef(lmF)[["x1"]] * x1 + coef(lmF)[["x2"]] * x2 + time.lm[[time]] + id.lm[[id]]]
all.equal(DT$fitted.plm, DT$fitted.lm)
希望這對其他可能感興趣的人有用。 問題可能與plm
和fixef
如何處理我有意創建的缺失值有關。 我嘗試使用fixef
的type=
參數,但沒有效果。
這適用於具有effect="individual"
和時間假人y ~ x +factor(year)
的不平衡數據:
fitted <- pmodel.response(plm.model)-residuals(plm.model)
我發現這可以幫助你,因為 lm() 解決方案在我的情況下不起作用(與 plm 包相比,我得到了不同的系數)
因此,這只是應用 plm 包作者的建議http://r.789695.n4.nabble.com/fitted-from-plm-td3003924.html
所以我所做的只是申請
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)
我需要 as.numeric 函數的地方,因為我需要將它用作向量來插入以進行進一步的操作。 我還想指出,如果您的模型在右側有一個滯后的因變量,那么上面的 as.numeric 解決方案提供了一個向量,由於滯后,已經包含缺失值的 NET。 對我來說,這正是我需要的。
我非常接近 Helix123 的建議,即減去within_intercept
(它包含在兩個固定效果中的每一個中,因此您需要對此進行更正)。
我的重建錯誤中有一個非常具有啟發性的模式:個體a
總是偏離 -0.004858712(對於每個時間段)。 個體b, c, d
在每個時間段總是偏離 0.002839703,除了在第 4 期(沒有觀察a
),它們偏離 -0.010981192。
有什么想法嗎? 看起來個體的固定效應被不平衡所拋棄。 重新運行它平衡工作正常。
完整代碼:
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]
編輯:適應雙向不平衡模型,需要plm版本>= 2.4-0
這是你想要的嗎? 通過fixef
提取固定效應。 以下是非平衡雙向模型上的 Grunfeld 數據示例(對平衡雙向模型的工作方式相同):
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)
如果您想在其組件中拆分個體和時間效果的總和(由effect = "twoways"
),您需要選擇一個參考,並且很自然地想到兩個,如下所示:
# 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
(這是基於 fixef 的手冊頁?fixef
。那里還展示了如何處理(平衡和非平衡)單向模型)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.