Mostrando entradas con la etiqueta Análisis de datos. Mostrar todas las entradas
Mostrando entradas con la etiqueta Análisis de datos. Mostrar todas las entradas

3 may 2025

Recodificación de Variables en R

 La recodificación de variables es una tarea esencial en el análisis de datos que nos permite transformar datos continuos en categorías más interpretables, facilitando tanto el análisis como la visualización. En este artículo, exploraremos diferentes técnicas para recodificar variables utilizando el poderoso ecosistema tidyverse en R.

 1.     Preparación del entorno

 Primero, cargamos las librerías necesarias y el conjunto de datos con el que trabajaremos:

 # Cargamos las librerías necesarias para manipulación de datos
library(tidyselect)  # Para selección avanzada de variables
library(wooldridge)  # Paquete con datos de ejemplos econométricos
 
# Cargamos el dataset wage1 (datos sobre salarios)
data("wage1")
 
# Visualizamos los datos
wage1 |> View()

El conjunto de datos wage1 contiene información sobre salarios, educación, experiencia laboral y otras variables socioeconómicas. Antes de cualquier recodificación, resulta útil explorar la relación entre las variables existentes.

2.     Exploración visual previa

Primero, examinemos la relación entre los años de educación (educ), el logaritmo del salario (lwage) y el género (female) (es siempre muy importante estudiar las relaciones y las características de las variables):

 # Visualizamos la relación entre educación y salario por género
wage1 |>
  # dplyr::filter(educ<=5) |> 
  ggplot(aes(x=educ, y=lwage, color=factor(female))) +
  geom_point() +
  geom_jitter(width = 0.4, height = 0, alpha = 0.6) + 
  geom_smooth(method = "lm") 

Este gráfico nos muestra cómo el logaritmo del salario tiende a aumentar con los años de educación, y cómo esta relación varía según el género. La función geom_jitter() añade una pequeña dispersión horizontal para evitar la superposición de puntos, mejorando la visualización.

3.     Recodificación Categórica con case_when()

La primera estrategia que exploraremos utiliza la función case_when() para crear categorías educativas basadas en rangos de años de estudio:

# Opción 1: Recodificación arbitraria basada en niveles educativos estándar
wage1 <- wage1 |>
  mutate(rango_Educ = case_when(
    educ == 0 ~ "0 esco",                # Sin escolaridad
    educ >= 1 & educ <= 6 ~ "Primaria",  # Educación primaria (1-6 años)
    educ >= 7 & educ <= 12 ~ "aSecundaria", # Educación secundaria (7-12 a)
    educ >= 13 ~ "Terciaria"             # Educación superior (13+ años)
  ),
  # Convertimos a factor con orden específico
  rango_Educ = factor(rango_Educ, levels = c("0 esco", "Primaria", "aSecundaria", "Terciaria"))
  )

Esta recodificación utiliza case_when() para crear categorías educativas significativas. La función evalúa cada condición secuencialmente y asigna la categoría correspondiente. Luego, convertimos la nueva variable en un factor ordenado para mantener la jerarquía natural de los niveles educativos.

Visualicemos cómo se relacionan estos rangos educativos con el salario:

# Visualizamos la mediante boxplots
wage1 |>
  ggplot(aes(x=rango_Educ, y=wage)) +
  geom_boxplot()

Los diagramas de caja nos permiten comparar la distribución salarial entre los diferentes niveles educativos, mostrando la mediana, los cuartiles y los valores atípicos para cada grupo.

 4.     Recodificación por Cuantiles con ntile()

Una alternativa a la categorización arbitraria es dividir los datos en cuantiles utilizando la función ntile(): 

# Opción 2: Recodificación basada en quintiles (divide los datos en 5 grupos de igual tamaño)
wage1 <- wage1 |>
  mutate(rango_Educ2 = ntile(educ, 5)) 

Esta técnica divide la variable educ en cinco grupos con aproximadamente el mismo número de observaciones en cada uno. Es especialmente útil cuando buscamos crear grupos balanceados sin imponer puntos de corte arbitrarios.

Visualicemos esta nueva categorización:

