2011-04-11 20 views
6

Estoy usando R para ejecutar una simulación Monte-Carlo estudiando el rendimiento de los estimadores de datos de panel. Debido a que voy a ejecutar una gran cantidad de pruebas, necesito obtener al menos un rendimiento decente de mi código.R: evitando summary.plm

El uso de Rprof en 10 intentos de mi simulación muestra que una gran parte del tiempo se gasta en llamadas al summary.plm. Las primeras líneas de Rprofsummary se proporcionan a continuación:

$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 

estoy llamando summary en mi código, ya que necesito para obtener los errores estándar de las estimaciones de los coeficientes, así como los propios coeficientes (que podría conseguir de sólo el objeto plm). Mi llamado parece

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"] 

Tengo una sensación de que esto es una enorme pérdida de tiempo de CPU, pero no sé lo suficiente sobre cómo R hace cosas para evitar llamar resumen. Apreciaría cualquier información sobre lo que está sucediendo detrás de las escenas aquí, o alguna forma de reducir el tiempo que se necesita para que esto exceda.

+1

Hmmm, una primera idea es combinar las dos llamadas de resumen. Voy a probar eso, y ver si ayuda a las cosas ... – Wilduck

+0

La combinación de las dos llamadas de resumen ayuda bastante, pero summary.plm sigue siendo un gran cerdo. – Wilduck

Respuesta

6

Solo necesita mirar adentro plm:::summary.plm para ver lo que hace. Cuando lo haga, verá que sus dos líneas de llamada summary() del modelo de ajuste se pueden sustituir por:

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

Por ejemplo:

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) da:

> 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 
.... 

y las dos líneas que mostré devuelven para 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 

En realidad, no proporciona suficiente información (su código de simulación ni la salida completa de Rprof() por ejemplo) para indicar si esto ayudará, sin duda no parece que se gasten grandes cantidades de tiempo en summary(); FUN es mucho más costoso que cualquier otra cosa que muestre, y de los elementos que muestra, r.squared() es el único que aparece en plm:::summary.plm() y parece que no lleva mucho tiempo.

Por lo tanto, si lo anterior acelera las cosas apreciablemente aún está por verse.

+0

Tiene razón, hay un efecto insignificante en la velocidad. Como señalé en mi comentario sobre la pregunta, tuve un aumento significativo de la reducción a una llamada al resumen (~ 30% de reducción en el tiempo). No pensé en ver qué summary.plm estaba haciendo, así que aprecio esa idea para futuros problemas. En cuanto a tus consejos para mirar "DIVERSIÓN", no estoy seguro a qué se refiere "DIVERSIÓN". Pensaría en un argumento para aplicarlo, pero no tengo ningún bucle de aplicación ... ¿Hay alguna manera de descubrir fácilmente qué es "DIVERSIÓN"? En cualquier caso, respuesta aceptada. Gracias. – Wilduck

+0

@Wilduck 'FUN' es generalmente el nombre del argumento para una función que se aplicará a fragmentos de datos. No tenemos su código de simulación, por lo que es difícil decir qué 'FUN 'es, pero ¿está utilizando alguna de las familias' apply() ',' sapply() ',' lapply() ', etc.? –

+0

sí, eso es más o menos lo que pensaba. No estoy utilizando ninguna familia de aplicaciones en grandes cantidades de datos, por lo que debe ser algo más. No voy a hacer que revises mi código de simulación antes de que lo haya pasado con un peine de dientes finos. Gracias por toda tu ayuda. – Wilduck

2

Si desea ir más allá, eche un vistazo al código de función real de plm:::plm Notará que hay una gran cantidad de comprobación de argumentos, antes de una llamada final al plm:::plm.fit Podría (si realmente lo desea), omita directo a plm.fit.

Un último punto. Usted menciona que su problema es una simulación Monte Carlo. ¿Puedes aprovechar la informática paralela para aumentar la velocidad?

+0

Buen punto, lástima que la función no está vinculada a '? Plm' ya que me preguntaba si había un núcleo de cálculo de levantamiento pesado que @Wilduck podría aprovechar. Dejé de mirar una mirada superficial a la ayuda de 'plm()'. –

+0

Como usted señala, creo que mirar 'FUN' puede ser la mejor apuesta de @ wilduck. – csgillespie

+0

Planeo aprovechar el cómputo paralelo, ya que monte carlo es embarazosamente paralelo, estaba pensando que foreach funcionaría bastante bien. – Wilduck

1

Simplemente use coeftest(zz). coeftest está en el paquete lmtest; le dará los coeficientes y errores estándar de los objetos plm mucho más rápido que summary.plm.

Cuestiones relacionadas