1. Instalar y cargar paquetes (solo una vez)

library(readxl)
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
library(ggplot2)

1. Descargar / leer los datos

data <- read_excel("C:/Users/Michael Encalada/Downloads/estadistica_2/data.xlsx")
# Explorar la base
head(data)
## # A tibble: 6 × 7
##     age gender norm_educ norm_income party prefsep_welfare welfare_support   
##   <dbl> <chr>  <chr>     <chr>       <chr>           <dbl> <chr>             
## 1    66 Hombre 0.8       1.0         cons               -1 Mantener o Reducir
## 2    30 Hombre 0.6       0.0         cons                1 Aumentar          
## 3    67 Hombre 0.9       0.25        cons               -1 Mantener o Reducir
## 4    19 Mujer  0.7       NA          lib                -1 Mantener o Reducir
## 5    37 Hombre 0.6       0.5         other              -1 Mantener o Reducir
## 6    47 Hombre 1.0       0.5         ndp                 1 Aumentar
str(data)
## tibble [4,253 × 7] (S3: tbl_df/tbl/data.frame)
##  $ age            : num [1:4253] 66 30 67 19 37 47 49 22 37 38 ...
##  $ gender         : chr [1:4253] "Hombre" "Hombre" "Hombre" "Mujer" ...
##  $ norm_educ      : chr [1:4253] "0.8" "0.6" "0.9" "0.7" ...
##  $ norm_income    : chr [1:4253] "1.0" "0.0" "0.25" "NA" ...
##  $ party          : chr [1:4253] "cons" "cons" "cons" "lib" ...
##  $ prefsep_welfare: num [1:4253] -1 1 -1 -1 -1 1 0 1 -1 0 ...
##  $ welfare_support: chr [1:4253] "Mantener o Reducir" "Aumentar" "Mantener o Reducir" "Mantener o Reducir" ...
summary(data)
##       age           gender           norm_educ         norm_income       
##  Min.   :18.00   Length:4253        Length:4253        Length:4253       
##  1st Qu.:33.00   Class :character   Class :character   Class :character  
##  Median :48.00   Mode  :character   Mode  :character   Mode  :character  
##  Mean   :47.27                                                           
##  3rd Qu.:62.00                                                           
##  Max.   :90.00                                                           
##     party           prefsep_welfare    welfare_support   
##  Length:4253        Min.   :-1.00000   Length:4253       
##  Class :character   1st Qu.:-1.00000   Class :character  
##  Mode  :character   Median : 0.00000   Mode  :character  
##                     Mean   : 0.07124                     
##                     3rd Qu.: 1.00000                     
##                     Max.   : 1.00000

3. Limpieza o formateo

# Revisar estructura
str(data)
## tibble [4,253 × 7] (S3: tbl_df/tbl/data.frame)
##  $ age            : num [1:4253] 66 30 67 19 37 47 49 22 37 38 ...
##  $ gender         : chr [1:4253] "Hombre" "Hombre" "Hombre" "Mujer" ...
##  $ norm_educ      : chr [1:4253] "0.8" "0.6" "0.9" "0.7" ...
##  $ norm_income    : chr [1:4253] "1.0" "0.0" "0.25" "NA" ...
##  $ party          : chr [1:4253] "cons" "cons" "cons" "lib" ...
##  $ prefsep_welfare: num [1:4253] -1 1 -1 -1 -1 1 0 1 -1 0 ...
##  $ welfare_support: chr [1:4253] "Mantener o Reducir" "Aumentar" "Mantener o Reducir" "Mantener o Reducir" ...
# Convertir variables que deberían ser numéricas
data <- data %>%
  mutate(
    norm_educ = as.numeric(norm_educ),
    norm_income = as.numeric(norm_income),
    age = as.numeric(age)
  )
## Warning: There were 2 warnings in `mutate()`.
## The first warning was:
## ℹ In argument: `norm_educ = as.numeric(norm_educ)`.
## Caused by warning:
## ! NAs introducidos por coerción
## ℹ Run ]8;;ide:run:dplyr::last_dplyr_warnings()dplyr::last_dplyr_warnings()]8;; to see the 1 remaining warning.
# Convertir variables categóricas a factores
data <- data %>%
  mutate(
    gender = factor(gender,
                    levels = c("Mujer", "Hombre")),  # asegúrate que "Mujer" sea la categoría base
    party = factor(party),
    welfare_support = ifelse(welfare_support == "Aumentar", 1, 0),
    welfare_support = as.factor(welfare_support)
  )