# Visualizamos la relación entre quintiles educativos y salario
wage1 |>
  ggplot(aes(x=factor(rango_Educ2), y=wage)) +
  geom_boxplot()

Finalmente, calculemos algunas estadísticas por grupo para evaluar las diferencias entre los quintiles educativos:

# Calculamos estadísticas descriptivas por quintil educativo
wage1 |>
  group_by(rango_Educ2) |>
  summarise(obs = n(),                           # Número de observaciones
            meand_educ = mean(wage, na.rm=T),    # Salario medio
            vol_educ = meand_educ/sd(wage, na.rm=T))   

Este análisis nos proporciona el número de observaciones, el salario medio y una medida de volatilidad relativa para cada quintil educativo.

5.     Recodificación con intervalos específicos usando cut()

La función cut() nos permite dividir una variable numérica en intervalos específicos, ofreciendo mayor control sobre los puntos de corte:

# Opción 3: Recodificación con intervalos específicos usando cut()
wage1 <- wage1 |>
  mutate(rango_Educ3 = cut(educ,
               breaks = c(0, 6, 12, 16, Inf),  # Puntos de corte específicos
               labels = c("Básica", "Media", "Universitaria", "Posgrado"),
       include.lowest = TRUE,  # Incluye el valor mínimo
                right = FALSE))  # Intervalos cerrados a la izquierda
 
# Visualizamos la nueva categorización
wage1 |>
  ggplot(aes(x=rango_Educ3, y=wage)) +
  geom_boxplot() +
  labs(title = "Distribución de salarios por nivel educativo",
       x = "Nivel educativo",
       y = "Salario por hora ($)")

Esta técnica nos permite definir manualmente los límites de cada categoría, lo que es ideal cuando tenemos umbrales específicos basados en conocimiento del dominio (como los niveles educativos estándar). El parámetro include.lowest = TRUE asegura que el valor mínimo (0 en este caso) se incluya en el primer intervalo, mientras que right = FALSE define intervalos cerrados a la izquierda.

 6.     Creación de variables dummy con if_else()

Para análisis estadísticos como regresiones, a menudo necesitamos variables binarias (0/1):

# Opción 4: Creación de variables dummy utilizando if_else()
wage1 <- wage1 |>
  mutate(
    # Educación superior (binaria)
    educ_superior = if_else(educ >= 13, 1, 0),
   
    # Alta experiencia (binaria)
    exper_alta = if_else(exper > median(exper), 1, 0),
   
    # Interacción entre educación superior y género
    educ_sup_mujer = educ_superior * female
  )
 
# Visualizamos el efecto de la educación superior en el salario por género
wage1 |>
  ggplot(aes(x = factor(educ_superior), y = wage, fill = factor(female))) +
  geom_boxplot() +
  labs(title = "Efecto de educación superior en salarios por género",
       x = "Educación superior",
       y = "Salario por hora ($)",
       fill = "Mujer")

La función if_else() es perfecta para crear variables binarias, ya que evalúa una condición y asigna un valor para los casos verdaderos y otro para los falsos. En este ejemplo, creamos indicadores para educación superior, alta experiencia, y una interacción entre educación superior y género.

 7.     Normalización para análisis de desviaciones estándar

 La normalización nos permite expresar los valores en términos de cuántas desviaciones estándar se alejan de la media:

 # Opción 5: Normalización de variables para análisis de desviaciones estándar
wage1 <- wage1 |>
  mutate(
    # Z-score de educación (normalización)
    educ_z = (educ - mean(educ)) / sd(educ),
   
    # Z-score de experiencia
    exper_z = (exper - mean(exper)) / sd(exper),
   
    # Z-score de salario
    wage_z = (wage - mean(wage)) / sd(wage)
  )
 
# Visualizamos distribución de valores normalizados
wage1 |>
  select(educ_z, exper_z, wage_z) |>
  pivot_longer(cols = everything(), names_to = "variable", values_to = "valor_z") |>
  ggplot(aes(x = valor_z, fill = variable)) +
  geom_density(alpha = 0.5) +
  geom_vline(xintercept = 0, linetype = "dashed") +
  labs(title = "Distribución de variables normalizadas",
       x = "Desviaciones estándar desde la media",
       y = "Densidad")

