Práctico 6. Análisis factorial Exploratorio

Estadística IV

Fecha de publicación

1 de octubre de 2024

Análisis factorial exploratorio (AFE)

Presentación

Para el taller práctico de hoy utilizaremos la base de datos del Estudio Longitudinal Social de Chile, realizado por el Centro de estudios del conflicto y la cohesión social COES.

El Estudio Longitudinal Social del Chile ELSOC, único en Chile y América Latina, consiste en encuestar a casi 3.000 chilenos, anualmente, a lo largo de una década. ELSOC ha sido diseñado para evaluar la manera cómo piensan, sienten y se comportan los chilenos en torno a un conjunto de temas referidos al conflicto y la cohesión social en Chile. La población objetivo son hombres y mujeres entre 15 y 75 años de edad, tiene una representación de la población nacional urbana, donde se obtuvo una muestra original de 2927 casos en el año 2016 y mantiene 1728 en 2022, además de una muestra de refresco en 2018.

Objetivo general

El objetivo de este ejercicio práctico es comprender y estimar un análisis factorial exploratorio con el fin de reducir la dimensionalidad de una batería de variables.

Cargar paquetes

Código
pacman::p_load(tidyverse, #Conjunto de paquetes, sobre todo dplyr y ggplot2
               car, #Para recodificar
               haven,
               summarytools, #Para descriptivos
               sjmisc,
               psych,     # para Alfa de Chronbach
               sjPlot,
               psy, # scree plot function
               nFactors, # parallel
               GPArotation, # Rotación
               sjlabelled)

options(scipen = 999) # para desactivar notacion cientifica
rm(list = ls()) # para limpiar el entorno de trabajo

Cargar base de datos

Código
load(url("https://dataverse.harvard.edu/api/access/datafile/7245118")) #Cargar base de datos

Visualización de datos

Código
dim(elsoc_long_2016_2022.2)
[1] 18035   750

Debido a la naturaleza longitudinal de ELSOC, la base de datos contiene 18035 casos (las mismas personas durante 6 años) y 750 variables (las mismas variables en 6 periodos distintos). Por lo tanto, para simplificar el proceso de análisis de este práctico trabajaremos solo con los casos y variables de quienes participaron en la cuarta ola (2019)

Datos y variables

Para estimar AFE, utilizaremos específicamente el módulo de Ciudadanía. De este módulo utilizaremos un concepto en particular llamado Confianza en instituciones con los ítems:

  • Grado de acuerdo: Mujeres son mas refinadas

  • Grado de acuerdo: Mujeres deberian ser protegidas

  • Grado de acuerdo: Mujeres consiguen privilegios en nombre de igualdad

  • Grado de acuerdo: Mujeres derrotadas se quejan de discriminacion

La idea general es ver si esque todas estas variables miden algún tipo de Confianza en instituciones o si esque existen dimensiones subyacentes.

Filtrar base de datos

Filtraremos la base de datos para quedarnos con las observaciones correspondientes solamente a la ola 4, y además seleccionaremos los ítems de interés.

Código
data <- elsoc_long_2016_2022.2 %>% filter(ola==4) %>%  # seleccionamos solo los casos de la ola 1
  select(son_refinadas=g01_01,
         ser_protegidas=g01_02,
         consiguen_privilegios=g01_03,
         quejan_discriminacion=g01_04
         )

head(data)
  son_refinadas ser_protegidas consiguen_privilegios quejan_discriminacion
1             5              4                     4                     4
2             4              5                     5                     2
3             4              5                     4                     4
4             3              4                     3                     4
5             4              4                     4                     4
6             4              4                     4                     4
Código
table(data$son_refinadas)

-999 -888    1    2    3    4    5 
   6   15  108  473  590 1731  494 
Código
table(data$ser_protegidas)

-999 -888    1    2    3    4    5 
   2    1   35  148  244 1784 1203 
Código
table(data$consiguen_privilegios)

-999 -888    1    2    3    4    5 
   4   57   79  487  611 1887  292 
Código
table(data$quejan_discriminacion)

-999 -888    1    2    3    4    5 
   8   64  106  717  669 1641  212 

Estos ítems cuentan con las mismas categorías de respuesta: (1) totalmente desacuerdo, a (5) Totalmente de acuerdo. Además de los valores codificados como -888 y -999.

