Figura 1: antecedentes de la desocupación urbana

# ----------------------------------------------------------
#  ETAPA 1. GRÁFICAS DE ANTECEDENTES -->
#  IMPORTAR LOS DATOS DE 1973 A 2004 PARA LAS GRÁFICAS
# ----------------------------------------------------------
# Instalar los paquetes solamente la primera vez
paquetes <- c("readxl", "dplyr", "ggplot2")

# Revisamos cuáles paquetes todavía no están instalados
faltantes <- paquetes[!paquetes %in% installed.packages()[, "Package"]]

# Instalamos solamente los que hacen falta
if (length(faltantes) > 0) {
  install.packages(faltantes)
}

# Cargamos los paquetes
library(readxl)
## Warning: package 'readxl' was built under R version 4.5.3
library(dplyr)
## 
## Adjuntando el paquete: 'dplyr'
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(ggplot2)
## Warning: package 'ggplot2' was built under R version 4.5.3
# Escribimos el nombre del archivo
archivo <- "Datos_Antecedentes_Empleo_Desempleo_Mexico.xlsx"

desempleo_antiguo <- read_excel(
  archivo,
  sheet = "Desempleo_urbano_1973_2004"
)

# Dejamos solamente las columnas necesarias
desempleo_antiguo <- desempleo_antiguo %>%
  transmute(
    anio = Año,
    tasa = Tasa_desempleo_abierto_pct,
    segmento = "1973-2004: ECSO y ENEU"
  )

# ----------------------------------------------------------
# IMPORTAR LOS DATOS DE 2005 A 2020
# ----------------------------------------------------------

desempleo_reciente <- read_excel(
  archivo,
  sheet = "Tasas_ciudades_2005_2020"
)

# Calculamos un promedio anual de los datos trimestrales
# En 2020 el promedio solamente incluye los tres primeros trimestres
desempleo_reciente_anual <- desempleo_reciente %>%
  group_by(Año) %>%
  summarise(
    tasa = mean(Tasa_desocupacion_pct, na.rm = TRUE),
    trimestres_disponibles = n(),
    .groups = "drop"
  ) %>%
  transmute(
    anio = Año,
    tasa = tasa,
    segmento = "2005-2020: ENOE, ETOE y ENOEN"
  )

# Unimos ambos conjuntos, pero conservamos el segmento metodológico
desempleo_largo_plazo <- bind_rows(
  desempleo_antiguo,
  desempleo_reciente_anual
)

# Revisamos los datos antes de graficar
print(desempleo_largo_plazo)
## # A tibble: 48 × 3
##     anio  tasa segmento              
##    <dbl> <dbl> <chr>                 
##  1  1973   7.5 1973-2004: ECSO y ENEU
##  2  1974   7.2 1973-2004: ECSO y ENEU
##  3  1975   7.2 1973-2004: ECSO y ENEU
##  4  1976   6.7 1973-2004: ECSO y ENEU
##  5  1977   8.1 1973-2004: ECSO y ENEU
##  6  1978   6.8 1973-2004: ECSO y ENEU
##  7  1979   5.8 1973-2004: ECSO y ENEU
##  8  1980   4.5 1973-2004: ECSO y ENEU
##  9  1981   4.2 1973-2004: ECSO y ENEU
## 10  1982   4.2 1973-2004: ECSO y ENEU
## # ℹ 38 more rows
print(table(desempleo_largo_plazo$segmento))
## 
##        1973-2004: ECSO y ENEU 2005-2020: ENOE, ETOE y ENOEN 
##                            32                            16
# ----------------------------------------------------------
# CONSTRUIR LA GRÁFICA
# ----------------------------------------------------------

figura1 <- ggplot(
  desempleo_largo_plazo,
  aes(x = anio, y = tasa)
) +
  geom_line(linewidth = 0.7) +
  geom_point(size = 1.8) +
  facet_wrap(
    ~ segmento,
    ncol = 1,
    scales = "free_x"
  ) +
  labs(
    title = "Evolución de la desocupación urbana en México",
    subtitle = "Segmentos metodológicos presentados por separado",
    x = "Año",
    y = "Porcentaje"
  ) +
  theme_minimal(base_size = 11) +
  theme(
    plot.title = element_text(face = "bold"),
    panel.grid.minor = element_blank()
  )

# Mostrar la gráfica
print(figura1)

# Guardar la gráfica
ggsave(
  filename = "Figura_1_Desocupacion_urbana_1973_2020.png",
  plot = figura1,
  width = 9,
  height = 7,
  dpi = 300
)

Figura 2: antecedentes de la desocupación urbana

# IMPORTAR LOS PUNTOS HISTÓRICOS DE OCUPACIÓN

ocupacion_referencias <- read_excel(
  archivo,
  sheet = "Ocupacion_referencias"
)