La normalización (cálculo de z-scores) convierte los valores a una escala común donde 0 representa la media y cada unidad representa una desviación estándar. Esto facilita la comparación de variables con diferentes unidades o escalas, y es especialmente útil para identificar valores atípicos y para ciertos modelos estadísticos.

12 mar 2025

Análisis del Impacto de un Choque Monetario sobre el Desempleo usando VAR en R

 En este post, exploraremos cómo estimar un modelo VAR en R utilizando la base de datos Canada del paquete vars. Se intenta mostrar cómo usar impulso respuesta de un VAR y como generar escenarios a partir de la introducción de choques. Nos enfocaremos en analizar la respuesta del desempleo ante un choque monetario, graficar la función de impulso-respuesta (IRF) y proyectar la tasa de desempleo con y sin la presencia del choque.

Antes de comenzar, asegurémonos de tener instalados y cargados los paquetes necesarios:
 
library(vars)
library(ggplot2)
library(forecast)

Utilizaremos la base Canada, que contiene datos macroeconómicos de Canadá. Seleccionaremos la tasa de desempleo (U) y la tasa de interés (R) para modelar su relación mediante un VAR con dos rezagos.
 
# Cargar la base de datos
data(Canada)
Canada_ts <- as.data.frame(Canada)
 
# Estimar un modelo VAR con 2 rezagos
desempleo_VAR <- VAR(Canada_ts, p = 2, type = "const")
 
Funciones de Impulso-Respuesta (IRF)

Ahora obtenemos la función de impulso-respuesta para analizar el efecto de un choque monetario (en la tasa de interés R) sobre el desempleo (U).
 
irf_result <- irf(desempleo_VAR, impulse = "rw", response = "U", n.ahead = 10, boot = TRUE)
 
irf_df <- data.frame(
  Horizon = 1:11,
  Response = irf_result$irf$rw |> as.vector(),
  Lower = irf_result$Lower$rw |> as.vector(),
  Upper = irf_result$Upper$rw |> as.vector()
)
 
ggplot(irf_df, aes(x = Horizon, y = Response)) +
  geom_line(color = "blue", size = 1) +
  geom_ribbon(aes(ymin = Lower, ymax = Upper), fill = "blue", alpha = 0.2) +
  labs(title = "Respuesta del Desempleo a un Choque Monetario",
       x = "Horizonte",
       y = "Impacto en el Desempleo") +
  theme_minimal()
 

Proyección del Desempleo sin Choque
 
Ahora realizamos una proyección de la tasa de desempleo para los próximos 10 períodos sin ningún choque:
 
forecasts <- predict(desempleo_VAR, n.ahead = 10)
U_forecast <- data.frame(
  Horizon = 1:10,
  Forecast = forecasts$fcst$U[, 1]
)

Proyección del Desempleo con un Choque Monetario

En un modelo VAR (Vector Autoregressive), un choque se refiere a una perturbación o innovación inesperada que afecta a una o más variables del sistema. Estos choques representan eventos imprevistos que alteran la trayectoria normal de las variables económicas o financieras modeladas.

Un choque en un modelo VAR tiene las siguientes características:
·        Es una perturbación exógena que entra al sistema a través de los términos de error en las ecuaciones del modelo
·        Puede afectar simultáneamente a múltiples variables debido a la estructura multivariante del VAR
·        Permite analizar la propagación de efectos a lo largo del tiempo (mediante funciones de impulso-respuesta)
·        Ayuda a entender cómo un cambio inesperado en una variable afecta a las demás variables del sistema
 
Introducimos un choque en la tasa de interés (+0.5 puntos porcentuales en el primer período) y ajustamos la predicción:
 
forecasts <- predict(desempleo_VAR, n.ahead = 10)
 
U_forecast <- data.frame(
  Horizon = 1:10,
  Forecast = forecasts$fcst$U[, 1]
)
 
  shock <- rep(0, 10)