Recodificar

Recodificamos los valores -888 y -999 en NA y eliminamos los NAs.

Código
data$son_refinadas <- car::recode(data$son_refinadas, "c(-999,-888)=NA")
data$ser_protegidas <- car::recode(data$ser_protegidas, "c(-999,-888)=NA")
data$consiguen_privilegios <- car::recode(data$consiguen_privilegios, "c(-999,-888)=NA")
data$quejan_discriminacion <- car::recode(data$quejan_discriminacion, "c(-999,-888)=NA")

data$son_refinadas <- set_labels(data$son_refinadas,
            labels=c( "Totalmente desacuerdo"=1,
                      "Desacuerdo"=2,
                      "Ni de acuerdo ni desacuerdo"=3,
                      "De acuerdo"=4,
                      "Totalmente de acuerdo"=5))

data$ser_protegidas <- set_labels(data$ser_protegidas,
            labels=c( "Totalmente desacuerdo"=1,
                      "Desacuerdo"=2,
                      "Ni de acuerdo ni desacuerdo"=3,
                      "De acuerdo"=4,
                      "Totalmente de acuerdo"=5))

data$consiguen_privilegios <- set_labels(data$consiguen_privilegios,
            labels=c( "Totalmente desacuerdo"=1,
                      "Desacuerdo"=2,
                      "Ni de acuerdo ni desacuerdo"=3,
                      "De acuerdo"=4,
                      "Totalmente de acuerdo"=5))

data$quejan_discriminacion <- set_labels(data$quejan_discriminacion,
            labels=c( "Totalmente desacuerdo"=1,
                      "Desacuerdo"=2,
                      "Ni de acuerdo ni desacuerdo"=3,
                      "De acuerdo"=4,
                      "Totalmente de acuerdo"=5))

Análisis

Código
data %>% 
  plot_stackfrq() + theme(legend.position="bottom")

Estimar correlación

Código
tab_corr(data, triangle = "lower")
  Grado de acuerdo: Mujeres son mas
refinadas
Grado de acuerdo: Mujeres deberian ser
protegidas
Grado de acuerdo: Mujeres consiguen
privilegios en nombre de igualdad
Grado de acuerdo: Mujeres derrotadas se
quejan de discriminacion
Grado de acuerdo: Mujeres son mas
refinadas
       
Grado de acuerdo: Mujeres deberian ser
protegidas
0.364***      
Grado de acuerdo: Mujeres consiguen
privilegios en nombre de igualdad
0.224*** 0.199***    
Grado de acuerdo: Mujeres derrotadas se
quejan de discriminacion
0.183*** 0.163*** 0.453***  
Computed correlation used pearson-method with listwise-deletion.

Podemos observar que todas las correlaciones son positivas, por lo que no quedaron ítems invertidos.

Análisis factorial exploratorio

¿Qué se puede deducir de la matriz de correlaciones en relación a la estructura subyacente en términos de variables latentes? No hay claridad de grupos de indicadores asociados entre sí.

Test de adecuación de matriz para AFE

KMO (Kaiser, Meyer, Olkin Measure of Sampling Adequacy):

  • Varía entre 0 y 1. Contrasta si las correlaciones parciales entre las variables son pequeñas

  • Valores pequeños (menores a 0.5) indican que los datos no serían adecuados para AFE, ya que las correlaciones entre pares de variables no pueden ser explicadas por otras variables.

Código
corMat  <- data %>% 
  cor(use = "complete.obs")  # estimar matriz pearson

KMO(corMat)
Kaiser-Meyer-Olkin factor adequacy
Call: KMO(r = corMat)
Overall MSA =  0.61
MSA for each item = 
        son_refinadas        ser_protegidas consiguen_privilegios 
                 0.63                  0.62                  0.59 
quejan_discriminacion 
                 0.59 

En este caso las correlaciones son altas, por lo que los datos sí son adecuados para AFE.

Nivel de correlaciones de la matriz: test de esfericidad de Barlett

Se utiliza para evluar la hipótesis que la matriz de correlaciones es una matriz identidad (diagonal=1 y bajo la diagonal=0)

  • Se busca significación (p < 0.05) ya que se espera que las variables estén correlacionadas
Código
cortest.bartlett(corMat, n = 3417)
$chisq
[1] 1542.697

