Managerial Problem

The purpose of this factor analysis example is to detect the underlying structure in the relationship between several loyalty items measured in a survey. The dataset used within this section is called Loyalty.xls and it describes the following managerial problem.

The sports company Shoetas wishes to assess the degree of consumers´loyalty towards Shoetas´trainers. They interviewed 189 consumers in a sports store through the medium of a questionnaire. Two dimensions of loyalty are taken into consideration, namely the cognitive loyalty and the affective loyalty. Cognitive loyalty was measured by rating six statements on 5-point Likert-scale, ranging from 1 = “completely disagree” to 5 = “completely agree”. The statements used in the questionnaire are the following:

Affective loyalty was measured by rating three statements on 5-point Likert-scale, ranging from 1 = completely disagree to 5= completely agree. The statements used in the questionnaire are the the following:

Solución

El problema planteado por la compañía Shoetas implica una solución mediante un análisis que permita entender si las evaluaciones de la marca se corresponden efectivamente con la estructura de las variables latentes construídas por la empresa. Para ello se buscará definir mediante un análisis de factores si las estructuras predefinidas de las dimensiones de “Cognitive Loyalty” y de “Affective Loyalty” se corresponden con el set de variables utilizados. Se trabajará con la base loyalty que incluye las 9 variable de las dimensiones cognitivas y afectivas y cuenta con 189 observaciones.

#Levantamos el archivo

library(readxl)

loyalty<- read_excel(path ="C:\\Users\\jonat\\OneDrive\\Escritorio\\Maestria generacion y analisis de informacion estadistica\\9. Estadistica aplicada a la investigacion de mercados\\2. Mapas perceptuales\\Loyalty.xls")

library(tidyverse)

loyalty<- column_to_rownames(loyalty, var= "id")

El primer paso antes de realizar un análisis de corrrespondencia es identificar si nuetra base cuenta con casos perdidos que requieran ser reemplazados.

#Chequeamos la estructura de la base

summary(loyalty)
##      ALOY1           ALOY2          ALOY3           CLOY1           CLOY2      
##  Min.   :1.000   Min.   :1.00   Min.   :1.000   Min.   :2.000   Min.   :1.000  
##  1st Qu.:4.000   1st Qu.:4.00   1st Qu.:3.000   1st Qu.:4.000   1st Qu.:4.000  
##  Median :4.000   Median :4.00   Median :4.000   Median :4.000   Median :4.000  
##  Mean   :4.148   Mean   :4.28   Mean   :3.783   Mean   :4.275   Mean   :4.095  
##  3rd Qu.:5.000   3rd Qu.:5.00   3rd Qu.:5.000   3rd Qu.:5.000   3rd Qu.:5.000  
##  Max.   :5.000   Max.   :5.00   Max.   :5.000   Max.   :5.000   Max.   :5.000  
##      CLOY3           CLOY4           CLOY5           CLOY6      
##  Min.   :1.000   Min.   :1.000   Min.   :1.000   Min.   :1.000  
##  1st Qu.:4.000   1st Qu.:4.000   1st Qu.:4.000   1st Qu.:3.000  
##  Median :4.000   Median :4.000   Median :4.000   Median :4.000  
##  Mean   :4.175   Mean   :4.074   Mean   :4.169   Mean   :4.058  
##  3rd Qu.:5.000   3rd Qu.:5.000   3rd Qu.:5.000   3rd Qu.:5.000  
##  Max.   :5.000   Max.   :5.000   Max.   :5.000   Max.   :5.000
str(loyalty)
## 'data.frame':    189 obs. of  9 variables:
##  $ ALOY1: num  5 4 3 4 3 3 3 3 5 5 ...
##  $ ALOY2: num  5 5 4 4 3 3 4 3 5 5 ...
##  $ ALOY3: num  5 3 3 4 3 3 3 3 3 5 ...
##  $ CLOY1: num  5 5 4 4 2 3 5 4 4 5 ...
##  $ CLOY2: num  5 5 4 4 3 3 5 4 4 5 ...
##  $ CLOY3: num  5 5 4 4 2 3 5 4 5 5 ...
##  $ CLOY4: num  5 4 4 4 2 3 5 4 5 5 ...
##  $ CLOY5: num  5 4 4 4 2 3 5 4 5 5 ...
##  $ CLOY6: num  5 4 3 4 3 3 4 3 3 5 ...