shock[1] <- 0.5  # Simulamos un aumento de 0.5 pp en la tasa de interés
response_with_shock <- irf_result$irf$rw[-11] + shock  # Aplicamos el choque a la IRF
 
U_forecast_shock <- data.frame(
  Horizon = 1:10,
  Forecast = U_forecast$Forecast + response_with_shock
)
 
ggplot() +
  geom_line(data = U_forecast, aes(x = Horizon, y = Forecast, color = "Sin Choque"), size = 1) +
  geom_line(data = U_forecast_shock, aes(x = Horizon, y = Forecast, color = "Con Choque"), size = 1) +
  labs(title = "Proyección del Desempleo con y sin Choque Monetario",
       x = "Horizonte",
       y = "Tasa de Desempleo") +
  scale_color_manual(name = "Escenario", values = c("Sin Choque" = "black", "Con Choque" = "red")) +
  theme_minimal()



8 mar 2025

Curso completo de R: de 0 a avanzando

 El curso que he diseñado (claude.ia) para ti sigue una estructura progresiva que te permitirá dominar R desde los conceptos básicos hasta técnicas avanzadas. Lo he organizado en 7 módulos principales:

  1. Introducción a R: Cubre instalación, tipos de datos, estructuras fundamentales e importación/exportación.
    1. Clase 1.1. [video] Introducción a R. Tipo de datos, operadores, funciones, consola, editor, entorno, visualizador, entorno de trabajo, estructura de datos:  creación, indexación y operaciones. Importación de datos y funciones integradas.
  2. Análisis Estadístico: Incluye estadística descriptiva, manejo de datos atípicos, imputación de valores perdidos y pruebas de independencia, tal como solicitaste.
    1. Clase 2.1. [video] Análisis descriptivo en R
    2. Clase 2.2. [video] Análisis de independencia
    3. Clase 2.3. Valores atípicos
    4. Clase 2.4. Impuetación de datos en R
  3. Tidyverse: Abarca todo el ecosistema con especial énfasis en dplyr, ggplot2 y manipulación de datos relacionales (long, join, wide).
    1. Clase 3.1. Dplyr. Análisis de base de hogares
    2. Clase 3.2. Ggplot
    3. Clase 3.3. Dplur II. Bases relacionales (join, long data, nest...)
  4. Programación en R: Desarrolla bucles, funciones, estructuras y vectorización, con una clase completa dedicada al paquete purrr.
    1. Clase 4.1. Introducción a la programación
    2. Clase 4.2. Funciones propias
    3. Clase 4.3. Operaciones vectorizadas + purr
  5. Modelado Estadístico y Machine Learning: Módulo adicional que te permitirá aplicar R en contextos analíticos avanzados.
  6. Desarrollo Avanzado en R: Para convertirte en un profesional completo, incluyendo optimización, desarrollo de paquetes y aplicaciones.
  7. Macroeconometría aplicada en R: Para consolidar todos los conocimientos en casos prácticos.
    1. Clase 7.1. Introducción aplicada (R intermedio)
    2. Análisis univariado
    3. Modelos lineles
    4. Vectores Autorregresivos (VAR)
    5. Vector de corrección de errores (VEC)

13 nov 2024

Recodificación de variables usando dplyr en R

Una base de datos suele tener diversos tipos de variables del tipo cualitativo y cuantitativo. En función del tipo de variables aplicamos diversos tipos de herramientas estadísticas para el análisis de datos. Por ejemplo, el estudio de la independencia entre dos variables depende de la forma de la misma:

Dos variables cuantitativas: análisis de regresión o correlación

* Una variable cuantitativa y una cualitativa: test de media o comparación de media.

-          * Dos variables cualitativas: test chi-cuadrado.

Por tanto, pueden existir casos donde estemos interesados en recodificar una de estas variables para aplicar algún tipo de análisis, como convertir una variable cuantitativa en cualitativa o transformar una variable cualitativa para recalificar grupos. Por ejemplo agregar edades por rango: 0-10, 11-20, 21-30, …; o reagrupar grupos dentro de una variable cualitativa, ejemplo, agrupar los estudiantes de economía y contabilidad como miembros de la facultad de económicas.