$p.value
[1] 0

$df
[1] 6

En este caso el valor p es 0, así que hay significación estadística

Selección de número de factores

Código
scree.plot(data)

Código
fa.parallel(corMat, n.obs=3417)

Parallel analysis suggests that the number of factors =  2  and the number of components =  2 

Extracción

  • ejes principales
Código
fac_pa <- fa(r = data, nfactors = 2, fm= "pa")
#summary(fac_pa)
fac_pa
Factor Analysis using method =  pa
Call: fa(r = data, nfactors = 2, fm = "pa")
Standardized loadings (pattern matrix) based upon correlation matrix
                        PA1   PA2   h2   u2 com
son_refinadas          0.02  0.60 0.37 0.63   1
ser_protegidas        -0.01  0.60 0.35 0.65   1
consiguen_privilegios  0.67  0.03 0.47 0.53   1
quejan_discriminacion  0.68 -0.03 0.44 0.56   1

                       PA1  PA2
SS loadings           0.90 0.72
Proportion Var        0.23 0.18
Cumulative Var        0.23 0.41
Proportion Explained  0.56 0.44
Cumulative Proportion 0.56 1.00

 With factor correlations of 
     PA1  PA2
PA1 1.00 0.47
PA2 0.47 1.00

Mean item complexity =  1
Test of the hypothesis that 2 factors are sufficient.

df null model =  6  with the objective function =  0.45 with Chi Square =  1522.89
df of  the model are -1  and the objective function was  0 

The root mean square of the residuals (RMSR) is  0 
The df corrected root mean square of the residuals is  NA 

The harmonic n.obs is  3354 with the empirical chi square  0.01  with prob <  NA 
The total n.obs was  3417  with Likelihood Chi Square =  0.01  with prob <  NA 

Tucker Lewis Index of factoring reliability =  1.004
Fit based upon off diagonal values = 1
Measures of factor score adequacy             
                                                   PA1  PA2
Correlation of (regression) scores with factors   0.80 0.75
Multiple R square of scores with factors          0.64 0.56
Minimum correlation of possible factor scores     0.28 0.13
  • Maximum likelihood

Maximiza la posibilidad de que los parámetros reproduzcan los datos observados

Código
fac_ml <- fa(r = data, nfactors = 2, fm= "ml")
fac_ml
Factor Analysis using method =  ml
Call: fa(r = data, nfactors = 2, fm = "ml")
Standardized loadings (pattern matrix) based upon correlation matrix
                        ML1   ML2   h2   u2 com
son_refinadas          0.01  0.62 0.38 0.62   1
ser_protegidas        -0.01  0.58 0.34 0.66   1
consiguen_privilegios  0.67  0.03 0.47 0.53   1
quejan_discriminacion  0.68 -0.03 0.44 0.56   1

                       ML1  ML2
SS loadings           0.90 0.72
Proportion Var        0.23 0.18
Cumulative Var        0.23 0.41
Proportion Explained  0.56 0.44
Cumulative Proportion 0.56 1.00

 With factor correlations of 
     ML1  ML2
ML1 1.00 0.47
ML2 0.47 1.00

Mean item complexity =  1
Test of the hypothesis that 2 factors are sufficient.

df null model =  6  with the objective function =  0.45 with Chi Square =  1522.89
df of  the model are -1  and the objective function was  0 

The root mean square of the residuals (RMSR) is  0 
The df corrected root mean square of the residuals is  NA 

The harmonic n.obs is  3354 with the empirical chi square  0  with prob <  NA 
The total n.obs was  3417  with Likelihood Chi Square =  0  with prob <  NA 

Tucker Lewis Index of factoring reliability =  1.004
Fit based upon off diagonal values = 1
Measures of factor score adequacy             
                                                   ML1  ML2
Correlation of (regression) scores with factors   0.80 0.75
Multiple R square of scores with factors          0.64 0.56
Minimum correlation of possible factor scores     0.28 0.13

Rotación

  • Varimax (ortogonal)
Código
fac_ml_var <- fa(r = data, nfactors = 2, fm= "ml", rotate="varimax") # ortogonal
fac_ml_var
Factor Analysis using method =  ml
Call: fa(r = data, nfactors = 2, rotate = "varimax", fm = "ml")
Standardized loadings (pattern matrix) based upon correlation matrix
                       ML1  ML2   h2   u2 com
