Índice
1. Introducción 2. Acceder y conocer
la base 3. Estimar el modelo 4. Predicción puntual e intervalos de confianza
Este es un documento de trabajo, contiene ejemplos para aplicar modelos de regresión lineal simple con los datos del libro de texto del curso de Econometría 1, Wooldridge 2010-Introducción a la Econometría (4ta edución). El mismo fue elaborado en Markdown utilizando R studio (software que vemos en el curso). Aquí se encuentran detalles para utilizar R Markdown http://rmarkdown.rstudio.com.
El R permite instalar la librería Wooldridge de la siguiente manera.
if(!require(‘wooldridge’)) { install.packages(‘wooldridge’) library(‘wooldridge’) }
Esto es equivalente a lo siguiente: install.packages(“wooldridge”) #la instalo si es la primera vez que la llamo. library(wooldridge) #la llamo una vez que ya la tengo instalada.
En ella encontrará todas las bases de datos que contiene el libro, utilizando el mismo nombre con el que son referenciadas en el texto. A modo de ejemplo, trabajaremos con la base wage1 que contiene datos de la Encuesta de población de 1976, recopilados por Henry Farber cuando él y Wooldridge eran colegas en el MIT en 1988.
Para cargar los datos se escribe data(“wage1”) # carga la base salarios base <-wage1 # la asigno al objeto base con el que trabaremos
Acceso a la base y solicito los nombres de las variables:
library(wooldridge)
base <-data("wage1")
base <-wage1
#View(base)
names(base)
## [1] "wage" "educ" "exper" "tenure" "nonwhite" "female"
## [7] "married" "numdep" "smsa" "northcen" "south" "west"
## [13] "construc" "ndurman" "trcommpu" "trade" "services" "profserv"
## [19] "profocc" "clerocc" "servocc" "lwage" "expersq" "tenursq"
Las variables que utilizaremos son las siguientes:
Cambio el nombre de la variable que está en la posición 4
names(base)[4]<-"antiguedad"
Selecciono las variables que me interesan por la posición de las columnas en el data frame. Indico que quiero las variables que están desde la posición 1 hasta la 7 y las que están en la posición 22, 23 y 24
base1<-base[,c(1: 7, 22, 23, 24)]
Miro las observaciones de las primeras 5 personas de la base:
head(base1, n=5)
## wage educ exper antiguedad nonwhite female married lwage expersq tenursq
## 1 3.10 11 2 0 0 1 0 1.131402 4 0
## 2 3.24 12 22 2 0 1 1 1.175573 484 4
## 3 3.00 11 2 0 0 0 0 1.098612 4 0
## 4 6.00 8 44 28 0 0 1 1.791759 1936 784
## 5 5.30 12 7 2 0 0 1 1.667707 49 4
También se puede seleccionar utilizando el nombre de las variables
datos1<-base[,c("wage","educ","exper", "antiguedad" )]
head(datos1, n=5)
## wage educ exper antiguedad
## 1 3.10 11 2 0
## 2 3.24 12 22 2
## 3 3.00 11 2 0
## 4 6.00 8 44 28
## 5 5.30 12 7 2
Otra forma mas sencilla de seleccionar la base es utilizar la función select del paquete dplyr, se usa el comando llamado pipe %>%, el mismo enlaza las órdenes de manera secuencial.
Si es la primera vez que se usa recordar instalarlo: #install.packages(“dplyr”)
library(dplyr)
##
## Attaching package: 'dplyr'
## The following objects are masked from 'package:stats':
##
## filter, lag
## The following objects are masked from 'package:base':
##
## intersect, setdiff, setequal, union
datos2<-base %>%
select("wage", "educ", "exper", "antiguedad")
head(datos2, n=5)
## wage educ exper antiguedad
## 1 3.10 11 2 0
## 2 3.24 12 22 2
## 3 3.00 11 2 0
## 4 6.00 8 44 28
## 5 5.30 12 7 2
Lo puedo combinar con un filtro por filas con la función filter del paquete dplyr. Selecciono solo a las personas casadas.
datos3<-base %>%
select("wage", "educ", "exper", "antiguedad", "married")%>%
filter(married==1)
#View(datos3)
plot(datos2)
Calculo la matriz de correlaciones de las variables que figuran en datos
cor(datos2)
## wage educ exper antiguedad
## wage 1.0000000 0.40590333 0.1129034 0.34688957
## educ 0.4059033 1.00000000 -0.2995418 -0.05617257
## exper 0.1129034 -0.29954184 1.0000000 0.49929145
## antiguedad 0.3468896 -0.05617257 0.4992914 1.00000000
Existe una correlación positiva entre el salario y la educación (0.4059)
Por el momento vamos a trabajar solo con el salario (wage) y educación (educ) en un MRLS.
Creamos el diagrama de dispersión entre salario y educación. Utilizaremos la librería ggplot2.
#install.packages("ggplot2")
library(ggplot2)
ggplot(datos2, aes(x=educ, y=wage)) +
geom_point() + theme_light() +
ggtitle("Relación entre salario y educación")
Estimo un MRLS con el método Mínimos cuadrados ordinarios (en adelante MCO)
mod1 <- lm(wage ~ educ, data=datos2)
summary(mod1) #para imprimir la salida
##
## Call:
## lm(formula = wage ~ educ, data = datos2)
##
## Residuals:
## Min 1Q Median 3Q Max
## -5.3396 -2.1501 -0.9674 1.1921 16.6085
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -0.90485 0.68497 -1.321 0.187
## educ 0.54136 0.05325 10.167 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 3.378 on 524 degrees of freedom
## Multiple R-squared: 0.1648, Adjusted R-squared: 0.1632
## F-statistic: 103.4 on 1 and 524 DF, p-value: < 2.2e-16
Interpretar la estimación de los parámetros.
Incluyo la recta de regresión al gráfico de dispersión
ggplot(datos2, aes(x=educ, y=wage)) +
geom_point() +
geom_smooth(method='lm', formula=y~x, se=FALSE, col='dodgerblue1') +
theme_light() +
ggtitle("Relación entre salario y educación")
Es posible obtener un gráfico de dispersión interactivo, me paro en cada observación y veo los valores. Necesita la función plotly
library(plotly)
##
## Attaching package: 'plotly'
## The following object is masked from 'package:ggplot2':
##
## last_plot
## The following object is masked from 'package:stats':
##
## filter
## The following object is masked from 'package:graphics':
##
## layout
plot_ly(data=datos2, x=~educ, y=~wage)
## No trace type specified:
## Based on info supplied, a 'scatter' trace seems appropriate.
## Read more about this trace type -> https://plotly.com/r/reference/#scatter
## No scatter mode specifed:
## Setting the mode to markers
## Read more about this attribute -> https://plotly.com/r/reference/#scatter-mode
Miro los componentes del modelo y los asigno a nuevos objetos
names(mod1)
## [1] "coefficients" "residuals" "effects" "rank"
## [5] "fitted.values" "assign" "qr" "df.residual"
## [9] "xlevels" "call" "terms" "model"
coeficientes<- mod1$coefficients
ygorro<- mod1$fitted.values
resid<-mod1$residuals
Para consultar la estimación de un coeficiente de regresión se utilizan paréntesis rectos.
#View(coeficientes)
beta.estimate <- coeficientes["educ"]
print(beta.estimate)
## educ
## 0.5413593
Agrego a mis datos una nueva variable con los valores estimados según el MRLS.
datos2$predicciones <- predict(mod1)
head(datos2, 5)
## wage educ exper antiguedad predicciones
## 1 3.10 11 2 0 5.050100
## 2 3.24 12 22 2 5.591459
## 3 3.00 11 2 0 5.050100
## 4 6.00 8 44 28 3.426022
## 5 5.30 12 7 2 5.591459
Calculo los residuos
datos2$residuos <- datos2$wage-datos2$predicciones
head(datos2, 5)
## wage educ exper antiguedad predicciones residuos
## 1 3.10 11 2 0 5.050100 -1.9501003
## 2 3.24 12 22 2 5.591459 -2.3514594
## 3 3.00 11 2 0 5.050100 -2.0501002
## 4 6.00 8 44 28 3.426022 2.5739776
## 5 5.30 12 7 2 5.591459 -0.2914593
Comparo los residuos calculados con los que me dio el modelo
datos2$resid<- resid
datos2$verif<-datos2$residuos-datos2$resid
Agrego al gráfico de dispersión los ygorro en rojo y muestro los residuos
ggplot(datos2, aes(x=educ, y=wage)) +
geom_smooth(method="lm", se=FALSE, color="lightgrey") +
geom_segment(aes(xend=educ, yend=predicciones), col='red', lty='dashed') +
geom_point() +
geom_point(aes(y=predicciones), col='red') +
theme_light()
## `geom_smooth()` using formula 'y ~ x'
Inspección gráfica de los resididuos
plot(datos2$residuos)
Inspecciono las funciones de densidad estimadas
library(e1071) # for skewness function
par(mfrow=c(1, 2)) # divide graph area in 2 columns
plot(density(datos2$wage), main="Density Plot: salario", ylab="Frequency", sub=paste("Skewness:", round(e1071::skewness(datos2$wage), 2))) # density para 'salario'
polygon(density(datos2$wage), col="red")
plot(density(datos2$residuos), main="Density Plot: residuos", ylab="Frequency", sub=paste("Skewness:", round(e1071::skewness(datos2$residuos), 2))) # density para los 'residuos'
polygon(density(datos2$residuos), col="red")
Genero la predicción puntual y el intervalo de confianza para una educación de 10 años, prediction devuelve el valor para la predicción puntual
Calculo el salario esperado para una persona con la educación promedio
mean(datos2$educ)
## [1] 12.56274
sal_prom<-0.90485+0.054136*12.56
nuevo <- data.frame(educ=10)
future_y<-predict(object=mod1, newdata=nuevo, interval="prediction", level=0.95)
Genera el intervalo de confianza para el valor esperado de \(y\). Debemos cambiar el argumento de interval= “confidence”.
future_esp_y <- predict(object=mod1,newdata = nuevo, interval = "confidence", level = 0.95)
future_esp_y<-as.data.frame(future_esp_y)
IC_inf_esp_y<-future_esp_y$lwr
IC_sup_esp_y<-future_esp_y$upr
Genera el data frame completo, agregando los extremos de los intervalos de confianza
nuevos_datos <- cbind(datos2, future_y, IC_inf_esp_y, IC_sup_esp_y)
IC_y<-ggplot(nuevos_datos, aes(x=educ, y=wage))+
geom_point() +
geom_line(aes(y=lwr), color="red", linetype="dashed") +
geom_line(aes(y=upr), color="red", linetype="dashed") +
geom_smooth(method=lm, formula=y~x, se=TRUE, level=0.95, col='blue', fill='pink2') +
theme_light() + ggtitle("Precicción de y al 95%")
library(ggplot2)
IC_esp_y_95<-ggplot(nuevos_datos, aes(x=educ, y=wage))+
geom_point() +
geom_line(aes(y=IC_inf_esp_y), color="blue", linetype="dashed") +
geom_line(aes(y=IC_inf_esp_y), color="blue", linetype="dashed") +
geom_smooth(method=lm, formula=y~x, se=TRUE, level=0.95, col='blue', fill='pink2') +
theme_light() + ggtitle("predicción de E(y/x) al 95%")
Imprimo los gráficos juntos para poder compararlos mejor. ¿Cuál de los dos tiene mayor amplitud?
#nstall.packages("gridExtra")
library(gridExtra)
##
## Attaching package: 'gridExtra'
## The following object is masked from 'package:dplyr':
##
## combine
grid.arrange(IC_esp_y_95, IC_y, ncol=2,nrow=1)
Veo el efecto de los niveles de confianza.
library(ggplot2)
#install.packages("jtools")
#install.packages("ggstance")
#install.packages("broom.mixed")
library(jtools)
library(ggstance)
##
## Attaching package: 'ggstance'
## The following objects are masked from 'package:ggplot2':
##
## geom_errorbarh, GeomErrorbarh
library(broom.mixed)
## Registered S3 methods overwritten by 'broom':
## method from
## tidy.glht jtools
## tidy.summary.glht jtools
a=plot_summs (mod1 , escala = TRUE , plot.distributions = TRUE , inner_ci_level = .90)
b=plot_summs (mod1 , escala = TRUE , plot.distributions = TRUE , inner_ci_level = .7)
library(gridExtra)
grid.arrange(a, b, ncol=1,nrow=2)