Para ilustrar estos ejemplos, simulamos la siguiente base de datos:

set.seed(1)  # Para reproducibilidad
library(tidyverse)
 
# Simulación de datos
data_simulada <- tibble(
  edad = sample(0:90, 100, replace = TRUE),
  sexo = sample(c("Masculino", "Femenino"), 100, replace = TRUE),
  ingresos = round(rnorm(100, mean = 30000, sd = 10000), 2),
  zona_residencia = sample(c("a", "b", "c"), 100, replace = TRUE))
 
# A tibble: 100 × 4
    edad sexo      ingresos zona_residencia
   <int> <chr>        <dbl> <chr>         
 1     7 Femenino    13113. a             
 2    24 Masculino   14276. a              
 3    19 Femenino    25950. a             
 4    83 Masculino   33193. a             
 5     4 Masculino   30404. c             
 6    73 Femenino    26100. a             
 7    19 Masculino   11808. c             
 8    54 Masculino   36592. b             
 9    55 Femenino    34596. c             
10    78 Femenino    46166. C

 1.       Análisis de correlación para estudiar dependencia entre dos variables cuantitativas:

 ggplot(data_simulada, aes(x = edad, y = ingresos)) +
  geom_point(alpha = 0.6) +
  geom_smooth(method = "lm", color = "blue", se = FALSE) +
  labs(x = "Edad", y = "Ingresos", title = "Relación entre Edad e Ingresos") +
  theme_minimal()

 2.       Tabla de comparación de promedios, para estudiar independencia entre una variable cualitativa y otra cuantitativa:

 data_simulada |>
  group_by(sexo) |>
  summarize(ingreso_promedio = mean(ingresos, na.rm = TRUE))
 
# A tibble: 2 × 2
  sexo      ingreso_promedio
  <chr>                <dbl>
1 Femenino            29794.
2 Masculino           29546.

 3.       Recodification de variables.

 Ahora, queremos estudiar la relación entre edad e ingreso vista en el apartado 1, pero con el fin estudiar la independencia a partir del ejemplo visto en el apartado 2. Es decir, necesitamos convertir una variable cuantitativa en cualitativa para realizar algún tipo de análisis. Un primer ejemplo de este tipo de análisis es transformar una variable cuantitativa en grupos específicos, con el objetivo de resaltar clúster de observaciones con algún objetivo.

 3.1. Recodificar una variable cuantitativa, creando grupos arbitrarios.

 Según edad, por ejemplo, podemos crear grupos segmentarlo según edad del trabajador.

 data_simulada |>
  mutate(grupo_edad = case_when(
    edad >= 0 & edad <= 14 ~ "0-14",
    edad >= 15 & edad <= 64 ~ "15-64",
    edad > 65 ~ ">65",
    TRUE ~ NA_character_  # Manejo de posibles NA
  )) |>
  group_by(grupo_edad) |>
  summarise(media = mean(ingresos))
 
# A tibble: 3 × 2
  grupo_edad  media
  <chr>       <dbl>
1 0-14       29160.
2 15-64      28094.
3 >65        32791

Otro ejemplo de este tipo de recodificación es crear una variable con distintos niveles de ingresos: bajo, medio, alto. Podemos ahora obtener edad promedio según nivel de ingresos.

 data_simulada %>%
  mutate(
    nivel_ingreso = case_when(
      ingresos < 20000 ~ "Bajo",
      ingresos >= 20000 & ingresos < 40000 ~ "Medio",
      ingresos >= 40000 ~ "Alto"
    )
  ) |> 
  group_by(nivel_ingreso) |>
  summarize(edad_m_ing = mean(edad, na.rm = TRUE))
 
# A tibble: 3 × 2
  nivel_ingreso edad_m_ing
  <chr>              <dbl>