ocupacion_referencias <- ocupacion_referencias %>%
  mutate(
    etiqueta = ifelse(
      Año %in% c(1980, 1990, 2000, 2008, 2020),
      paste0(
        Periodo,
        "\n",
        round(Poblacion_ocupada_millones, 1),
        " millones"
      ),
      NA
    )
  )

print(ocupacion_referencias)
## # A tibble: 16 × 7
##      Año Periodo Poblacion_ocupada_millones Instrumento     Poblacion_referencia
##    <dbl> <chr>                        <dbl> <chr>           <chr>               
##  1  1980 1980                          21.4 Censo de Pobla… Población de 12 año…
##  2  1990 1990                          23.4 Censo de Pobla… Población de 12 año…
##  3  1991 1991-T2                       30.5 ENE             Población de 12 año…
##  4  1997 1997-T2                       37.4 ENE             Población de 12 año…
##  5  1998 1998-T2                       38.7 ENE             Población de 12 año…
##  6  1999 1999-T2                       39.0 ENE             Población de 12 año…
##  7  2000 2000-T2                       39.5 ENE             Población de 12 año…
##  8  2001 2001-T2                       39.4 ENE             Población de 12 año…
##  9  2002 2002-T2                       40.3 ENE             Población de 12 año…
## 10  2003 2003-T2                       40.6 ENE             Población de 12 año…
## 11  2004 2004-T2                       42.3 ENE             Población de 12 año…
## 12  2005 2005-T2                       40.8 ENOE            Población de 14 año…
## 13  2006 2006-T2                       42.2 ENOE            Población de 14 año…
## 14  2007 2007-T2                       42.9 ENOE            Población de 14 año…
## 15  2008 2008-T2                       43.9 ENOE            Población de 14 año…
## 16  2020 2020-T3                       51.0 ENOEN           Población de 15 año…
## # ℹ 2 more variables: Nota_comparabilidad <chr>, etiqueta <chr>
#GRÁFICA
figura2 <- ggplot(
  ocupacion_referencias,
  aes(
    x = Año,
    y = Poblacion_ocupada_millones,
    shape = Instrumento
  )
) +
  geom_point(size = 3) +
  geom_text(
    aes(label = etiqueta),
    vjust = -0.8,
    size = 3.2,
    na.rm = TRUE,
    check_overlap = TRUE
  ) +
  labs(
    title = "Puntos de referencia de la población ocupada en México",
    subtitle = "Los puntos provienen de instrumentos estadísticos diferentes",
    x = "Año",
    y = "Millones de personas ocupadas",
    shape = "Fuente"
  ) +
  theme_minimal(base_size = 11) +
  theme(
    plot.title = element_text(face = "bold"),
    panel.grid.minor = element_blank(),
    legend.position = "bottom"
  ) +
  expand_limits(y = max(ocupacion_referencias$Poblacion_ocupada_millones) + 5)

# Mostrar la gráfica
print(figura2)

# Guardar la gráfica
ggsave(
  filename = "Figura_2_Poblacion_ocupada_referencias.png",
  plot = figura2,
  width = 9,
  height = 6,
  dpi = 300
)
# ----------------------------------------------------------
# ETAPA 2. REVISIÓN INICIAL DE LA BASE DE SERIE DE TIEMPO
# ----------------------------------------------------------
archivo <- "Base_Serie_Tiempo_Desempleo_Mexico.xlsx"
datos <- read_excel(
  path = archivo,
  sheet = "Datos",
  skip = 3
)
head(datos)
## # A tibble: 6 × 11
##     año desempleo crec_pib inflacion inversion exportaciones gasto_gob
##   <dbl>     <dbl>    <dbl>     <dbl>     <dbl>         <dbl>     <dbl>
## 1  1993      3.36     2.87      9.75      20.1          11.6      8.58
## 2  1994      4.44     4.39      6.97      21.7          12.8      8.98
## 3  1995      7.10    -5.91     35.0       16.2          22.9      8.04
## 4  1996      5.46     6.22     34.4       17.7          24.7      7.67
## 5  1997      4.24     7.20     20.6       19.4          23.3      7.85
## 6  1998      3.73     6.19     15.9       21.0          23.2      8.03
## # ℹ 4 more variables: crec_poblacion <dbl>, ied <dbl>, industria_pib <dbl>,
## #   tasa_interes_real <dbl>
# ----------------------------------------------------------
# 2. REVISAR LA ESTRUCTURA
# ----------------------------------------------------------

