【问题标题】:plm: using fixef() to manually calculate fitted values for a fixed effects twoways modelplm:使用 fixef() 手动计算固定效应双向模型的拟合值
【发布时间】:2013-10-13 03:10:22
【问题描述】:

请注意:我正在尝试让代码与 时间和个人固定效果以及 不平衡 数据集一起使用。下面的示例代码适用于平衡数据集。

请参阅下面的编辑

我正在尝试使用 plm 包手动计算固定效应模型(具有个体效应和时间效应)的拟合值。这更像是一个练习,以确认我了解模型和包的机制,我知道我可以从 plm 对象和两个相关问题(herehere)中获得拟合值。

plm vignette (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 package vignette 在第 3 页顶部段落中所说的那样)——相同的斜率,不同的截距。

这与为timeid 添加假人后运行普通OLS 回归相同。使用下面的代码,我可以使用基础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)

希望这对可能感兴趣的其他人有用。问题可能与plmfixef 如何处理我故意创建的缺失值有关。我尝试使用fixeftype= 参数,但没有效果。

【问题讨论】:

  • 您是在估计随机斜率和截距还是只是随机截距?
  • 请注意,您的示例代码也不适用于平衡面板。您需要DT[, fitted.calc := as.numeric(coef(plmFEit)[1] * x1 + coef(plmFEit)[2]*x2 + fei + fet - within_intercept(plmFEit))] 才能获得相同的值。 within_intercept(目前,仅在 plm 的开发版本中)给出了 FE 模型的整体(人工)截距。在这里,它解释了共享 ID/时间效应。
  • 谢谢。我最近没有使用过这个包,但是关于开发版本的信息很有用。我们离答案越来越近了:)

标签: r plm


【解决方案1】:

这适用于具有effect="individual" 和时间假人y ~ x +factor(year) 的不平衡数据:

fitted <- pmodel.response(plm.model)-residuals(plm.model)

【讨论】:

    【解决方案2】:

    我发现这可以帮助您,因为 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 的向量,因为存在滞后。对我来说,这正是我需要的。

    【讨论】:

    • 你好鲍勃,谢谢你的回答。它没有解决我需要的东西。我使用了与您建议的相同的东西(可能是在阅读了您链接到的线程之后)。我想做的是使用自变量和估计系数(包括时间/id 效应)来生成估计值。类似于我作为 lm() 示例添加的内容。
    • 这也是我想做的,但我没能做到。同样使用您的方法与 lm() 我从 plm 模型中得到不同的估计
    【解决方案3】:

    我非常接近 Helix123 的减去 within_intercept 的建议(它包含在两个固定效果中的每一个中,因此您需要对此进行更正)。

    在我的重建错误中有一个非常具有启发性的模式:单个 a 总是偏离 -0.004858712(对于每个时间段)。个人b, c, d 在第 4 期(没有观察到 a)的每个时间段除了总是偏离 0.002839703,他们偏离 -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]
    

    【讨论】:

    • 嗨 Toban,您能发布一个完整的代码吗?我没有在最后一行得到TRUE。另外,您是针对单个变量 X 而不是两个变量运行此操作吗?
    • 感谢您的检查。我以为我以前用我的代码工作过......我只是花了一些时间测试这个,试图让它与你的代码一起工作。我更新了我的答案,我觉得它非常接近,但无法指出问题所在。
    【解决方案4】:

    编辑:适配双向不平衡模型,需要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。其中还显示了如何处理(平衡和不平衡)单向模型)。

    【讨论】:

    • 您好,感谢您的发帖。您的代码有效,但本质上它只是我原始问题中代码的一个子集——(1)处理平衡的数据集,(2)只有一个效果,“个人”。如果您可以让它同时处理时间和个体效应以及不平衡的数据集(例如从 Grunfeld 删除一行),我很乐意接受它作为答案。
    • 谢谢!我真的很惊讶人们仍然找到精力和时间来解决 5 岁的问题:)
    • 我最初的回答是大约 5 岁。您最初的问题大约 7 年! ;)
    猜你喜欢
    • 1970-01-01
    • 2015-04-06
    • 1970-01-01
    • 1970-01-01
    • 2022-01-02
    • 1970-01-01
    • 2020-06-30
    • 2017-10-18
    • 1970-01-01
    相关资源
    最近更新 更多