# Verificar después de limpiar
summary(data)
##       age           gender       norm_educ       norm_income       party     
##  Min.   :18.00   Mujer :1955   Min.   :0.0000   Min.   :0.0000   bloc : 318  
##  1st Qu.:33.00   Hombre:2297   1st Qu.:0.5000   1st Qu.:0.2500   cons :1046  
##  Median :48.00   NA's  :   1   Median :0.6000   Median :0.2500   lib  :1282  
##  Mean   :47.27                 Mean   :0.6214   Mean   :0.3944   ndp  :1306  
##  3rd Qu.:62.00                 3rd Qu.:0.8000   3rd Qu.:0.5000   other: 301  
##  Max.   :90.00                 Max.   :1.0000   Max.   :1.0000               
##                                NA's   :12       NA's   :220                  
##  prefsep_welfare    welfare_support
##  Min.   :-1.00000   0:2835         
##  1st Qu.:-1.00000   1:1418         
##  Median : 0.00000                  
##  Mean   : 0.07124                  
##  3rd Qu.: 1.00000                  
##  Max.   : 1.00000                  
## 
str(data)
## tibble [4,253 × 7] (S3: tbl_df/tbl/data.frame)
##  $ age            : num [1:4253] 66 30 67 19 37 47 49 22 37 38 ...
##  $ gender         : Factor w/ 2 levels "Mujer","Hombre": 2 2 2 1 2 2 2 1 2 2 ...
##  $ norm_educ      : num [1:4253] 0.8 0.6 0.9 0.7 0.6 1 0.6 0.3 0.9 0.4 ...
##  $ norm_income    : num [1:4253] 1 0 0.25 NA 0.5 0.5 0 0 0.75 0.75 ...
##  $ party          : Factor w/ 5 levels "bloc","cons",..: 2 2 2 3 5 4 2 3 2 4 ...
##  $ prefsep_welfare: num [1:4253] -1 1 -1 -1 -1 1 0 1 -1 0 ...
##  $ welfare_support: Factor w/ 2 levels "0","1": 1 2 1 1 1 2 1 2 1 1 ...

4. MODELOS

4.1 Modelo 1: sociodemográficos

modelo1 <- glm(
  welfare_support ~ age + gender + norm_educ + norm_income,
  data = data,
  family = binomial(link = "logit")
)

summary(modelo1)
## 
## Call:
## glm(formula = welfare_support ~ age + gender + norm_educ + norm_income, 
##     family = binomial(link = "logit"), data = data)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -1.2291  -0.9338  -0.7809   1.3080   2.0013  
## 
## Coefficients:
##               Estimate Std. Error z value Pr(>|z|)    
## (Intercept)  -0.233902   0.154135  -1.518  0.12914    
## age          -0.006549   0.002010  -3.258  0.00112 ** 
## genderHombre  0.142860   0.068628   2.082  0.03737 *  
## norm_educ     0.417333   0.179098   2.330  0.01980 *  
## norm_income  -1.279782   0.115687 -11.062  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 5136.2  on 4025  degrees of freedom
## Residual deviance: 4998.7  on 4021  degrees of freedom
##   (227 observations deleted due to missingness)
## AIC: 5008.7
## 
## Number of Fisher Scoring iterations: 4

Intepretación: Los resultados muestran que la edad tiene un efecto negativo y significativo (-0.0065, p = 0.001), indicando que las personas mayores son menos propensas a respaldar un aumento del gasto. El género masculino (0.143, p = 0.037) y el nivel educativo (0.417, p = 0.020) tienen efectos positivos y significativos, lo que sugiere que los hombres y las personas con mayor educación tienden a mostrar mayor apoyo. Por el contrario, el nivel de ingresos tiene un efecto fuertemente negativo (-1.280, p < 0.001), evidenciando que quienes poseen mayores recursos económicos son menos favorables a políticas redistributivas. En conjunto, el modelo confirma la relevancia de las condiciones socioeconómicas en la formación de actitudes hacia el bienestar.