Una vez que nos aseguramos que nuestra base no cuenta con casos perdidos, procedemos a estandarizar todas las variables. Este proceso evita sesgos que puedan ser introducidos por distintos niveles de escalas de las variables y que puedan afectar al análisis factorial. De este modo se asumen todas las variables con media “0” (cero).

#Standarizamos las escalas de las variables a factorizar

loyalty_scale<- data.frame(scale(loyalty))

summary(loyalty_scale)
##      ALOY1             ALOY2             ALOY3             CLOY1        
##  Min.   :-3.7310   Min.   :-4.0370   Min.   :-3.0941   Min.   :-3.1561  
##  1st Qu.:-0.1756   1st Qu.:-0.3451   1st Qu.:-0.8706   1st Qu.:-0.3817  
##  Median :-0.1756   Median :-0.3451   Median : 0.2412   Median :-0.3817  
##  Mean   : 0.0000   Mean   : 0.0000   Mean   : 0.0000   Mean   : 0.0000  
##  3rd Qu.: 1.0096   3rd Qu.: 0.8855   3rd Qu.: 1.3529   3rd Qu.: 1.0056  
##  Max.   : 1.0096   Max.   : 0.8855   Max.   : 1.3529   Max.   : 1.0056  
##      CLOY2             CLOY3             CLOY4              CLOY5        
##  Min.   :-3.9022   Min.   :-4.0201   Min.   :-3.71160   Min.   :-3.8624  
##  1st Qu.:-0.1201   1st Qu.:-0.2211   1st Qu.:-0.08944   1st Qu.:-0.2063  
##  Median :-0.1201   Median :-0.2211   Median :-0.08944   Median :-0.2063  
##  Mean   : 0.0000   Mean   : 0.0000   Mean   : 0.00000   Mean   : 0.0000  
##  3rd Qu.: 1.1406   3rd Qu.: 1.0452   3rd Qu.: 1.11795   3rd Qu.: 1.0124  
##  Max.   : 1.1406   Max.   : 1.0452   Max.   : 1.11795   Max.   : 1.0124  
##      CLOY6         
##  Min.   :-3.64474  
##  1st Qu.:-1.26116  
##  Median :-0.06936  
##  Mean   : 0.00000  
##  3rd Qu.: 1.12243  
##  Max.   : 1.12243

La primera aproximación para entender si nuestras variables son factorizables es realizar una matriz de correlación la cual nos arroja un primer indicio sobre si podremos hallar algún tipo de relación entre las variables que nos den cuenta de variables latentes o no observadas. Viendo la matriz de correlación se pueden identificar varias variables con buenas correlaciones con un coeficiente del 0.4 o más. Por ejemplo, CLOY1 correlaciona fuertemente con otras variables de la dimensión denominada lealtad cognitiva pero lo hace en menor medida con las variables de la dimensión afectiva.

#Observamos las correlaciones entre las variables 

library(corrplot)

correla_loyalty <- cor(loyalty_scale)
#Observamos las correlaciones entre las variables 

corrplot(correla_loyalty, order= "hclust")

Siguiendo lo expusto más arriba, el Test de Bartlett nos indica de manera numérica si la correlación entre las variables analizadas es lo suficientemente grande para realizar un análisis. Este test parte de la Hipótesis nula de que la matriz de coeficientes de correlación no es significativamente distinta de la matriz de identidad. En nuestro caso con un P value de 3.203898e-283 rechazamos la hipótesis nula y podemos decir que la correlación es significativamente distinta de la matriz de identidad.

#Testeo de esfericidad 
library(psych)

cortest.bartlett(correla_loyalty, n=189)
## $chisq
## [1] 1458.09
## 
## $p.value
## [1] 3.203898e-283
## 
## $df
## [1] 36

Además de contrastar si las correlaciones son distintas a la matriz de identidad, debemos contrastar si la muestra es lo suficientemente pequeña para un análisis factorial. El test de Kaiser-Meyer-Olkin tiene como finalidad determinar qué tan adecuada es nuestra muestra. Con un Overall MSA = 0.86 nuestra muestra presenta una buena adecuación para un análisis factorial, también se observan buenos valores para cada una de las variables.

#Test de KMO 

KMO(loyalty_scale)
## Kaiser-Meyer-Olkin factor adequacy
## Call: KMO(r = loyalty_scale)
## Overall MSA =  0.86
## MSA for each item = 
## ALOY1 ALOY2 ALOY3 CLOY1 CLOY2 CLOY3 CLOY4 CLOY5 CLOY6 
##  0.85  0.82  0.86  0.92  0.88  0.85  0.89  0.86  0.86