# Revisamos el tipo de cada columna
str(datos)
## tibble [32 × 11] (S3: tbl_df/tbl/data.frame)
##  $ año              : num [1:32] 1993 1994 1995 1996 1997 ...
##  $ desempleo        : num [1:32] 3.37 4.44 7.09 5.46 4.24 ...
##  $ crec_pib         : num [1:32] 2.87 4.39 -5.91 6.22 7.2 ...
##  $ inflacion        : num [1:32] 9.75 6.97 35 34.38 20.63 ...
##  $ inversion        : num [1:32] 20.1 21.7 16.2 17.7 19.4 ...
##  $ exportaciones    : num [1:32] 11.6 12.8 22.9 24.7 23.3 ...
##  $ gasto_gob        : num [1:32] 8.58 8.98 8.04 7.67 7.85 ...
##  $ crec_poblacion   : num [1:32] 1.85 1.81 1.78 1.74 1.68 ...
##  $ ied              : num [1:32] 0.828 1.982 2.506 2.126 2.451 ...
##  $ industria_pib    : num [1:32] 33 32.6 33.3 34.3 34.8 ...
##  $ tasa_interes_real: num [1:32] -17.25 10.1 14.86 7.65 3.74 ...
# Mostramos los nombres de las variables
names(datos)
##  [1] "año"               "desempleo"         "crec_pib"         
##  [4] "inflacion"         "inversion"         "exportaciones"    
##  [7] "gasto_gob"         "crec_poblacion"    "ied"              
## [10] "industria_pib"     "tasa_interes_real"
# Revisamos el número de filas y columnas
dim(datos)
## [1] 32 11
# Mostramos el número exacto de observaciones
nrow(datos)
## [1] 32
# ----------------------------------------------------------
# 3. ORDENAR Y COMPROBAR LOS AÑOS
# ----------------------------------------------------------

# Convertimos el año a número entero
datos$año <- as.integer(datos$año)

# Ordenamos la base desde el año más antiguo
datos <- datos %>%
  arrange(año)

# Revisamos el primer y el último año
min(datos$año)
## [1] 1993
max(datos$año)
## [1] 2024
# Revisamos si existen años duplicados
sum(duplicated(datos$año))
## [1] 0
# ----------------------------------------------------------
# 4. REVISAR VALORES FALTANTES
# ----------------------------------------------------------

# Contamos cuántos valores faltantes tiene cada variable
colSums(is.na(datos))
##               año         desempleo          crec_pib         inflacion 
##                 0                 0                 0                 0 
##         inversion     exportaciones         gasto_gob    crec_poblacion 
##                 0                 0                 0                 0 
##               ied     industria_pib tasa_interes_real 
##                 0                 0                 0
# Revisamos si existe alguna fila con datos faltantes
datos[!complete.cases(datos), ]
## # A tibble: 0 × 11
## # ℹ 11 variables: año <int>, desempleo <dbl>, crec_pib <dbl>, inflacion <dbl>,
## #   inversion <dbl>, exportaciones <dbl>, gasto_gob <dbl>,
## #   crec_poblacion <dbl>, ied <dbl>, industria_pib <dbl>,
## #   tasa_interes_real <dbl>
# ----------------------------------------------------------
# 5. ESTADÍSTICAS DESCRIPTIVAS
# ----------------------------------------------------------

# Obtenemos mínimo, máximo, promedio y otras medidas
summary(datos)
##       año         desempleo        crec_pib        inflacion     
##  Min.   :1993   Min.   :2.598   Min.   :-8.354   Min.   : 2.721  
##  1st Qu.:2001   1st Qu.:3.342   1st Qu.: 1.125   1st Qu.: 3.983  
##  Median :2008   Median :3.793   Median : 2.603   Median : 4.965  
##  Mean   :2008   Mean   :3.974   Mean   : 2.059   Mean   : 8.069  
##  3rd Qu.:2016   3rd Qu.:4.535   3rd Qu.: 3.881   3rd Qu.: 7.198  
##  Max.   :2024   Max.   :7.095   Max.   : 7.199   Max.   :34.999  
##    inversion     exportaciones     gasto_gob      crec_poblacion  
##  Min.   :16.21   Min.   :11.60   Min.   : 7.665   Min.   :0.6674  
##  1st Qu.:20.56   1st Qu.:23.60   1st Qu.: 9.276   1st Qu.:0.9644  
##  Median :21.67   Median :26.90   Median :10.803   Median :1.3818  
##  Mean   :21.54   Mean   :28.92   Mean   :10.306   Mean   :1.3102  
##  3rd Qu.:23.08   3rd Qu.:36.23   3rd Qu.:11.342   3rd Qu.:1.4980  
##  Max.   :24.12   Max.   :42.93   Max.   :12.197   Max.   :1.8527  
##       ied         industria_pib   tasa_interes_real 
##  Min.   :0.8279   Min.   :30.62   Min.   :-17.2486  
##  1st Qu.:2.1581   1st Qu.:31.97   1st Qu.:  0.6349  
##  Median :2.4820   Median :32.93   Median :  2.3886  
##  Mean   :2.4984   Mean   :32.88   Mean   :  2.7008  
##  3rd Qu.:2.7908   3rd Qu.:34.04   3rd Qu.:  5.7056  
##  Max.   :3.8367   Max.   :34.85   Max.   : 14.8567
# Promedio de cada variable
sapply(datos, mean, na.rm = TRUE)
##               año         desempleo          crec_pib         inflacion 
##       2008.500000          3.974375          2.058773          8.069340 
##         inversion     exportaciones         gasto_gob    crec_poblacion 
##         21.538529         28.917736         10.305646          1.310211 
##               ied     industria_pib tasa_interes_real 
##          2.498364         32.878355          2.700844
# Desviación estándar de cada variable
sapply(datos, sd, na.rm = TRUE)
##               año         desempleo          crec_pib         inflacion 
##         9.3808315         1.0230945         3.5141740         8.1188111 
##         inversion     exportaciones         gasto_gob    crec_poblacion 
##         1.8451707         7.7006064         1.3428993         0.3323636 
##               ied     industria_pib tasa_interes_real 
##         0.6118893         1.1872613         5.1457786
# ----------------------------------------------------------
# 6. MATRIZ DE CORRELACIONES
# ----------------------------------------------------------