4.2 Modelo 2: añadiendo afiliación política

modelo2 <- glm(
  welfare_support ~ age + gender + norm_educ + norm_income + party,
  data = data,
  family = binomial(link = "logit")
)

summary(modelo2)
## 
## Call:
## glm(formula = welfare_support ~ age + gender + norm_educ + norm_income + 
##     party, family = binomial(link = "logit"), data = data)
## 
## Deviance Residuals: 
##     Min       1Q   Median       3Q      Max  
## -1.3574  -0.9616  -0.6691   1.2290   2.3144  
## 
## Coefficients:
##               Estimate Std. Error z value Pr(>|z|)    
## (Intercept)  -0.199425   0.190337  -1.048  0.29476    
## age          -0.004273   0.002071  -2.064  0.03906 *  
## genderHombre  0.201412   0.070207   2.869  0.00412 ** 
## norm_educ     0.345391   0.182503   1.893  0.05842 .  
## norm_income  -1.186313   0.117948 -10.058  < 2e-16 ***
## partycons    -1.026069   0.146897  -6.985 2.85e-12 ***
## partylib     -0.097886   0.134350  -0.729  0.46626    
## partyndp      0.220515   0.132782   1.661  0.09677 .  
## partyother    0.062928   0.172780   0.364  0.71570    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## (Dispersion parameter for binomial family taken to be 1)
## 
##     Null deviance: 5136.2  on 4025  degrees of freedom
## Residual deviance: 4831.9  on 4017  degrees of freedom
##   (227 observations deleted due to missingness)
## AIC: 4849.9
## 
## Number of Fisher Scoring iterations: 4

Interpretacion: En el segundo modelo se incorpora la afiliación partidaria como variable explicativa, lo que mejora el ajuste general del modelo y permite observar cómo las orientaciones ideológicas modulan las preferencias por el gasto social. Aunque los efectos de la edad, el género, la educación y los ingresos se mantienen en la misma dirección que en el modelo anterior, el resultado más destacable es que identificarse con el partido conservador reduce significativamente la probabilidad de apoyar un aumento del gasto en bienestar (coef. = -1.026, p < 0.001). Esto sugiere que las actitudes hacia el gasto social no solo dependen de factores demográficos, sino también de la identidad política, confirmando la influencia del posicionamiento ideológico en las preferencias redistributivas.

4.3 Comparación de modelos

# Ver si el modelo 2 mejora significativamente el ajuste
anova(modelo1, modelo2, test = "Chisq")
## Analysis of Deviance Table
## 
## Model 1: welfare_support ~ age + gender + norm_educ + norm_income
## Model 2: welfare_support ~ age + gender + norm_educ + norm_income + party
##   Resid. Df Resid. Dev Df Deviance  Pr(>Chi)    
## 1      4021     4998.7                          
## 2      4017     4831.9  4   166.84 < 2.2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1

Interpretacion: El Modelo 2 ofrece un mejor ajuste que el Modelo 1, ya que la inclusión de la variable party reduce significativamente la devianza (ΔDeviance = 166.84, p < 0.001). Esto demuestra que la afiliación partidaria mejora la capacidad explicativa del modelo, al captar diferencias relevantes en el apoyo al gasto en bienestar social. En síntesis, el Modelo 2 es el preferido, porque integra tanto factores sociodemográficos como políticos, proporcionando una comprensión más completa de las actitudes hacia las políticas de bienestar.

# También puedes comparar con AIC:
AIC(modelo1, modelo2)
##         df      AIC
## modelo1  5 5008.694
## modelo2  9 4849.854

Interpretacion: El Modelo 2 es superior al Modelo 1, ya que presenta un AIC menor (4849.85 vs. 5008.69) y una reducción significativa de la devianza (p < 0.001). Esto confirma que la inclusión de la afiliación partidaria mejora el ajuste y la capacidad explicativa del modelo sobre el apoyo al gasto en bienestar social.

4.4 Diagnóstico básico (heterocedasticidad, colinealidad, influencia)

