En esta clase veremos como construir un pool de datos de panel utilizando múltiples bases de la EPH. El ejercicio consiste en analizar las transiciones individuales entre las distintas categorías y estados ocupacionales. Trabajaremos con un caso sencillo, sin reclasificar a la población en más que las categorías definidas por la EPH. A su vez, para maximizar la cantidad de casos del ejercicio utilizando las bases recientemente publicadas, trabajaremos con transiciones entre trimestres (Aunque en la práctica suelen realizarse paneles anuales para observar más movilidad)
Comenzamos limpiando la memoria y creando los directorios
rm(list=ls())
dir <- paste0(dirname(rstudioapi::getActiveDocumentContext()$path),"/")
bases.dir <- paste0(dirname(dir),"/Fuentes/")
resultados.dir <- paste0(dirname(dir),"/Resultados/")
Cargamos la librería tidyverse con la cual trabajaremos para procesar la información
library(tidyverse, warn = FALSE)
Levantamos las Bases Individuales de 4 trimestres publicados.
individual.216 <- read.table(paste0(bases.dir, "usu_individual_t216.txt"), sep=";", dec=",", header = TRUE, fill = TRUE)
individual.316 <- read.table(paste0(bases.dir, "usu_individual_t316.txt"), sep=";", dec=",", header = TRUE, fill = TRUE)
individual.416 <- read.table(paste0(bases.dir, "usu_individual_t416.txt"), sep=";", dec=",", header = TRUE, fill = TRUE)
individual.117 <- read.table(paste0(bases.dir, "usu_individual_t117.txt"), sep=";", dec=",", header = TRUE, fill = TRUE)
#Paso 1
var.ind <- c('CODUSU','NRO_HOGAR','COMPONENTE', 'ANO4','TRIMESTRE','ESTADO','CAT_OCUP','PONDERA', 'CH04', 'CH06','P21','PP3E_TOT')
#Paso 2
Bases_Continua <- bind_rows(
individual.216 %>% select(var.ind),
individual.316 %>% select(var.ind),
individual.416 %>% select(var.ind),
individual.117 %>% select(var.ind))
#Pasos 3 y 4
Bases_Continua <- Bases_Continua %>%
filter(CH06 %in% c(18:65),ESTADO !=0) %>%
mutate(Categoria = case_when(ESTADO %in% c(3,4)~"Inactivos",
ESTADO == 2 ~"Desocupados",
ESTADO == 1 & CAT_OCUP == 1 ~"Patrones",
ESTADO == 1 & CAT_OCUP == 2 ~"Cuenta Propistas",
ESTADO == 1 & CAT_OCUP == 3 ~"Asalariados",
ESTADO == 1 & CAT_OCUP == 4 ~"Trabajador familiar s/r",
TRUE ~ "Otros"))
#Paso 5
Bases_Continua <- Bases_Continua %>%
mutate(Trimestre = paste(ANO4, TRIMESTRE, sep="_")) %>%
arrange(Trimestre) %>%
mutate(Id_Trimestre = match(Trimestre,unique(Trimestre)))
#Paso 6
Bases_Continua_Replica <- Bases_Continua
names(Bases_Continua_Replica)
[1] "CODUSU" "NRO_HOGAR" "COMPONENTE" "ANO4" "TRIMESTRE"
[6] "ESTADO" "CAT_OCUP" "PONDERA" "CH04" "CH06"
[11] "P21" "PP3E_TOT" "Categoria" "Trimestre" "Id_Trimestre"
names(Bases_Continua_Replica)[4:(length(Bases_Continua_Replica)-1)] <-
paste0(names(Bases_Continua_Replica)[4:(length(Bases_Continua_Replica)-1)],"_t1")
names(Bases_Continua_Replica)
[1] "CODUSU" "NRO_HOGAR" "COMPONENTE" "ANO4_t1" "TRIMESTRE_t1"
[6] "ESTADO_t1" "CAT_OCUP_t1" "PONDERA_t1" "CH04_t1" "CH06_t1"
[11] "P21_t1" "PP3E_TOT_t1" "Categoria_t1" "Trimestre_t1" "Id_Trimestre"
#Paso 7
Bases_Continua_Replica$Id_Trimestre <- Bases_Continua_Replica$Id_Trimestre - 1
#Pasos 8 y 9
Panel_Continua <- inner_join(Bases_Continua,Bases_Continua_Replica)
Joining, by = c("CODUSU", "NRO_HOGAR", "COMPONENTE", "Id_Trimestre")
Panel_Continua <- Panel_Continua %>%
mutate(Consistencia = case_when(abs(CH06_t1-CH06) > 2 |
CH04 != CH04_t1 ~ "inconsistente",
TRUE ~ "consistente")) %>%
filter(Consistencia == "consistente")
Realizaremos un breve ejercicio para identificar la magnitud relativa de las transiciones entre las distintas categorías ocupacionales. Para ello calculamos la suma ponderada de la cantidad de casos observados para cada posible combinación de Cateogria y Categoria_t1. Luego calcularemos la probabilidad de encontrarse en categoría en t1, condicional a haber pertenecido a las distintas categorías en t0.
Categorias_transiciones <- Panel_Continua %>%
#filter(Categoria != Categoria_t1) %>%
group_by(Categoria,Categoria_t1) %>%
summarise(frec_muestral = n(),
frecuencia = sum((PONDERA+PONDERA_t1/2))) %>%
ungroup() %>%
group_by(Categoria) %>%
mutate(Prob_salida = frecuencia/sum(frecuencia))
Notese que la linea comentada en el medio de la cadena de pipes, nos permitiría iterar rapidamente sobre el procedimiento anterior agregando un filtro. En este ejemplo, podríamos recalcular las proporciones únicamente para aquellas personas que presentan un movimiento de categoría
library(ggthemes)
ggplot(Categorias_transiciones, aes(x = Categoria_t1,
y = Categoria, fill = Prob_salida,
label =round(Prob_salida*100,2))) +
labs(title = "Probabilidades de Transicion de hacia las distintas Categorías")+
geom_tile()+
geom_text()+
scale_fill_gradient(low = "grey100", high = "grey30")+
theme_tufte()
A continuación veremos una breve introducción a los comandos básicos que se utilizan para realizar econometría en R. En primera instancia observaremos la correlación entre dos variables, y luego haremos un test de correlación. Elegimos un caso simple, como observar la relación entre la cantidad de horas de horas trabajadas en la ocupación principal ( PP3E_TOT ) y el ingreso por la ocupación principal ( P21). Retomamos el trabajo con la información completa de las bases, dejando a un lado el panel construido.
Grafiquemos rápidamente para tener una intuición:
plot(Bases_Continua$PP3E_TOT,Bases_Continua$P21)
Como vemos aquí la función plot nos ayuda para mirar un poco la información antes de realizar un test o un modelo econométrico. En este caso, nos permite observar que en PP3E_TOT tenemos codificados con 999 a aquellos que no respondieron la pregunta por la cantidad de horas.
Bases_Continua_graf <- Bases_Continua %>% filter(PP3E_TOT != 999)
plot(Bases_Continua_graf$PP3E_TOT,Bases_Continua_graf$P21)
En una segunda mirada, podemos ver que tenemos algunos individuos que declarar trabajar las 168 horas de la semana, varios que declaran más de 100 horas, y otros tantos con ingreso 0, o -9 (código para los que no responden la pregunta de ingresos).
Aplicaremos un filtro más para restringir las horas trabajadas por semana a 84 (12*7) y quedarnos con ingresos positivos.
Bases_Continua_listo <- Bases_Continua %>% filter(P21>0,PP3E_TOT %in% c(1:84))
plot(Bases_Continua_listo$PP3E_TOT,Bases_Continua_listo$P21)
Luego del pantallazo a través de los gráficos, pasemos a realizar el calculo de la correlación entre las variables a partir de la función cor. Los función puede tomar como argumento dos vectores por separado y calculará el coeficiente de correlación entre ambas variables, o bien puede tomar como argumento un dataframe (O algunas variables del mismo) y arrojará como resultado una matriz cuadrada con los coeficiente de correlación entre cada una de ellas.
cor(Bases_Continua_listo$P21,Bases_Continua_listo$PP3E_TOT)
[1] 0.27738
cor(Bases_Continua_listo$P21,Bases_Continua_listo$CH06)
[1] 0.1679269
cor(Bases_Continua_listo[,c("P21","PP3E_TOT","CH06")])
P21 PP3E_TOT CH06
P21 1.0000000 0.27738000 0.16792691
PP3E_TOT 0.2773800 1.00000000 0.01281683
CH06 0.1679269 0.01281683 1.00000000
La función cor.test nos ejecutará el test de correlación sobre dos variables. Necesariamente requiere como argumentos dos vectores por separado.
En la salida podremos observar: el valor del estimador t, el p-valor, la hipotesis alternativa del test y el intervalo de confianza de la estimación.
cor.test(Bases_Continua_listo$P21, Bases_Continua_listo$PP3E_TOT)
Pearson's product-moment correlation
data: Bases_Continua_listo$P21 and Bases_Continua_listo$PP3E_TOT
t = 76.274, df = 69797, p-value < 2.2e-16
alternative hypothesis: true correlation is not equal to 0
95 percent confidence interval:
0.2705180 0.2842138
sample estimates:
cor
0.27738
A su vez, la función tiene otros parametros como por ejemplo conf_level que nos permite definir a gusto el nivel de confianza con el que queremos realizar el test. Por otro lado, la función tiene seteado por default el test de Pearson, pero el parámetro “method” nos permite elejir otros tests.
cor.test(Bases_Continua_listo$P21, Bases_Continua_listo$PP3E_TOT,conf.level = 0.90,
method = "spearman")
Cannot compute exact p-value with ties
Spearman's rank correlation rho
data: Bases_Continua_listo$P21 and Bases_Continua_listo$PP3E_TOT
S = 3.5649e+13, p-value < 2.2e-16
alternative hypothesis: true rho is not equal to 0
sample estimates:
rho
0.3710052
Para realizar una regresión simple usaremos la función lm. En este caso probaremos la siguiente regresión con las variables que estamos observando: Ingreso de la Ocupación principal como la variable dependiente, y las horas trabajadas en la ocupación principal como la independiente \[
E(P_{21}/horas)= \beta_0 + \beta_1 horas
\] La función lm tiene entre sus parametros principales:
formula: En el se especifican las variables que ingresan en el modelo de regresión. El signo de = del modelo se representa aquí mediante el signo ~.
data : Debe especificarse el dataframe que contiene la información de las variables a utilizar en el modelo.
Al ejectuar la función lm() con sus respectivos parametros, podremos visualizar los coeficientes estimados del modelo. Sin embargo, la función summary nos mostrará en más detalle los resultados.
lm(formula = P21 ~ PP3E_TOT, data = Bases_Continua_listo)
Call:
lm(formula = P21 ~ PP3E_TOT, data = Bases_Continua_listo)
Coefficients:
(Intercept) PP3E_TOT
4775.9 153.7
modelo.ajustado <-lm(formula = P21 ~ PP3E_TOT, data = Bases_Continua_listo)
summary(modelo.ajustado)
Call:
lm(formula = P21 ~ PP3E_TOT, data = Bases_Continua_listo)
Residuals:
Min 1Q Median 3Q Max
-17484 -4849 -1996 2848 287540
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 4775.924 81.752 58.42 <2e-16 ***
PP3E_TOT 153.672 2.015 76.27 <2e-16 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 8284 on 69797 degrees of freedom
Multiple R-squared: 0.07694, Adjusted R-squared: 0.07693
F-statistic: 5818 on 1 and 69797 DF, p-value: < 2.2e-16