1 Alto                51.6
2 Bajo                44.7
3 Medio               42.1

 3.2. Recodificar una variable cuantitativa, creando grupos estadísticos: quintiles.

 Ahora, si quisiéramos agrupar los ingresos, no tenemos de antemano una segmentación por grupos que sea representativa como la edad[1]. En estos casos, donde no tenemos una segmentación orientada a caracterizar una población, podemos optar por grupos estadísticos, como los percentiles.

 Por ejemplo: podemos ver la edad promedio pro percentil de ingresos.

 data_simulada |>
  mutate(quintil_ingresos = ntile(ingresos, 5)) |>  # Dividir ingresos en 5 quintiles
  group_by(quintil_ingresos) |>
  summarize(edad_promedio = mean(edad, na.rm = TRUE))
 
# A tibble: 5 × 2
  quintil_ingresos edad_promedio
             <int>         <dbl>
1                1          44.1
2                2          43.8
3                3          41.8
4                4          44.4
5                5          59.2

 ·         mutate(quintil_ingresos = ntile(ingresos, 5)): Crea una nueva columna quintil_ingresos que divide ingresos en 5 grupos de igual tamaño.

·         group_by(quintil_ingresos): Agrupa los datos por cada quintil de ingresos.

·         summarize(edad_promedio = mean(edad, na.rm = TRUE)): Calcula la edad promedio dentro de cada quintil.

 3.3. Recodificar una variable cualitativa para crear una variable binaria.

Este ejemplo aplica para variables cuantitativas, al recodificar una variable para crear un grupo que sea igual a 1. Por ejemplo, podemos querer que menores de edad sean 1, o que mujeres sean menores a 1.

Recodificar Sexo a Valores Binarios. Convertimos sexo en variables binarias, codificando "Masculino" como 1 y "Femenino" como 0. Al grupo base se coloca el valor de 1.

 data_simulada %>%
  mutate(hombre_binario = if_else(sexo == "Masculino", 1, 0)) |> 
  group_by(hombre_binario) |>
  summarize(edad_sexo = mean(ingresos, na.rm = TRUE))
 
# A tibble: 2 × 2
  hombre_binario edad_sexo
           <dbl>     <dbl>
1              0    28807.
2              1    29658.

 3.4. Recodificar una variable cualitativa para recalificar grupos.

 Finalmente, recodificamos una variable cualitativa como zona, para verificar que la zona a y b sean consideradas como zona rural y c como urbana. Esto se hace para obtener un grupo cuya calificación sean mas familiar para el lector, o este mas acorde como los objetivos de la investigación. Primero creamos la variable en la base de datos, mediante una recodificación de la variable zona, usando case_when para crear la nueva columna zona en la que las categorías "a" y "b" se recodifican como "Rural" y "c" como "Urbana":

 data_simulada |>
  mutate(zona = case_when(
    zona_residencia %in% c("a", "b") ~ "Rural",
    zona_residencia == "c" ~ "Urbana"
  ))
 
# A tibble: 100 × 5
    edad sexo      ingresos zona_residencia zona 
   <int> <chr>        <dbl> <chr>           <chr>
 1     7 Femenino    13113. a               Rural
 2    24 Masculino   14276. a               Rural
 3    19 Femenino    25950. a               Rural
 4    83 Masculino   33193. a               Rural
 5     4 Masculino   30404. c               Urbana
 6    73 Femenino    26100. a               Rural
 7    19 Masculino   11808. c               Urbana
 8    54 Masculino   36592. b               Rural
 9    55 Femenino    34596. c               Urbana
10    78 Femenino    46166. c               Urbana
# 90 more rows
# Use `print(n = ...)` to see more rows

Ahora calculamos el ingreso promedio por la zona de residencia.

 data_simulada |>
  mutate(zona = case_when(
    zona_residencia %in% c("a", "b") ~ "Rural",
    zona_residencia == "c" ~ "Urbana"
  ))   |>
  group_by(zona) |>
  summarize(ingreso_promedio = mean(ingresos, na.rm = TRUE))
 
# A tibble: 2 × 2
  zona   ingreso_promedio
  <chr>             <dbl>
1 Rural            29684.
2 Urbana           28133.


[1] Salvo en el caso de la pobreza, que podemos agrupar según la línea de pobreza.

Recodificación de Variables en R

  La recodificación de variables es una tarea esencial en el análisis de datos que nos permite transformar datos continuos en categorías más...