library(car)
## Loading required package: carData
## 
## Attaching package: 'car'
## The following object is masked from 'package:dplyr':
## 
##     recode
vif(modelo2)  # valores > 5 o 10 indican multicolinealidad
##                 GVIF Df GVIF^(1/(2*Df))
## age         1.029414  1        1.014600
## gender      1.017665  1        1.008794
## norm_educ   1.064663  1        1.031825
## norm_income 1.078549  1        1.038532
## party       1.034493  4        1.004248
# Influencia de observaciones (detecta países con mucha influencia)

#summary(influence)

# Gráficos de diagnóstico
plot(modelo2)

5. Resultados prácticos

# Odds ratios (razones de momios)
exp(coef(modelo2))
##  (Intercept)          age genderHombre    norm_educ  norm_income    partycons 
##    0.8192016    0.9957360    1.2231281    1.4125428    0.3053450    0.3584131 
##     partylib     partyndp   partyother 
##    0.9067527    1.2467183    1.0649498

Interpretacion: Los resultados del modelo muestran que la edad reduce ligeramente el apoyo al gasto social (OR = 0.996), mientras que ser hombre lo incrementa (OR = 1.22). Un mayor nivel educativo también aumenta la probabilidad de apoyo (OR = 1.41), pero mayores ingresos la reducen notablemente (OR = 0.31). En cuanto a la afiliación partidaria, identificarse con el partido conservador disminuye el respaldo (OR = 0.36) y hacerlo con el NDP lo incrementa (OR = 1.25), mientras que los liberales y otros partidos presentan efectos menores (OR = 0.91 y OR = 1.06, respectivamente).

# Intervalos de confianza del OR
exp(confint(modelo2))
## Waiting for profiling to be done...
##                  2.5 %    97.5 %
## (Intercept)  0.5635947 1.1888391
## age          0.9916994 0.9997836
## genderHombre 1.0661043 1.4039022
## norm_educ    0.9881557 2.0210871
## norm_income  0.2419506 0.3842114
## partycons    0.2687850 0.4782469
## partylib     0.6977187 1.1818508
## partyndp     0.9623659 1.6201509
## partyother   0.7588657 1.4944840
# Paquetes necesarios
library(broom)

# Si ya tienes el modelo (modelo2), extraemos los coeficientes y los OR con IC
coefs <- broom::tidy(modelo2, conf.int = TRUE, exp = TRUE)

# Renombramos para claridad
coefs <- coefs %>%
  rename(Odds_Ratio = estimate,
         IC_low = conf.low,
         IC_high = conf.high)

# Gráfico de coeficientes con IC
ggplot(coefs, aes(x = reorder(term, Odds_Ratio), y = Odds_Ratio)) +
  geom_point(size = 3, color = "#0072B2") +
  geom_errorbar(aes(ymin = IC_low, ymax = IC_high), width = 0.1, color = "gray40") +
  geom_hline(yintercept = 1, linetype = "dashed", color = "red") +
  coord_flip() +
  labs(
    title = "Odds Ratios e Intervalos de Confianza (95%)",
    x = "Variables del modelo",
    y = "Odds Ratio (escala logarítmica)"
  ) +
  scale_y_log10() +
  theme_minimal(base_size = 13)

Interpretacion: “Los intervalos de confianza confirman la dirección y significancia de varios efectos. La edad tiene un efecto negativo significativo sobre el apoyo al gasto social (OR = 0.996; IC 95% [0.99, 1.00]), mientras que ser hombre lo aumenta (OR = 1.22; IC [1.07, 1.40]). El nivel educativo muestra un efecto positivo pero no significativo (IC [0.99, 2.02]). En cambio, el ingreso tiene un efecto negativo y claramente significativo (OR = 0.31; IC [0.24, 0.38]). Respecto al partido, los conservadores presentan un menor apoyo (OR = 0.36; IC [0.27, 0.48]), mientras que los liberales (OR = 0.91; IC [0.70, 1.18]), el NDP (OR = 1.25; IC [0.96, 1.62]) y otros partidos (OR = 1.06; IC [0.76, 1.49]) no difieren significativamente del grupo de referencia.”