# Seleccionamos solamente las variables numéricas
datos_numericos <- datos %>%
  select(-año)

# Calculamos la matriz de correlaciones
matriz_correlaciones <- cor(
  datos_numericos,
  use = "complete.obs"
)

# Mostramos la matriz con tres decimales
round(matriz_correlaciones, 3)
##                   desempleo crec_pib inflacion inversion exportaciones
## desempleo             1.000   -0.252     0.411    -0.285        -0.081
## crec_pib             -0.252    1.000     0.057     0.167        -0.114
## inflacion             0.411    0.057     1.000    -0.725        -0.342
## inversion            -0.285    0.167    -0.725     1.000         0.508
## exportaciones        -0.081   -0.114    -0.342     0.508         1.000
## gasto_gob            -0.003   -0.285    -0.760     0.689         0.748
## crec_poblacion        0.298    0.127     0.524    -0.531        -0.934
## ied                  -0.066   -0.170    -0.178     0.018         0.324
## industria_pib        -0.017    0.415     0.443    -0.250        -0.470
## tasa_interes_real     0.147   -0.098     0.473    -0.277        -0.022
##                   gasto_gob crec_poblacion    ied industria_pib
## desempleo            -0.003          0.298 -0.066        -0.017
## crec_pib             -0.285          0.127 -0.170         0.415
## inflacion            -0.760          0.524 -0.178         0.443
## inversion             0.689         -0.531  0.018        -0.250
## exportaciones         0.748         -0.934  0.324        -0.470
## gasto_gob             1.000         -0.786  0.253        -0.679
## crec_poblacion       -0.786          1.000 -0.322         0.602
## ied                   0.253         -0.322  1.000        -0.302
## industria_pib        -0.679          0.602 -0.302         1.000
## tasa_interes_real    -0.324          0.125  0.234         0.199
##                   tasa_interes_real
## desempleo                     0.147
## crec_pib                     -0.098
## inflacion                     0.473
## inversion                    -0.277
## exportaciones                -0.022
## gasto_gob                    -0.324
## crec_poblacion                0.125
## ied                           0.234
## industria_pib                 0.199
## tasa_interes_real             1.000
# ----------------------------------------------------------
# 7. COMPROBACIÓN FINAL
# ----------------------------------------------------------

cat("Número de observaciones:", nrow(datos), "\n")
## Número de observaciones: 32
cat("Número de variables independientes:", ncol(datos) - 2, "\n")
## Número de variables independientes: 9
cat("Primer año:", min(datos$año), "\n")
## Primer año: 1993
cat("Último año:", max(datos$año), "\n")
## Último año: 2024
cat("Años duplicados:", sum(duplicated(datos$año)), "\n")
## Años duplicados: 0
cat("Total de valores faltantes:", sum(is.na(datos)), "\n")
## Total de valores faltantes: 0

INTERPRETACIÓN

Después de importar la base en RStudio, comprobamos que contiene 32 observaciones anuales entre 1993 y 2024, nueve variables independientes y una variable dependiente. Todas las variables se importaron como numéricas y no encontramos años duplicados ni valores faltantes.

Durante el periodo analizado, la tasa de desempleo tuvo un promedio de 3.97 %, con un mínimo de 2.60% y un máximo de 7.10%. El crecimiento del PIB y la inflación presentaron cambios amplios, lo cual refleja que la muestra incluye periodos de crecimiento, crisis y recuperación.