Una vez que nos hemos asegurado que nuestro set de datos sea válido para un análisis factorial o un análisis de componentes principales podemos proceder. A continuación se corre un análisis de componentes principales en el cual podemos destacar que siguiendo el método de los autovalores, podríamos decir que se identifican dos componentes principales. Tanto el PC1 y el PC2 tienen valores de desvío standard mayor a uno lo cuál nos da un indicio de que estos son los dos componentes a seleccionar y que entre los dos explican casi el 80% de la variancia total.

#Componentes principales

loyalty_PC<- prcomp(loyalty_scale)

summary(loyalty_PC)
## Importance of components:
##                           PC1    PC2     PC3     PC4     PC5     PC6     PC7
## Standard deviation     2.3473 1.2743 0.69432 0.66346 0.53794 0.45382 0.42465
## Proportion of Variance 0.6122 0.1804 0.05357 0.04891 0.03215 0.02288 0.02004
## Cumulative Proportion  0.6122 0.7926 0.84619 0.89510 0.92725 0.95013 0.97017
##                            PC8     PC9
## Standard deviation     0.38314 0.34880
## Proportion of Variance 0.01631 0.01352
## Cumulative Proportion  0.98648 1.00000

En cambio, en el criterio del constrante de caída, se observa que la curva tiende a estancarse a partir del tercer componente. Sin embargo, si tomamos el criterio de la raíz latente se observa que el componente PC3 tiene un valor bajo de sólo un 0.5% de la variancia.

#Ploteamos el grafico de sedimentacion
plot(loyalty_PC, type= 'l')

En el análisis del biplot podemos ver que las variables se agrupan en dós grupos homogéneos entre sí mientras que no se distingue una fuerte tendencia a la dispersión de los casos sino que tienen a concentrarse de manera homogénea.

#Biplot

biplot(loyalty_PC)

Entonces, si quisieramos determinar la cantidad de componentes para un análisis de los componentes principales deberíamos delimitarnos a dos grupos. En este punto sólo bastaría contrastar las cargas de las variables para determinar si la estructura de las dimensiones afectivas y cognitivas de lealtad a Shoetas se cumple o no. Las cargas de las variables para el componente uno son negatiivas y no presentarían de manera clara alguna tendencia en particular, mientras que el componente dos tiene signos positivos en todas las variables de lealtad afectiva (ALOY1 a ALOY3) y CLOY (6). El análisis de los componentes principales nos permitiría reducir los datos e incluso crear escalas aditivas. Pero como nuestro fin es determinar la estructura, resultará pertinente proceder con un análisis factorial.

#Seleccionamos los factores mediante el metodo de los componentes principales. Solo 2 sin rotacion


loyalty_PC<- prcomp(loyalty_scale, rank. = 2)

loyalty_PC
## Standard deviations (1, .., p=9):
## [1] 2.3473137 1.2742561 0.6943241 0.6634601 0.5379420 0.4538213 0.4246545
## [8] 0.3831427 0.3487974
## 
## Rotation (n x k) = (9 x 2):
##              PC1        PC2
## ALOY1 -0.3301171  0.3411057
## ALOY2 -0.3340774  0.3779836
## ALOY3 -0.2926799  0.4366218
## CLOY1 -0.3297481 -0.3077233
## CLOY2 -0.3504813 -0.2619504
## CLOY3 -0.3416527 -0.2582582
## CLOY4 -0.3482747 -0.3037055
## CLOY5 -0.3422103 -0.2970512
## CLOY6 -0.3271891  0.3736994

Los eigenvalues del análisis factorial nos permite deducir una conclusión similar a la de los componentes principales en lo referido a la cantidad de factores que vamos a seleccionar. A continuación se muestran los eingenvalues, la forma gráfica de solución y el análisis de paralelas comparando el método de componentes principales y de análisis factorial con la información real y simulada. Queda claro entonces que la solución evidente es la de seleccionar dos componentes o factores.

