17 mar 2019

Usar el bucle for para guardar resultados de la estimación de una regresión

En la siguiente entrada, se muestra cómo utilizar el buche for, para guardar resultados estimados en una regresión lineal simple (lm), sea en un vector o en una matriz. En el ejemplo siguiente, se utiliza la base de datos iris, que contiene las siguientes variables:

head(iris)
  Sepal.Length Sepal.Width Petal.Length Petal.Width Species
1          5.1         3.5          1.4         0.2  setosa
2          4.9         3.0          1.4         0.2  setosa
3          4.7         3.2          1.3         0.2  setosa
4          4.6         3.1          1.5         0.2  setosa
5          5.0         3.6          1.4         0.2  setosa
6          5.4         3.9          1.7         0.4  setosa

En el ejemplo, se estima mediante lm, un modelo de regresión simple de la primera variable (iris[,1] == Sepal.Length) en función de la segunda, tercera y cuarta variable, respectivamente (iris[,i] == Sepal.Length). Véase de forma directa, como este ejemplo se puede extender a cualquier número de variables, o inclusive utilizar indexación para identificar de forma automática las variables de un data.frame que cumple con alguna condición.

# --------------------------------
head(iris)
for (i in 2:4){
  mod<-lm(iris[,1]~iris[,i])
}
summary(mod)

O de forma alternativa, se puede utilizar la opción get() para llamar variables directamente, a partir de un vector de nombres:

Sepal.Length = b0 + b1*Sepal.Width
Sepal.Length = b0 + b1*Petal.Length
Sepal.Length = b0 + b1*Petal.Width

# --------------------------------
attach(iris)
var<-names(iris)[2:4]
 
> var
[1] "Sepal.Width"  "Petal.Length" "Petal.Width" 
 
for (i in var){
  mod<-lm(Sepal.Length~get(i))
}

El problema con las secuencias anteriores, es que pese a realizar un número determinado de regresiones, los resultados estimados no son guardados. Por lo que, en los siguientes ejemplos se muestra cómo se pueden guardar los resultados. Note como se crea un vector vacío (sumResid) que posteriormente se va completando con la suma de los residuos (mod$residuals) al cuadrado que se obtiene en la estimación de cada regresión de manera sucesiva [c(sumResid, sum(mod$residuals))].

# Guardar la suma de los residuos de cada regresión
# --------------------------------
sumResid <-c()
 
for (i in var){
  mod<-lm(Sepal.Length~get(i))
  sumResid <-c(sumResid, sum(mod$residuals)) 
}

> sumResid
[1] -4.982126e-15  9.992007e-16 -5.516421e-16

En un ejemplo final, en vez de guardar un vector 1x1 en cada iteración del bucle, es posible guardar un vector de coeficientes estimados en cada una de las regresiones (mod$coefficients). Ahora, en vez de ir anexando un escalar a un vector determinado, como hicimos en el ejemplo anterior, se va agregando un vector de coeficientes (coeff), a la matriz de coeficientes estimados que se va completando, utilizando el comando rbind.

# Guardar los coeficientes
# --------------------------------
coeff <-c()
 
for (i in var){
  mod<-lm(Sepal.Length~get(i))
  coeff <-rbind(coeff, mod$coefficients) 
}

> coeff
     (Intercept)     get(i)
[1,]    6.526223 -0.2233611
[2,]    4.306603  0.4089223

[3,]    4.777629  0.8885803

Recesión plot en R usando ggplot (recession plot in r)

En el siguiente ejemplo se simular y replica -parcialmente- un ejemplo usado por el FMI para ilustrar la importancia del uso de series de ti...