La matriz de correlaciones mostró que el desempleo mantiene su relación simple más alta con la inflación, con un valor de 0.411. También presentó una relación positiva con el crecimiento poblacional y relaciones negativas con la inversión y el crecimiento del PIB. Sin embargo, estas correlaciones no permiten establecer causalidad ni sustituyen los resultados de la regresión.

Además, encontramos correlaciones elevadas entre algunas variables independientes, especialmente entre las exportaciones y el crecimiento poblacional, así como entre el gasto gubernamental, la inflación y la inversión. Por ello, más adelante revisaremos formalmente la multicolinealidad mediante el Factor de Inflación de la Varianza.

# ----------------------------------------------------------
# ESTIMACIÓN DEL MODELO GENERAL
# ----------------------------------------------------------

# Paquete para presentar los resultados de manera ordenada
if (!"broom" %in% installed.packages()[, "Package"]) {
  install.packages("broom")
}

library(broom)

# ----------------------------------------------------------
# 1. CREAR LA TENDENCIA TEMPORAL
# ----------------------------------------------------------

# La tendencia toma los valores 1, 2, 3, ..., 32
datos$tendencia <- seq_len(nrow(datos))

# Revisamos los primeros valores
head(datos[, c("año", "tendencia")])
## # A tibble: 6 × 2
##     año tendencia
##   <int>     <int>
## 1  1993         1
## 2  1994         2
## 3  1995         3
## 4  1996         4
## 5  1997         5
## 6  1998         6
# ----------------------------------------------------------
# 2. ESTIMAR EL MODELO GENERAL
# ----------------------------------------------------------

modelo_general <- lm(
  desempleo ~ crec_pib +
    inflacion +
    inversion +
    exportaciones +
    gasto_gob +
    crec_poblacion +
    ied +
    industria_pib +
    tasa_interes_real +
    tendencia,
  data = datos
)

# ----------------------------------------------------------
# 3. RESULTADOS COMPLETOS
# ----------------------------------------------------------

# Salida principal del modelo
summary(modelo_general)
## 
## Call:
## lm(formula = desempleo ~ crec_pib + inflacion + inversion + exportaciones + 
##     gasto_gob + crec_poblacion + ied + industria_pib + tasa_interes_real + 
##     tendencia, data = datos)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1.30689 -0.26333 -0.02882  0.26063  0.84250 
## 
## Coefficients:
##                     Estimate Std. Error t value Pr(>|t|)   
## (Intercept)       -11.437189   6.743631  -1.696  0.10466   
## crec_pib            0.032619   0.040074   0.814  0.42480   
## inflacion           0.102871   0.047841   2.150  0.04333 * 
## inversion          -0.173897   0.140943  -1.234  0.23090   
## exportaciones       0.058346   0.081040   0.720  0.47948   
## gasto_gob           1.211386   0.390360   3.103  0.00538 **
## crec_poblacion      4.413225   2.260812   1.952  0.06439 . 
## ied                -0.045180   0.225216  -0.201  0.84293   
## industria_pib      -0.052699   0.181125  -0.291  0.77394   
## tasa_interes_real   0.011654   0.026378   0.442  0.66315   
## tendencia           0.007286   0.084421   0.086  0.93204   
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.5781 on 21 degrees of freedom
## Multiple R-squared:  0.7837, Adjusted R-squared:  0.6807 
## F-statistic: 7.609 on 10 and 21 DF,  p-value: 5.081e-05
# Intervalos de confianza al 95 %
confint(modelo_general, level = 0.95)
##                           2.5 %     97.5 %
## (Intercept)       -25.461336981 2.58695911
## crec_pib           -0.050718859 0.11595646
## inflacion           0.003381178 0.20236085
## inversion          -0.467003948 0.11920991
## exportaciones      -0.110186138 0.22687884
## gasto_gob           0.399587262 2.02318427
## crec_poblacion     -0.288390924 9.11484011
## ied                -0.513542260 0.42318162
## industria_pib      -0.429369395 0.32397231
## tasa_interes_real  -0.043202418 0.06651046
## tendencia          -0.168277254 0.18284978
# Número de observaciones utilizadas
nobs(modelo_general)
## [1] 32
# ----------------------------------------------------------
# 4. TABLA ORDENADA DE COEFICIENTES
# ----------------------------------------------------------

tabla_coeficientes <- tidy(
  modelo_general,
  conf.int = TRUE,
  conf.level = 0.95
)