#Eigenvalues para el FA
library(nFactors)
## Warning: package 'nFactors' was built under R version 4.1.3
## Loading required package: lattice
## 
## Attaching package: 'nFactors'
## The following object is masked from 'package:lattice':
## 
##     parallel
eigen(correla_loyalty)
## eigen() decomposition
## $values
## [1] 5.5098814 1.6237286 0.4820859 0.4401793 0.2893816 0.2059538 0.1803314
## [8] 0.1467983 0.1216596
## 
## $vectors
##             [,1]       [,2]        [,3]         [,4]        [,5]        [,6]
##  [1,] -0.3301171 -0.3411057  0.21583769  0.513355328  0.19219336  0.21788717
##  [2,] -0.3340774 -0.3779836  0.04280657  0.417532801  0.06241108 -0.12104156
##  [3,] -0.2926799 -0.4366218 -0.14587272 -0.510398767 -0.27681348  0.48858802
##  [4,] -0.3297481  0.3077233  0.23827156 -0.322523659  0.74877438  0.08425939
##  [5,] -0.3504813  0.2619504 -0.48336607  0.053667913 -0.03842030  0.32355544
##  [6,] -0.3416527  0.2582582 -0.58471172  0.180573728  0.02338267 -0.22646331
##  [7,] -0.3482747  0.3037055  0.26361597  0.004848457 -0.47859480 -0.34402261
##  [8,] -0.3422103  0.2970512  0.47747882 -0.010904116 -0.29345544  0.23091770
##  [9,] -0.3271891 -0.3736994 -0.02279367 -0.402460846  0.06845323 -0.60366210
##             [,7]         [,8]        [,9]
##  [1,]  0.1892345  0.364854324  0.45957427
##  [2,] -0.1380196 -0.355396485 -0.63675144
##  [3,]  0.3334972 -0.105311462 -0.06526315
##  [4,]  0.1842492 -0.005753169 -0.18448331
##  [5,] -0.4951535  0.437516093 -0.17105654
##  [6,]  0.3379657 -0.422155399  0.31275077
##  [7,]  0.3926143  0.385501627 -0.25843532
##  [8,] -0.3851210 -0.443506929  0.28651716
##  [9,] -0.3716327  0.120439381  0.26285252
#Scree para determinar factores del analisis factorial

scree(loyalty_scale)

#Analisis de las paralelas

fa.parallel(loyalty_scale, n.obs = 100)

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

Debido a que nuestra intención es entender los constructos que subyacen a los datos, realizamos un análisis factorial con dos factores.

#Fa para entender los constructos que subyacen a los datos con 2 factores

loyalty_fa<- factanal(loyalty_scale, factors= 2)


loyalty_fa$loadings
## 
## Loadings:
##       Factor1 Factor2
## ALOY1 0.308   0.833  
## ALOY2 0.278   0.893  
## ALOY3 0.208   0.749  
## CLOY1 0.801   0.205  
## CLOY2 0.795   0.287  
## CLOY3 0.767   0.290  
## CLOY4 0.861   0.238  
## CLOY5 0.836   0.243  
## CLOY6 0.305   0.770  
## 
##                Factor1 Factor2
## SS loadings      3.612   2.969
## Proportion Var   0.401   0.330
## Cumulative Var   0.401   0.731

Al observar las cargas factoriales para estos dos factores es un poco más clara la solución con respecto a nuestro problema. La estructura de las dimensiones pareciera responder a las categorías creadas por Shoetas para medir la lealtad de los clientes hacia la marca, pero con algunas salvedades. Mientras que las variables de lealtad afectiva responden efectivamente a la dimensión, no todas las variables de lealtad cognitiva lo hacen bien con su dimensión. La variable CLOY6(“If someone proposes that I use another trainers’ brand, I will continue using Shoetas for their price”) responde de hecho a cuestiones más relacionadas con las variables emocionales que a cuestiones racionales. Podríamos decir que la elección de Shoetas por su precio sobre el precio de otras zapatillas está ligada a una dimensión de lealtad emocional más que racional o de producto en sí.

#Visualizamos la estructura de los dos factores obtenidos

library(gplots)
library(RColorBrewer)

heatmap.2(loyalty_fa$loadings, 
          col=brewer.pal(9, "Greens"), trace="none", key=FALSE, dend="none",
          Colv=FALSE, cexCol = 1.2,
          main="\n\n\n\nHeatmap de cargas factoriales")

#Visualizamos la estructura 

library(semPlot)

semPaths(loyalty_fa, what="est", residuals=FALSE,
         cut=0.7, posCol=c("white", "darkgreen"), negCol=c("white", "red"),
         edge.label.cex=0.75, nCharNodes=7)