source("../_common.R")
suppressPackageStartupMessages({
library("lavaan")
library("semTools")
})set.seed(42)
46 ✏️ Esercizi
E1. Si ripeta l’esercizio che abbiamo svolto in precedenza usando l’analisi fattoriale esplorativa, questa volta usando la CFA in lavaan
. I dati sono forniti da Brown (2015) e riguardano a otto misure di personalità raccolte su un campione di 250 pazienti che hanno concluso un programma di psicoterapia:
- anxiety (N1),
- hostility (N2),
- depression (N3),
- self-consciousness (N4),
- warmth (E1),
- gregariousness (E2),
- assertiveness (E3),
- positive emotions (E4).
<- c("N1", "N2", "N3", "N4", "E1", "E2", "E3", "E4")
varnames <- "5.7 5.6 6.4 5.7 6.0 6.2 5.7 5.6"
sds
<- "
cors 1.000
0.767 1.000
0.731 0.709 1.000
0.778 0.738 0.762 1.000
-0.351 -0.302 -0.356 -0.318 1.000
-0.316 -0.280 -0.300 -0.267 0.675 1.000
-0.296 -0.289 -0.297 -0.296 0.634 0.651 1.000
-0.282 -0.254 -0.292 -0.245 0.534 0.593 0.566 1.000"
<- getCov(cors, names = varnames)
psychot_cor_mat <- 250 n
Il modello con due fattori ortogonali può essere adattato ai dati nel modo seguente.
<- "
cfa_mod N =~ N1 + N2 + N3 + N4
E =~ E1 + E2 + E3 + E4
"
<- lavaan::cfa(
fit_cfa
cfa_mod,sample.cov = psychot_cor_mat,
sample.nobs = n,
orthogonal = TRUE,
std.lv = TRUE
)
::semPaths(fit_cfa,
semPlotwhat = "col", whatLabels = "par", style = "mx",
layout = "tree2", nCharNodes = 7,
shapeMan = "rectangle", sizeMan = 8, sizeMan2 = 5
)
Esaminiamo le saturazioni fattoriali:
parameterEstimates(fit_cfa, standardized = TRUE) %>%
::filter(op == "=~") %>%
dplyr::select(
dplyr"Latent Factor" = lhs,
Indicator = rhs,
B = est,
SE = se,
Z = z,
"p-value" = pvalue,
Beta = std.all
%>%
) ::kable(
knitrdigits = 3, booktabs = TRUE, format = "markdown",
caption = "Factor Loadings"
)
Table: Factor Loadings
|Latent Factor |Indicator | B| SE| Z| p-value| Beta|
|:-------------|:---------|-----:|-----:|------:|-------:|-----:|
|N |N1 | 0.882| 0.051| 17.422| 0| 0.884|
|N |N2 | 0.847| 0.052| 16.340| 0| 0.849|
|N |N3 | 0.840| 0.052| 16.134| 0| 0.842|
|N |N4 | 0.882| 0.051| 17.432| 0| 0.884|
|E |E1 | 0.795| 0.056| 14.276| 0| 0.796|
|E |E2 | 0.838| 0.054| 15.369| 0| 0.839|
|E |E3 | 0.788| 0.056| 14.097| 0| 0.789|
|E |E4 | 0.697| 0.058| 11.942| 0| 0.699|
Il risultato sembra sensato: le saturazioni su ciascun fattore sono molto alte. Tuttavia, la matrice delle correlazioni residue
<- residuals(fit_cfa, type = "cor")$cov
cor_table ::kable(
knitr
cor_table,digits = 3,
format = "markdown",
booktabs = TRUE
)
| | N1| N2| N3| N4| E1| E2| E3| E4|
|:--|------:|------:|------:|------:|------:|------:|------:|------:|
|N1 | 0.000| 0.017| -0.013| -0.003| -0.351| -0.316| -0.296| -0.282|
|N2 | 0.017| 0.000| -0.006| -0.012| -0.302| -0.280| -0.289| -0.254|
|N3 | -0.013| -0.006| 0.000| 0.018| -0.356| -0.300| -0.297| -0.292|
|N4 | -0.003| -0.012| 0.018| 0.000| -0.318| -0.267| -0.296| -0.245|
|E1 | -0.351| -0.302| -0.356| -0.318| 0.000| 0.007| 0.006| -0.022|
|E2 | -0.316| -0.280| -0.300| -0.267| 0.007| 0.000| -0.011| 0.007|
|E3 | -0.296| -0.289| -0.297| -0.296| 0.006| -0.011| 0.000| 0.015|
|E4 | -0.282| -0.254| -0.292| -0.245| -0.022| 0.007| 0.015| 0.000|
rivela che il modello ipotizzato dall’analisi fattoriale confermativa non è adeguato.
<- lavaan::cfa(
fit2_cfa
cfa_mod,sample.cov = psychot_cor_mat,
sample.nobs = n,
orthogonal = FALSE,
std.lv = TRUE
)
::semPaths(fit2_cfa,
semPlotwhat = "col", whatLabels = "par", style = "mx",
layout = "tree2", nCharNodes = 7,
shapeMan = "rectangle", sizeMan = 8, sizeMan2 = 5
)
Esaminiamo le saturazioni fattoriali.
parameterEstimates(fit2_cfa, standardized = TRUE) %>%
::filter(op == "=~") %>%
dplyr::select(
dplyr"Latent Factor" = lhs,
Indicator = rhs,
B = est,
SE = se,
Z = z,
"p-value" = pvalue,
Beta = std.all
%>%
) ::kable(
knitrdigits = 3, booktabs = TRUE, format = "markdown",
caption = "Factor Loadings"
)
Table: Factor Loadings
|Latent Factor |Indicator | B| SE| Z| p-value| Beta|
|:-------------|:---------|-----:|-----:|------:|-------:|-----:|
|N |N1 | 0.883| 0.051| 17.472| 0| 0.885|
|N |N2 | 0.847| 0.052| 16.337| 0| 0.849|
|N |N3 | 0.842| 0.052| 16.190| 0| 0.844|
|N |N4 | 0.880| 0.051| 17.381| 0| 0.882|
|E |E1 | 0.800| 0.055| 14.465| 0| 0.802|
|E |E2 | 0.832| 0.054| 15.294| 0| 0.834|
|E |E3 | 0.788| 0.056| 14.150| 0| 0.789|
|E |E4 | 0.698| 0.058| 11.974| 0| 0.699|
Esaminiamo i residui.
<- residuals(fit2_cfa, type = "cor")$cov
cor_table ::kable(
knitr
cor_table,digits = 3,
format = "markdown",
booktabs = TRUE
)
| | N1| N2| N3| N4| E1| E2| E3| E4|
|:--|------:|------:|------:|------:|------:|------:|------:|------:|
|N1 | 0.000| 0.016| -0.015| -0.002| -0.042| 0.005| 0.008| -0.013|
|N2 | 0.016| 0.000| -0.007| -0.010| -0.006| 0.028| 0.002| 0.004|
|N3 | -0.015| -0.007| 0.000| 0.018| -0.062| 0.006| -0.007| -0.035|
|N4 | -0.002| -0.010| 0.018| 0.000| -0.010| 0.053| 0.007| 0.023|
|E1 | -0.042| -0.006| -0.062| -0.010| 0.000| 0.006| 0.001| -0.027|
|E2 | 0.005| 0.028| 0.006| 0.053| 0.006| 0.000| -0.007| 0.010|
|E3 | 0.008| 0.002| -0.007| 0.007| 0.001| -0.007| 0.000| 0.014|
|E4 | -0.013| 0.004| -0.035| 0.023| -0.027| 0.010| 0.014| 0.000|
Sistemiamo le saturazioni fattoriali in una matrice 8 \(\times\) 2:
<- inspect(fit2_cfa, what = "std")$lambda
lambda lambda
N | E | |
---|---|---|
N1 | 0.8848214 | 0.0000000 |
N2 | 0.8485128 | 0.0000000 |
N3 | 0.8436432 | 0.0000000 |
N4 | 0.8819736 | 0.0000000 |
E1 | 0.0000000 | 0.8018485 |
E2 | 0.0000000 | 0.8337599 |
E3 | 0.0000000 | 0.7894530 |
E4 | 0.0000000 | 0.6990366 |
Otteniamo la matrice di intercorrelazoni fattoriali.
<- inspect(fit2_cfa, what = "std")$psi
Phi Phi
N | E | |
---|---|---|
N | 1.000000 | -0.434962 |
E | -0.434962 | 1.000000 |
Otteniamo la matrice di varianze residue.
<- inspect(fit2_cfa, what = "std")$theta
Psi Psi
N1 | N2 | N3 | N4 | E1 | E2 | E3 | E4 | |
---|---|---|---|---|---|---|---|---|
N1 | 0.217091 | 0.0000000 | 0.0000000 | 0.0000000 | 0.000000 | 0.0000000 | 0.000000 | 0.0000000 |
N2 | 0.000000 | 0.2800261 | 0.0000000 | 0.0000000 | 0.000000 | 0.0000000 | 0.000000 | 0.0000000 |
N3 | 0.000000 | 0.0000000 | 0.2882661 | 0.0000000 | 0.000000 | 0.0000000 | 0.000000 | 0.0000000 |
N4 | 0.000000 | 0.0000000 | 0.0000000 | 0.2221225 | 0.000000 | 0.0000000 | 0.000000 | 0.0000000 |
E1 | 0.000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.357039 | 0.0000000 | 0.000000 | 0.0000000 |
E2 | 0.000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.000000 | 0.3048445 | 0.000000 | 0.0000000 |
E3 | 0.000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.000000 | 0.0000000 | 0.376764 | 0.0000000 |
E4 | 0.000000 | 0.0000000 | 0.0000000 | 0.0000000 | 0.000000 | 0.0000000 | 0.000000 | 0.5113478 |
Mediante i parametri del modello la matrice di correlazione si riproduce nel modo seguente:
\[ \boldsymbol{\Sigma} =\boldsymbol{\Lambda} \boldsymbol{\Phi} \boldsymbol{\Lambda}^{\mathsf{T}} + \boldsymbol{\Psi}. \]
In \(\textsf{R}\) scriviamo:
<- lambda %*% Phi %*% t(lambda) + Psi
R_hat %>%
R_hat round(3)
N1 | N2 | N3 | N4 | E1 | E2 | E3 | E4 | |
---|---|---|---|---|---|---|---|---|
N1 | 1.000 | 0.751 | 0.746 | 0.780 | -0.309 | -0.321 | -0.304 | -0.269 |
N2 | 0.751 | 1.000 | 0.716 | 0.748 | -0.296 | -0.308 | -0.291 | -0.258 |
N3 | 0.746 | 0.716 | 1.000 | 0.744 | -0.294 | -0.306 | -0.290 | -0.257 |
N4 | 0.780 | 0.748 | 0.744 | 1.000 | -0.308 | -0.320 | -0.303 | -0.268 |
E1 | -0.309 | -0.296 | -0.294 | -0.308 | 1.000 | 0.669 | 0.633 | 0.561 |
E2 | -0.321 | -0.308 | -0.306 | -0.320 | 0.669 | 1.000 | 0.658 | 0.583 |
E3 | -0.304 | -0.291 | -0.290 | -0.303 | 0.633 | 0.658 | 1.000 | 0.552 |
E4 | -0.269 | -0.258 | -0.257 | -0.268 | 0.561 | 0.583 | 0.552 | 1.000 |
Le correlazioni residue sono:
- R_hat) %>%
(psychot_cor_mat round(3)
N1 | N2 | N3 | N4 | E1 | E2 | E3 | E4 | |
---|---|---|---|---|---|---|---|---|
N1 | 0.000 | 0.016 | -0.015 | -0.002 | -0.042 | 0.005 | 0.008 | -0.013 |
N2 | 0.016 | 0.000 | -0.007 | -0.010 | -0.006 | 0.028 | 0.002 | 0.004 |
N3 | -0.015 | -0.007 | 0.000 | 0.018 | -0.062 | 0.006 | -0.007 | -0.035 |
N4 | -0.002 | -0.010 | 0.018 | 0.000 | -0.010 | 0.053 | 0.007 | 0.023 |
E1 | -0.042 | -0.006 | -0.062 | -0.010 | 0.000 | 0.006 | 0.001 | -0.027 |
E2 | 0.005 | 0.028 | 0.006 | 0.053 | 0.006 | 0.000 | -0.007 | 0.010 |
E3 | 0.008 | 0.002 | -0.007 | 0.007 | 0.001 | -0.007 | 0.000 | 0.014 |
E4 | -0.013 | 0.004 | -0.035 | 0.023 | -0.027 | 0.010 | 0.014 | 0.000 |
Calcoliamo la correlazione predetta dal modello tra le variabili \(Y_1\) e \(Y_2\):
1, 1] * lambda[2, 1] + lambda[1, 2] * lambda[2, 2] +
lambda[1, 1] * lambda[2, 2] * Phi[1, 2] +
lambda[1, 2] * lambda[2, 1] * Phi[1, 2] lambda[
Questo risultato è molto simile al valore contenuto dell’elemento (1, 2) della matrice di correlazioni osservate:
1, 2] psychot_cor_mat[
Usando le funzonalità di lavaan
la matrice di correlazione predetta si ottiene con:
fitted(fit2_cfa)$cov |>
print()
N1 N2 N3 N4 E1 E2 E3 E4
N1 0.996
N2 0.748 0.996
N3 0.743 0.713 0.996
N4 0.777 0.745 0.741 0.996
E1 -0.307 -0.295 -0.293 -0.306 0.996
E2 -0.320 -0.306 -0.305 -0.319 0.666 0.996
E3 -0.303 -0.290 -0.289 -0.302 0.630 0.656 0.996
E4 -0.268 -0.257 -0.255 -0.267 0.558 0.580 0.550 0.996
La matrice dei residui è
resid(fit2_cfa)$cov |>
print()
N1 N2 N3 N4 E1 E2 E3 E4
N1 0.000
N2 0.016 0.000
N3 -0.015 -0.007 0.000
N4 -0.002 -0.010 0.018 0.000
E1 -0.042 -0.006 -0.062 -0.010 0.000
E2 0.005 0.028 0.006 0.053 0.006 0.000
E3 0.008 0.002 -0.007 0.007 0.001 -0.007 0.000
E4 -0.013 0.004 -0.035 0.023 -0.026 0.010 0.014 0.000
La matrice dei residui standardizzati è
resid(fit2_cfa, type = "standardized")$cov |>
print()
N1 N2 N3 N4 E1 E2 E3 E4
N1 0.000
N2 1.674 0.000
N3 -1.769 -0.569 0.000
N4 -0.350 -1.152 1.746 0.000
E1 -1.214 -0.161 -1.646 -0.294 0.000
E2 0.154 0.794 0.168 1.626 0.637 0.000
E3 0.219 0.062 -0.191 0.193 0.075 -0.693 0.000
E4 -0.314 0.092 -0.824 0.552 -1.481 0.624 0.690 0.000
I valori precedenti possono essere considerati come punti z, dove i valori con un valore assoluto maggiore di 2 possono essere ritenuti problematici. Tuttavia, è importante considerare che in questo modo si stanno eseguendo molteplici confronti, pertanto, si dovrebbe considerare l’opportunità di applicare una qualche forma di correzione per i confronti multipli.
E2. Si utilizzino i dati dass21.txt
che corrispondono alla somministrazione del test DASS-21 a 334 partecipanti. Lo schema di codifica si può trovare seguendo questo link. Si adatti ai dati un modello a tre fattori usando l’analisi fattoriale esplorativa con la funzione lavaan::efa()
. Usando le saturazioni fattoriali e la matrice di inter-correlazioni fattoriali, si trovi la matrice di correlazioni riprodotta dal modello. Senza usare l’albebra matriciale, si trovi la correlazione predetta tra gli indicatori DASS-1 e DASS-2.