tabla_coeficientes
## # A tibble: 11 × 7
##    term               estimate std.error statistic p.value  conf.low conf.high
##    <chr>                 <dbl>     <dbl>     <dbl>   <dbl>     <dbl>     <dbl>
##  1 (Intercept)       -11.4        6.74     -1.70   0.105   -25.5        2.59  
##  2 crec_pib            0.0326     0.0401    0.814  0.425    -0.0507     0.116 
##  3 inflacion           0.103      0.0478    2.15   0.0433    0.00338    0.202 
##  4 inversion          -0.174      0.141    -1.23   0.231    -0.467      0.119 
##  5 exportaciones       0.0583     0.0810    0.720  0.479    -0.110      0.227 
##  6 gasto_gob           1.21       0.390     3.10   0.00538   0.400      2.02  
##  7 crec_poblacion      4.41       2.26      1.95   0.0644   -0.288      9.11  
##  8 ied                -0.0452     0.225    -0.201  0.843    -0.514      0.423 
##  9 industria_pib      -0.0527     0.181    -0.291  0.774    -0.429      0.324 
## 10 tasa_interes_real   0.0117     0.0264    0.442  0.663    -0.0432     0.0665
## 11 tendencia           0.00729    0.0844    0.0863 0.932    -0.168      0.183
# ----------------------------------------------------------
# 5. INDICADORES GENERALES DEL MODELO
# ----------------------------------------------------------

indicadores_modelo <- glance(modelo_general)

indicadores_modelo
## # A tibble: 1 × 12
##   r.squared adj.r.squared sigma statistic   p.value    df logLik   AIC   BIC
##       <dbl>         <dbl> <dbl>     <dbl>     <dbl> <dbl>  <dbl> <dbl> <dbl>
## 1     0.784         0.681 0.578      7.61 0.0000508    10  -21.1  66.3  83.8
## # ℹ 3 more variables: deviance <dbl>, df.residual <int>, nobs <int>
# Mostramos algunos indicadores de manera individual
cat(
  "R cuadrada:",
  summary(modelo_general)$r.squared,
  "\n"
)
## R cuadrada: 0.7837123
cat(
  "R cuadrada ajustada:",
  summary(modelo_general)$adj.r.squared,
  "\n"
)
## R cuadrada ajustada: 0.6807181
cat(
  "AIC:",
  AIC(modelo_general),
  "\n"
)
## AIC: 66.26068
cat(
  "BIC:",
  BIC(modelo_general),
  "\n"
)
## BIC: 83.84951
cat(
  "Número de observaciones:",
  nobs(modelo_general),
  "\n"
)
## Número de observaciones: 32
# ----------------------------------------------------------
# 6. GUARDAR LOS RESIDUOS
# ----------------------------------------------------------

datos$residuos_general <- residuals(modelo_general)

# Revisamos los primeros residuos
head(datos[, c("año", "residuos_general")])
## # A tibble: 6 × 2
##     año residuos_general
##   <int>            <dbl>
## 1  1993          -0.0807
## 2  1994           0.829 
## 3  1995           0.685 
## 4  1996          -0.354 
## 5  1997           0.260 
## 6  1998           0.418
# ----------------------------------------------------------
# DIAGNÓSTICOS ESENCIALES DEL MODELO GENERAL
# ----------------------------------------------------------

# Paquetes necesarios
paquetes <- c("car", "lmtest")

# Revisamos cuáles paquetes todavía no están instalados
faltantes <- paquetes[
  !paquetes %in% installed.packages()[, "Package"]
]

# Instalamos solamente los que hacen falta
if (length(faltantes) > 0) {
  install.packages(faltantes)
}

# Cargamos los paquetes
library(car)
## Warning: package 'car' was built under R version 4.5.3
## Cargando paquete requerido: carData
## 
## Adjuntando el paquete: 'car'
## The following object is masked from 'package:dplyr':
## 
##     recode
library(lmtest)
## Warning: package 'lmtest' was built under R version 4.5.3
## Cargando paquete requerido: zoo
## 
## Adjuntando el paquete: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
# Calculamos el Factor de Inflación de la Varianza
vif_general <- vif(modelo_general)

# Creamos una tabla sencilla
tabla_vif <- data.frame(
  variable = names(vif_general),
  VIF = as.numeric(vif_general)
)

# Mostramos la tabla
tabla_vif
##             variable       VIF
## 1           crec_pib  1.839584
## 2          inflacion 13.993710
## 3          inversion  6.273585
## 4      exportaciones 36.124983
## 5          gasto_gob 25.490238
## 6     crec_poblacion 52.373522
## 7                ied  1.761568
## 8      industria_pib  4.289505
## 9  tasa_interes_real  1.709023
## 10         tendencia 58.175720
# Prueba Durbin-Watson
# Hipótesis nula: los residuos no presentan autocorrelación
dw_general <- dwtest(modelo_general)

# Mostramos el resultado
dw_general
## 
##  Durbin-Watson test
## 
## data:  modelo_general
## DW = 1.3725, p-value = 0.001668
## alternative hypothesis: true autocorrelation is greater than 0
# Gráfica de autocorrelación de los residuos
acf(
  residuals(modelo_general),
  lag.max = 10,
  main = "Autocorrelación de los residuos del modelo general"
)

