避免使用summary.plm

7
我正在使用R运行蒙特卡罗模拟,研究面板数据估计器的性能。因为我将运行大量试验,所以我需要从我的代码中获得至少不错的性能。
在我的模拟的10个试验中使用Rprof显示,相当一部分时间花费在调用summary.plm上。下面提供了Rprofsummary的前几行:
$by.total
                            total.time total.pct self.time self.pct
"trial"                          54.48     100.0      0.00      0.0
"coefs"                          53.90      98.9      0.06      0.1
"model.matrix"                   36.72      67.4      0.10      0.2
"model.matrix.pFormula"          35.98      66.0      0.06      0.1
"summary"                        33.82      62.1      0.00      0.0
"summary.plm"                    33.80      62.0      0.08      0.1
"r.squared"                      29.00      53.2      0.02      0.0
"FUN"                            24.84      45.6      7.52     13.8

我在我的代码中调用summary,因为我需要获取系数估计的标准误差以及系数本身(我可以从plm对象中获取)。我的调用如下:

regression <- plm(g ~ y0 + Xit, data=panel_data, model=model, index=c("country","period"))

coefficients_estimated <- summary(regression)$coefficients[,"Estimate"]
ses_estimated <- summary(regression)$coefficients[,"Std. Error"]

我有一种难以摆脱的感觉,认为这是对CPU时间的巨大浪费,但我不了解R如何处理事情,无法避免调用summary。如果您能提供有关背后发生的事情的任何信息或缩短执行时间的方法,我将不胜感激。


1
嗯,第一个想法是将这两个摘要调用组合起来。我会尝试一下,看看是否有所帮助... - Wilduck
将这两个摘要调用组合确实有很大帮助,但 summary.plm 仍然是一个主要的资源占用程序。 - Wilduck
3个回答

6

您只需查看plm:::summary.plm内部的内容即可了解其功能。当您查看时,您会发现您对模型拟合调用summary()的两行可以替换为:

coefficients_estimated <- coef(regression)
ses_estimated <- sqrt(diag(vcov(regression)))

例如:

require(plm)
data("Produc", package = "plm")
zz <- plm(log(gsp) ~ log(pcap) + log(pc) + log(emp) + unemp, 
          data = Produc, index = c("state","year"))

summary(zz) 的输出结果如下:

> summary(zz)
Oneway (individual) effect Within Model

....

Coefficients :
             Estimate  Std. Error t-value  Pr(>|t|)    
log(pcap) -0.02614965  0.02900158 -0.9017    0.3675    
log(pc)    0.29200693  0.02511967 11.6246 < 2.2e-16 ***
log(emp)   0.76815947  0.03009174 25.5273 < 2.2e-16 ***
unemp     -0.00529774  0.00098873 -5.3582 1.114e-07 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 
....

对于zz,我展示的两行代码返回值为:

> coef(zz)
   log(pcap)      log(pc)     log(emp)        unemp 
-0.026149654  0.292006925  0.768159473 -0.005297741 
> sqrt(diag(vcov(zz)))
   log(pcap)      log(pc)     log(emp)        unemp 
0.0290015755 0.0251196728 0.0300917394 0.0009887257

您没有提供足够的信息(例如模拟代码或Rprof()的完整输出),以便确定这是否有所帮助 - 它看起来肯定不会花费大量时间在summary()上; FUN比您展示的任何其他内容都更加昂贵,而您展示的元素中,只有r.squared()出现在plm :::summary.plm()中,并且似乎根本不需要时间。
因此,以上内容是否显着加快速度还有待观察。

你说得对,速度影响可以忽略不计。就像我在评论中指出的那样,将调用缩减为一个 (~30% 时间缩短) 后,我的效率显著提高了。我没有想到去查看 summary.plm 在做什么,所以很感谢你为将来的问题提供的见解。关于你建议查看"FUN",我不确定"FUN"指的是什么。我认为它是一个应用程序的参数,但我并没有任何"apply loops"…是否有一种简便的方法可以找出"FUN"是什么?无论如何,答案已被接受。谢谢。 - Wilduck
@Wilduck FUN通常是应用于数据块的函数参数名称。我们没有您的模拟代码,因此很难说FUN是什么,但是您是否使用了apply()sapply()lapply()等函数族? - Gavin Simpson
是的,这正是我想的。我没有在大块数据上使用任何apply函数族,所以问题肯定出在别处。在我彻底检查代码之前,我不会让你再去看我的模拟代码。非常感谢你的帮助。 - Wilduck

2

只需使用coeftest(zz)coeftestlmtest包中;它将比summary.plm更快地为您提供来自plm对象的系数和标准误差。


2
如果您想进一步了解,可以查看plm:::plm的实际功能代码。在调用plm:::plm.fit之前,会进行大量参数检查。如果确实想要,您可以直接跳过到plm.fit
最后一点,您提到您的问题是蒙特卡罗模拟。您能否利用并行计算来提高速度?

好的观点,可惜该函数没有从?plm链接过来,我想知道@Wilduck是否可以利用一个重型计算核心。在浏览了plm()的帮助后,我放弃了寻找。 - Gavin Simpson
正如你所指出的,我认为查看FUN可能是@wilduck最好的选择。 - csgillespie
我计划利用并行计算,因为蒙特卡罗方法是令人尴尬的并行,我认为使用foreach会非常有效。 - Wilduck

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接