son_refinadas         0.14 0.60 0.38 0.62 1.1
ser_protegidas        0.12 0.57 0.34 0.66 1.1
consiguen_privilegios 0.65 0.21 0.47 0.53 1.2
quejan_discriminacion 0.65 0.15 0.44 0.56 1.1

                       ML1  ML2
SS loadings           0.88 0.75
Proportion Var        0.22 0.19
Cumulative Var        0.22 0.41
Proportion Explained  0.54 0.46
Cumulative Proportion 0.54 1.00

Mean item complexity =  1.1
Test of the hypothesis that 2 factors are sufficient.

df null model =  6  with the objective function =  0.45 with Chi Square =  1522.89
df of  the model are -1  and the objective function was  0 

The root mean square of the residuals (RMSR) is  0 
The df corrected root mean square of the residuals is  NA 

The harmonic n.obs is  3354 with the empirical chi square  0  with prob <  NA 
The total n.obs was  3417  with Likelihood Chi Square =  0  with prob <  NA 

Tucker Lewis Index of factoring reliability =  1.004
Fit based upon off diagonal values = 1
Measures of factor score adequacy             
                                                   ML1  ML2
Correlation of (regression) scores with factors   0.76 0.71
Multiple R square of scores with factors          0.58 0.51
Minimum correlation of possible factor scores     0.17 0.01
  • Promax (oblicua)
Código
fac_ml_pro <- fa(r = data, nfactors = 2, fm= "ml", rotate="promax")
fac_ml_pro
Factor Analysis using method =  ml
Call: fa(r = data, nfactors = 2, rotate = "promax", fm = "ml")
Standardized loadings (pattern matrix) based upon correlation matrix
                        ML1   ML2   h2   u2 com
son_refinadas          0.01  0.62 0.38 0.62   1
ser_protegidas        -0.01  0.58 0.34 0.66   1
consiguen_privilegios  0.67  0.04 0.47 0.53   1
quejan_discriminacion  0.67 -0.03 0.44 0.56   1

                       ML1  ML2
SS loadings           0.90 0.73
Proportion Var        0.23 0.18
Cumulative Var        0.23 0.41
Proportion Explained  0.55 0.45
Cumulative Proportion 0.55 1.00

 With factor correlations of 
     ML1  ML2
ML1 1.00 0.47
ML2 0.47 1.00

Mean item complexity =  1
Test of the hypothesis that 2 factors are sufficient.

df null model =  6  with the objective function =  0.45 with Chi Square =  1522.89
df of  the model are -1  and the objective function was  0 

The root mean square of the residuals (RMSR) is  0 
The df corrected root mean square of the residuals is  NA 

The harmonic n.obs is  3354 with the empirical chi square  0  with prob <  NA 
The total n.obs was  3417  with Likelihood Chi Square =  0  with prob <  NA 

Tucker Lewis Index of factoring reliability =  1.004
Fit based upon off diagonal values = 1
Measures of factor score adequacy             
                                                   ML1  ML2
Correlation of (regression) scores with factors   0.80 0.75
Multiple R square of scores with factors          0.64 0.56
Minimum correlation of possible factor scores     0.28 0.13

Casi automático con sjPlot

Código
sjPlot::tab_fa(data, method = "ml", rotation = "promax", show.comm = TRUE, title = "Análisis factorial de sexismo")
Parallel analysis suggests that the number of factors =  2  and the number of components =  NA 
Análisis factorial de sexismo
  Factor 1 Factor 2 Communality
Grado de acuerdo: Mujeres son mas
refinadas
0.01 0.62 0.38
Grado de acuerdo: Mujeres deberian ser
protegidas
-0.01 0.58 0.34
Grado de acuerdo: Mujeres consiguen
privilegios en nombre de igualdad
0.67 0.04 0.47
Grado de acuerdo: Mujeres derrotadas se
quejan de discriminacion
0.67 -0.03 0.44
Total Communalities 1.63
Cronbach's α 0.62 0.52

Luego de realizar el Análisis factorial exploratorio existen varias alternativas sobre los pasos a seguir. Por ejemplo, es posible estimar un promedio simple entre cada una de las variables de los factores. Otra opción es estimar puntajes factoriales.