# Prueba Breusch-Pagan
# Hipótesis nula: los errores tienen varianza constante
bp_general <- bptest(modelo_general)

# Mostramos el resultado
bp_general
## 
##  studentized Breusch-Pagan test
## 
## data:  modelo_general
## BP = 14.302, df = 10, p-value = 0.1597
# Guardamos los residuos dentro de la base
datos$residuos_general <- residuals(modelo_general)

# Graficamos los errores de cada año
plot(
  datos$año,
  datos$residuos_general,
  type = "b",
  main = "Errores del modelo general, 1993-2024",
  xlab = "Año",
  ylab = "Residuo"
)

# Agregamos una línea horizontal en cero
abline(
  h = 0,
  lty = 2
)

# Esta gráfica permite observar si los errores forman algún patrón
plot(
  fitted(modelo_general),
  residuals(modelo_general),
  main = "Residuos contra valores ajustados",
  xlab = "Valores ajustados",
  ylab = "Residuos"
)

# Línea horizontal de referencia
abline(
  h = 0,
  lty = 2
)

# ----------------------------------------------------------
# MODELO ÓPTIMO DE SERIE DE TIEMPO
# ----------------------------------------------------------

# Paquetes necesarios
paquetes <- c("car", "lmtest", "prais")

# Instalamos solamente los paquetes que hagan falta
faltantes <- paquetes[
  !paquetes %in% installed.packages()[, "Package"]
]

if (length(faltantes) > 0) {
  install.packages(faltantes)
}

# Cargamos los paquetes
library(car)
library(lmtest)
library(prais)
## Warning: package 'prais' was built under R version 4.5.3
## Cargando paquete requerido: sandwich
## Warning: package 'sandwich' was built under R version 4.5.3
## Cargando paquete requerido: pcse
## 
## Adjuntando el paquete: 'pcse'
## The following object is masked from 'package:sandwich':
## 
##     vcovPC
# Nos aseguramos de que los datos estén ordenados por año
datos <- datos[order(datos$año), ]

# ----------------------------------------------------------
# 1. MODELO ÓPTIMO ESTIMADO POR MCO
# ----------------------------------------------------------

modelo_optimo_mco <- lm(
  desempleo ~ inflacion +
    inversion +
    gasto_gob +
    crec_poblacion,
  data = datos
)

# Resultados del modelo antes de corregir la autocorrelación
summary(modelo_optimo_mco)
## 
## Call:
## lm(formula = desempleo ~ inflacion + inversion + gasto_gob + 
##     crec_poblacion, data = datos)
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1.37297 -0.29600  0.02104  0.37534  0.87820 
## 
## Coefficients:
##                 Estimate Std. Error t value Pr(>|t|)    
## (Intercept)    -12.44554    2.60838  -4.771 5.63e-05 ***
## inflacion        0.13398    0.02022   6.625 4.14e-07 ***
## inversion       -0.08460    0.07860  -1.076    0.291    
## gasto_gob        1.28109    0.15493   8.269 7.08e-09 ***
## crec_poblacion   3.02123    0.47038   6.423 7.00e-07 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.5281 on 27 degrees of freedom
## Multiple R-squared:  0.768,  Adjusted R-squared:  0.7336 
## F-statistic: 22.34 on 4 and 27 DF,  p-value: 3.096e-08
# ----------------------------------------------------------
# 2. MULTICOLINEALIDAD
# ----------------------------------------------------------

vif_optimo <- vif(modelo_optimo_mco)

tabla_vif_optimo <- data.frame(
  variable = names(vif_optimo),
  VIF = as.numeric(vif_optimo)
)

tabla_vif_optimo
##         variable      VIF
## 1      inflacion 2.996587
## 2      inversion 2.338184
## 3      gasto_gob 4.812092
## 4 crec_poblacion 2.717066
# ----------------------------------------------------------
# 3. AUTOCORRELACIÓN ANTES DE LA CORRECCIÓN
# ----------------------------------------------------------

dw_optimo_mco <- dwtest(modelo_optimo_mco)

dw_optimo_mco
## 
##  Durbin-Watson test
## 
## data:  modelo_optimo_mco
## DW = 1.496, p-value = 0.0188
## alternative hypothesis: true autocorrelation is greater than 0
# ----------------------------------------------------------
# 4. HETEROCEDASTICIDAD
# ----------------------------------------------------------

bp_optimo_mco <- bptest(modelo_optimo_mco)

bp_optimo_mco
## 
##  studentized Breusch-Pagan test
## 
## data:  modelo_optimo_mco
## BP = 5.6898, df = 4, p-value = 0.2235
# ----------------------------------------------------------
# 5. CORRECCIÓN MEDIANTE PRAIS-WINSTEN
# ----------------------------------------------------------

