2011-03-20 · Coding Notes, Uncategorized

Using loops to run (and export) many regressions / Usando loops para correr (y exportar) múltiples regresiones

español The use of  loops becomes essential when needing to perform repetitive calculations. Looping has many advantages, for example, when needing to do corrections in all the calculations specifications. So here are some interesting features that you would like to do when implementing a loop to run many regressions, and export their outputs:

So assume that you want to estimate a number of econometric models that are quite similar in terms of the explanatory variables that are incorporated, but differ between them in terms of the dependent variables, for example : Model 1: outcome1=b1*x1+b2*x2+b3*X3+b4*X4+e Model 2: outcome2=b1*x1+b2*x2+b3*X3+b4*X4+e In addition you also want to progressively add sets of explanatory variables. So for instance you want to estimate: Model 1: outcome1=b1*x1+b2*x2+e Model 2: outcome1=b1*x1+b2*x2+b3*X3+b4*X4+e Model 3: outcome2=b1*x1+b2*x2+e Model 4: outcome2=b1*x1+b2*x2+b3*X3+b4*X4+e Of course the code should work for n number of explanatory variables and k number of explanatory vars. Let’s do it. [sourcecode language=“text” firstline=“1” highlight=“1,6,10,11,12,16,17,18,23,32,35,36,45,46,51,52,57,61,63,70,72” padlinenumbers=“false”] What I am going to do is to first define the sets of explanatory variables using separate globals, for instance: global CONTROLGROUP1 “x1 x2” global CONTROLGROUP2 “x3 x4” * And add the outcome variables into a global global OUTCOMES “outcomevar1 outcomevar2 “ /*Start by looping on the types of explanatory variables, in this case we have discrete and continuous variables for each discrete variable we are running a probit model, and for each ordinal variable we will run an ordinal probit model */ global TIPO “disc ord” foreach tipo of global TIPO { /*Here is an interesting feature: using vartyp to separate the outcome variables into groups of discrete and ordinal variables. In this case, the first loop will assign all discrete variables to the global OUTCOMEBYTYPE, the second loop will assign the ordinal variables to the global OUTCOMEBYTYPE and so on. */ vartyp $OUTCOMES, list(tipo') global OUTCOMEBYTYPE "r(varlist)’“ /*Now assign the appropiate regression methodology to each type of explanatory variable*/ if “tipo'"=="disc" { local method "dprobit" } else { local method "oprobit" } /\*Start the loop of outcomes to be regressed\*/ foreach outcome of global OUTCOMEBYTYPE { /\*We are not using replace and append when exporting output to tables, so we need to erase the output file if already exists\*/ capture confirm file reg\_outcome’.txt if !_rc { erase reg_outcome'.txt } else { \*no action when file not found } /\*Start the loop that accumulates explanatory variables. Using while instead of foreach will allow adding more sets of explanatory variables later\*/ global i = 1 global CONTROLS "$CONTROLGROUP1" while $i < 4 { /\*Finally, the lines for running the regression and exporting the output. It is important to use capture when doing this since if any of the regression ends in an error (for example due to no observations), the loop will continue\*/ capture noisily xi: method’ outcome' $CONTROLS if respondiente==1 [fweight=pesosf] capture noisily outreg2 using reg\_outcome’.txt, append bdec(6) e(all) *The following lines do the trick to add the explanatory sets of variables global i = $i + 1 global CONTROLS “$CONTROLS ${CONTROLGROUP$i}” *Close explanatory variables loop } /* Use this space to add other alternative specifications*/ macro drop CONTROLS macro drop i *Close outcomes loop } *Close type loop } [/sourcecode] El uso de loops se hace imprescindible cuando se necesita  realizar cálculos repetitivos. Utilizar loops  tiene muchas ventajas, por ejemplo, si es necesario  hacer correcciones en todas las especificaciones de los cálculos deaseados, va a simplificar el trabajo. Así que aquí les presento  algunas características deseables en la  implementación de un loop que  ejecuta un gran número de regresiones, y exporta sus resultados:

Entonces supongamos que deseamos  estimar una serie de modelos econométricos que son bastante similares en términos de las variables explicativas que se incorporan, pero se diferencian entre ellos en términos de las variables dependientes, por ejemplo: Modelo 1: outcome1 = b1 + b2 * x1 * x2 + b3 X3 + X4 * b4 + e Modelo 2: outcome2 = b1 + b2 * x1 * x2 + b3 X3 + X4 * b4 + e Además también quiere añadir progresivamente conjuntos de variables explicativas. Así por ejemplo se desea estimar: Modelo 1: outcome1 = b1 + b2 * x1 * x2 + e Modelo 2: outcome1 = b1 + b2 * x1 * x2 + b3 X3 + X4 * b4 + e Modelo 3: outcome2 = b1 + b2 * x1 * x2 + e Modelo 4: outcome2 = b1 + b2 * x1 * x2 + b3 X3 + X4 * b4 + e Por supuesto, el código debería funcionar para un número n de variables explicativas y un número k de variables explicativas. Vamos a hacerlo: [sourcecode language=“text” firstline=“1” highlight=“1,6,10,11,12,16,17,18,23,32,35,36,45,46,51,52,57,61,63,70,72” padlinenumbers=“false”] /*Lo voy a hacer primero es definir conjuntos de variables explicativas utilizando globals, por ejemplo:*/ global CONTROLGROUP1 “x1 x2” global CONTROLGROUP2 “x3 x4” * Y también agregar las variables dependientes en el global OUTCOMES global OUTCOMES “outcomevar1 outcomevar2 “ /*Empiezo por generando un loop sobre los tipos de las variables a explicar, en este caso tenemos variables discretas 0-1 y ordinales. Para cada variable discreta 0-1 vamos a correr un modelo probit, y para cada variable ordinal vamos a correr un ordinal probit */ global TIPO “disc ord” foreach tipo of global TIPO { / * Esta es una característica interesante: el uso de vartyp para separar las variables dependientes en grupos de variables discretas y ordinales. En este caso, en la primera iteracion del loop asignará todas las variables discretas al global OUTCOMEBYTYPE,la segunda asignan las variables ordinales a OUTCOMEBYTYPE y así sucesivamente. * / vartyp $OUTCOMES, list(tipo') global OUTCOMEBYTYPE "r(varlist)’“ / * Ahora asigne la metodología de regresión apropiada para cada tipo de variable explicativa * / if “tipo'"=="disc" { local method "dprobit" } else { local method "oprobit" } / \* Iniciar el loop de los variables dependientes sobre las cuales se estimara\* / foreach outcome of global OUTCOMEBYTYPE { / \* Al no utilizar replace y append al exportar el resultado de las regresiones, tendremos que borrar el archivo de salida si ya existe \* / capture confirm file reg\_outcome’.txt if !_rc { erase reg_outcome'.txt } else { \* Ninguna acción si no encuentra el archivo } / \* Inicia el loop que acumula variables explicativas. Utilizar <em>while</em> en lugar de foreach permitirá añadir facilmente más grupos de variables explicativas \* / global i = 1 global CONTROLS "$CONTROLGROUP1" while $i < 4 { / \* Por último, las líneas para correr la regresión y exportar los resultados. Es importante la utilización de capture al hacer esto ya que si cualquiera de las iteraciones de la regresión presenta error (por ejemplo, debido a que una iteracion no presenta observaciones), el loop continuará y no se quedará frenará ante el error\* / capture noisily xi: method’ outcome' $CONTROLS if respondiente==1 [fweight=pesosf] capture noisily outreg2 using reg\_outcome’.txt, append bdec(6) e(all) *Las siguientes lineas hacen el truco para añadir los grupos de variables explicativas global i = $i + 1 global CONTROLS “$CONTROLS ${CONTROLGROUP$i}” *Cerrar el loop de variables explicativas } /* Puedo utilizar este espacio para correr otra especificacion que no siga el formato general del loop*/ macro drop CONTROLS macro drop i *cerrar el loop de variables dependientes } *cerrar el loop de tipos } [/sourcecode]

Export outputExportar resultadosLoopsRegressionStataTablasTables