modelo_optimo_final <- prais_winsten(
  desempleo ~ inflacion +
    inversion +
    gasto_gob +
    crec_poblacion,
  data = datos,
  index = "año"
)
## Iteration 0: rho = 0
## Iteration 1: rho = 0.2356
## Iteration 2: rho = 0.3156
## Iteration 3: rho = 0.3534
## Iteration 4: rho = 0.3734
## Iteration 5: rho = 0.3846
## Iteration 6: rho = 0.391
## Iteration 7: rho = 0.3948
## Iteration 8: rho = 0.397
## Iteration 9: rho = 0.3983
## Iteration 10: rho = 0.3991
## Iteration 11: rho = 0.3996
## Iteration 12: rho = 0.3999
## Iteration 13: rho = 0.4
## Iteration 14: rho = 0.4001
## Iteration 15: rho = 0.4002
## Iteration 16: rho = 0.4002
## Iteration 17: rho = 0.4003
## Iteration 18: rho = 0.4003
## Iteration 19: rho = 0.4003
## Iteration 20: rho = 0.4003
## Iteration 21: rho = 0.4003
## Iteration 22: rho = 0.4003
## Iteration 23: rho = 0.4003
# Resultados finales corregidos
resumen_modelo_final <- summary(modelo_optimo_final)

resumen_modelo_final
## 
## Call:
## prais_winsten(formula = desempleo ~ inflacion + inversion + gasto_gob + 
##     crec_poblacion, data = datos, index = "año")
## 
## Residuals:
##      Min       1Q   Median       3Q      Max 
## -1.36060 -0.32208  0.08368  0.39244  0.89804 
## 
## AR(1) coefficient rho after 23 iterations: 0.4003
## 
## Coefficients:
##                Estimate Std. Error t value Pr(>|t|)    
## (Intercept)    -9.26392    3.49704  -2.649 0.013322 *  
## inflacion       0.11025    0.02411   4.573 9.60e-05 ***
## inversion      -0.09407    0.09079  -1.036 0.309370    
## gasto_gob       1.06978    0.18921   5.654 5.29e-06 ***
## crec_poblacion  2.54186    0.65152   3.901 0.000574 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.5044 on 27 degrees of freedom
## Multiple R-squared:  0.6598, Adjusted R-squared:  0.6094 
## F-statistic: 13.09 on 4 and 27 DF,  p-value: 4.717e-06
## 
## Durbin-Watson statistic (original): 1.496 
## Durbin-Watson statistic (transformed): 1.937
# ----------------------------------------------------------
# 6. TABLA FINAL DE COEFICIENTES
# ----------------------------------------------------------

tabla_coeficientes_final <- cbind(
  variable = rownames(resumen_modelo_final$coefficients),
  as.data.frame(resumen_modelo_final$coefficients)
)

rownames(tabla_coeficientes_final) <- NULL

tabla_coeficientes_final
##         variable    Estimate Std. Error   t value     Pr(>|t|)
## 1    (Intercept) -9.26391775 3.49703743 -2.649076 1.332152e-02
## 2      inflacion  0.11025471 0.02411028  4.572934 9.595272e-05
## 3      inversion -0.09406578 0.09079280 -1.036049 3.093699e-01
## 4      gasto_gob  1.06977904 0.18921169  5.653874 5.291306e-06
## 5 crec_poblacion  2.54185850 0.65152009  3.901428 5.740992e-04
# ----------------------------------------------------------
# 7. INDICADORES FINALES
# ----------------------------------------------------------

cat(
  "R cuadrada:",
  resumen_modelo_final$r.squared,
  "\n"
)
## R cuadrada: 0.6598435
cat(
  "R cuadrada ajustada:",
  resumen_modelo_final$adj.r.squared,
  "\n"
)
## R cuadrada ajustada: 0.6094499
cat(
  "Prueba F:",
  resumen_modelo_final$fstatistic[1],
  "\n"
)
## Prueba F: 13.09381
cat(
  "Coeficiente de autocorrelación rho:",
  tail(modelo_optimo_final$rho, 1),
  "\n"
)
## Coeficiente de autocorrelación rho: 0.4002943
# El resumen muestra el Durbin-Watson
# antes y después de aplicar Prais-Winsten
resumen_modelo_final$dw
##    original transformed 
##    1.496002    1.937483
# ----------------------------------------------------------
# 8. GRÁFICA FINAL DE LOS ERRORES
# ----------------------------------------------------------

plot(
  datos$año,
  modelo_optimo_final$residuals,
  type = "b",
  main = "Errores del modelo óptimo corregido, 1993-2024",
  xlab = "Año",
  ylab = "Residuo"
)

abline(
  h = 0,
  lty = 2
)