::here("code", "_common.R") |> source()
here
# Load packages
if (!requireNamespace("pacman")) install.packages("pacman")
::p_load(lavaan, semTools, semPlot, patchwork, lme4) pacman
55 Modelli di Equazioni Strutturali Multilivello
I modelli di equazioni strutturali multilivello (multilevel SEM) sono una metodologia statistica avanzata utilizzata per analizzare dati organizzati su più livelli gerarchici. Questa tecnica consente di modellare simultaneamente le variazioni sia tra gruppi (variazione inter-cluster) che all’interno dei gruppi (variazione intra-cluster).
Prerequisiti
Concetti e Competenze Chiave
Preparazione del Notebook
55.1 Introduzione
Nella ricerca psicologica e nelle scienze sociali, i dati raccolti spesso mostrano strutture complesse a più livelli, in cui le informazioni sono organizzate in gruppi o cluster, e le osservazioni all’interno di ogni cluster tendono a essere correlate tra loro. Questo fenomeno rappresenta un aspetto cruciale poiché, in molte situazioni, i modelli classici di equazioni strutturali (SEM) non sono adatti per analizzare dati di questo tipo. La principale limitazione dei modelli SEM tradizionali risiede nella loro incapacità di tenere conto delle correlazioni intrinseche che caratterizzano i dati strutturati su più livelli, il che può portare a stime distorte e inefficaci.
Di conseguenza, per analizzare i dati a struttura multilivello, è necessario estendere l’approccio SEM classico integrando una modellazione adatta a tale struttura. La modellazione delle equazioni strutturali multilivello (multilevel SEM) introduce variabili latenti progettate per catturare sia la variazione tra i cluster sia quella all’interno dei cluster. In questo modo, le variabili osservate sono influenzate da fattori latenti che operano sia a livello individuale che a livello di gruppo.
Questa strategia consente di distinguere tra la variazione sistematica tra i gruppi (variazione tra i cluster) e la variazione individuale all’interno dei gruppi (variazione intra-cluster), permettendo un’analisi più precisa e rappresentativa dei dati complessi tipici delle scienze sociali e psicologiche. Adottando questo approccio, si ottiene una visione più completa e informativa delle dinamiche che sottostanno ai fenomeni studiati, in quanto il modello multilevel SEM è in grado di cogliere sia le differenze tra gruppi sia le specificità individuali all’interno dei gruppi.
55.2 Concetto Generale per la Modellazione a Equazioni Strutturali Multilivello
La tipica implementazione della modellazione a equazioni strutturali multilivello (SEM) prevede la scomposizione dell’outcome osservato in due componenti, una per descrivere la varianza a livello “within” (all’interno) e l’altra a livello “between” (tra gruppi), come segue:
\[ \bar{y}_{ij} - \bar{y}_{..} = (\bar{y}_{ij} - \bar{y}_{.j}) + (\bar{y}_{.j} - \bar{y}_{..}), \]
dove \(j\) è l’indicatore del cluster \(j\)-esimo (ad esempio, una scuola, come nell’esempio sopra), con \(j = 1, \dots, J\) e \(i\) rappresenta l’indicatore dell’individuo \(i\)-esimo all’interno del cluster, con \(i = 1, \dots, n_j\). Il termine \(\bar{y}_{.j}\) indica la media a livello di cluster per il cluster \(j\), mentre \(\bar{y}_{..}\) rappresenta la media complessiva.
Questa equazione corrisponde alla scomposizione della matrice di covarianza della popolazione in componenti “within” e “between”:
\[ \text{Cov}(y) = \Sigma_T = \Sigma_W + \Sigma_B. \]
Basandosi su questa scomposizione, è possibile costruire una funzione di verosimiglianza per stimare i parametri associati ai pesi fattoriali, ai coefficienti di percorso e alle varianze residue nei modelli di equazioni strutturali. Gli errori standard e gli intervalli di credibilità si possono ottenere grazie alla teoria della stima di massima verosimiglianza per l’inferenza statistica. Questa stima viene implementata in lavaan basandosi sui metodi descritti da McDonald e Goldstein (1989).
55.3 Un Esempio Pratico
In questo capitolo introdurremo l’implementazione in lavaan
per l’analisi SEM multilivello seguendo il tutorial fornito sul sito di lavaan.org
.
Utilizzeremo un set di dati artificiali ricavato dal sito di MPlus.
<- read.table("http://statmodel.com/usersguide/chap9/ex9.6.dat")
dat names(dat) <- c("y1", "y2", "y3", "y4", "x1", "x2", "w", "clus")
head(dat)
y1 | y2 | y3 | y4 | x1 | x2 | w | clus | |
---|---|---|---|---|---|---|---|---|
<dbl> | <dbl> | <dbl> | <dbl> | <dbl> | <dbl> | <dbl> | <int> | |
1 | 2.2033 | 1.859 | 1.7385 | 2.245 | 1.143 | -0.797 | -0.150 | 1 |
2 | 1.9349 | 2.128 | 0.0831 | 2.509 | 1.949 | -0.123 | -0.150 | 1 |
3 | 0.3220 | 0.977 | -0.8354 | 0.558 | -0.716 | -0.767 | -0.150 | 1 |
4 | 0.0732 | -1.743 | -2.3103 | -1.514 | -2.649 | 0.638 | -0.150 | 1 |
5 | -1.2149 | 0.453 | 0.3726 | -1.790 | -0.263 | 0.303 | -0.150 | 1 |
6 | 0.2983 | -1.820 | 0.5613 | -2.091 | -0.945 | 1.363 | 0.319 | 2 |
Il data frame è costituito da 1000 righe:
dim(dat) |> print()
[1] 1000 8
Ci sono 110 cluster (clus
), il che significa che ci sono misure ripetute per ciascun cluster (possiamo immaginare che i cluster corrispondano ai soggetti):
length(unique(dat$clus))
Analizzeremo questi dati mediante un modello di equazioni strutturali multilivello. Iniziamo a definire il modello SEM appropriato per questi dati.
<- "
model level: 1
fw =~ y1 + y2 + y3 + y4
fw ~ x1 + x2
level: 2
fb =~ y1 + y2 + y3 + y4
# optional
y1 ~~ 0*y1
y2 ~~ 0*y2
y3 ~~ 0*y3
y4 ~~ 0*y4
fb ~ w
"
Questa sintassi del modello è strutturata su due livelli, uno per il livello 1 (intra-cluster) e uno per il livello 2 (inter-cluster). All’interno di ciascun livello, è possibile specificare un modello come nel caso a livello singolo, ma con una distinzione importante: ogni livello rappresenta fonti di variabilità differenti, in questo caso tra le misurazioni individuali (livello 1) e le differenze tra gruppi o cluster (livello 2).
55.3.1 Spiegazione dei livelli
Livello 1 (Intra-cluster):
- Fattore latente
fw
: Al livello individuale,fw
è un fattore latente che riflette la variazione tra le quattro variabili osservatey1
,y2
,y3
ey4
. La sintassifw =~ y1 + y2 + y3 + y4
indica chefw
è il costrutto latente che sottende questi indicatori osservabili. - Effetto dei predittori
x1
ex2
: Al livello individuale,fw
è modellato in funzione dei predittorix1
ex2
(fw ~ x1 + x2
), che rappresentano variabili a livello intra-cluster che possono influenzare il fattore latentefw
. Questo permette di catturare come i predittori influenzano la variabilità nelle risposte individuali.
- Fattore latente
Livello 2 (Inter-cluster):
- Fattore latente
fb
: Al livello del cluster,fb
rappresenta un secondo fattore latente che viene definito anch’esso dalle variabiliy1
,y2
,y3
ey4
, ma con una prospettiva inter-cluster. Questo livello considera quindi la variazione nei punteggi medi del cluster piuttosto che nelle risposte individuali. - Effetto del predittore
w
: Al livello di cluster,fb
è modellato come funzione del predittorew
(fb ~ w
), che rappresenta una variabile esplicativa per le differenze tra cluster.
- Fattore latente
55.3.2 Parte opzionale
La sezione opzionale, che include espressioni come y1 ~~ 0*y1
, specifica la varianza residua delle variabili osservate y1
, y2
, y3
e y4
al livello di cluster. L’uso di 0*y1
, 0*y2
, etc., indica che la varianza residua a livello inter-cluster viene fissata a zero, assumendo che tutta la varianza tra cluster sia spiegata da fb
.
In sintesi, questo modello permette di distinguere come i fattori latenti (fw
e fb
) siano influenzati rispettivamente da variabili a livello individuale e cluster, consentendo di modellare simultaneamente la variabilità intra- e inter-cluster.
55.3.3 Coefficiente di Correlazione Intraclasse (ICC)
L’analisi SEM Multilivello permette di calcolare il Coefficiente di Correlazione Intraclasse (ICC), una misura statistica utile in studi dove i dati sono raggruppati in cluster o gruppi (come ad esempio soggetti all’interno di classi o pazienti all’interno di ospedali). L’ICC valuta il grado di somiglianza o omogeneità delle misurazioni all’interno di ciascun gruppo rispetto alla variazione totale nei dati.
Più precisamente, l’ICC quantifica la proporzione della varianza totale che può essere attribuita alle differenze tra i gruppi piuttosto che a quelle all’interno dei gruppi. Quando l’ICC è elevato, significa che una parte rilevante della varianza osservata nei dati deriva dalle differenze tra i gruppi. In questo caso, le misurazioni all’interno dello stesso gruppo tendono a essere più simili tra loro rispetto a quelle di gruppi differenti. Al contrario, un ICC basso indica che la varianza è in gran parte dovuta alle differenze individuali all’interno dei gruppi, suggerendo una scarsa influenza del raggruppamento.
In sintesi, l’ICC è un indice di quanto “forte” sia l’effetto del raggruppamento sulle misurazioni, informando sulla necessità di considerare la struttura multilivello dei dati nell’analisi.
55.3.4 ICC nei Modelli SEM Multilivello
Il calcolo dell’ICC (Intra-Class Correlation) per ciascuna variabile osservata in un modello SEM multilivello è essenziale per comprendere la struttura gerarchica dei dati e la variabilità tra i gruppi. L’ICC quantifica la proporzione della varianza totale di una variabile che può essere attribuita a differenze tra gruppi piuttosto che a variazioni individuali all’interno dei gruppi. Un ICC elevato per una variabile suggerisce che l’appartenenza a un determinato gruppo (come una scuola, una famiglia o un ospedale) ha un’influenza rilevante su quella variabile, indicando che una parte consistente della variazione osservata è dovuta alle differenze tra gruppi piuttosto che alle differenze tra individui all’interno di ciascun gruppo.
In pratica, l’ICC è un criterio utile per determinare l’adeguatezza di un modello multilivello. Un ICC basso suggerisce che la variabilità tra i gruppi è limitata e che potrebbe non essere necessario utilizzare un modello multilivello complesso, in quanto le differenze individuali rappresentano la maggior parte della variabilità. Al contrario, un ICC alto indica che la struttura a cluster dei dati è rilevante e che ignorarla potrebbe portare a stime distorte e a conclusioni potenzialmente errate.
Utilizzando l’ICC come guida, i ricercatori possono decidere se e in che misura adottare un approccio multilivello per rappresentare in modo accurato e affidabile la varianza attribuibile a fattori tra e intra-gruppo, ottenendo così una comprensione più precisa dei fenomeni studiati.
55.4 Calcolo dell’ICC con lmer
Per iniziare, poniamoci il problema di calcolare l’ICC mediante un modello lineare multilivello. Svolgeremo questi calcoli con lmer
. Il modello lmer
considera ogni variabile osservata separatamente, fornendo un’analisi indipendente per ciascuna. Per y1
, per esempio, abbiamo:
<- lmer(y1 ~ 1 + (1 | clus), data = dat) model_lmer
Calcoliamo l’ICC:
<- VarCorr(model_lmer)$clus[1]
varianza_cluster <- attr(VarCorr(model_lmer), "sc")^2
varianza_residua <- varianza_cluster / (varianza_cluster + varianza_residua)
ICC ICC
Il Coefficiente di Correlazione Intraclass (ICC) di 0.129 per la variabile y1
significa che circa il 12.9% della variazione totale in y1
è ascrivibile alle differenze tra gli studenti, considerati come unità separate o cluster individuali. Questa percentuale relativamente modesta della variazione totale suggerisce che le caratteristiche o i comportamenti individuali degli studenti spiegano solo una piccola parte della variazione osservata in y1
.
Un ICC di questo livello, che si può considerare relativamente basso, implica che la maggior parte della variazione nella variabile non è legata in modo sostanziale alle differenze tra gli studenti. Questo può essere indicativo del fatto che altri fattori, esterni alle caratteristiche individuali degli studenti, giocano un ruolo più determinante. In un contesto educativo, ad esempio, questo potrebbe suggerire che elementi come l’ambiente scolastico, le metodologie didattiche impiegate, o le specificità del programma di studi, hanno un impatto maggiore sulla variazione di y1
rispetto alle differenze individuali tra gli studenti.
55.5 Calcolo dell’ICC con sem
Ora calcoliamo l’ICC utilizzando un modello SEM multilivello. Per adattare questo modello, è necessario aggiungere l’argomento cluster=
nella chiamata alla funzione sem
di lavaan
. Questo argomento specifica la variabile di raggruppamento, permettendo al modello di tenere conto della struttura a cluster dei dati e di stimare l’ICC per ciascuna variabile osservata.
<- sem(model,
fit data = dat,
cluster = "clus",
fixed.x = FALSE
)
L’argomento fixed.x
controlla come vengono trattate le variabili predittive (o esogene) all’interno del modello.
Quando fixed.x = FALSE
, si sta indicando a lavaan di trattare le variabili esogene non come valori fissi, ma come variabili aleatorie con una propria varianza e covarianza da stimare nel modello. Questo significa che le variabili esogene non sono considerate “date” o senza errore, ma il modello tiene conto della loro variabilità.
fixed.x = TRUE
(impostazione predefinita in lavaan):- Le variabili esogene sono considerate senza errore (cioè come dati “fissi”).
- Non si stima la varianza delle variabili esogene.
- Questo approccio è tipico nei modelli di regressione classici, dove le variabili predittive sono trattate come note e prive di errore.
fixed.x = FALSE
:- Le variabili esogene sono considerate come variabili aleatorie con errori di misurazione, quindi la loro varianza e covarianza vengono stimate.
- Questo approccio è più realistico in molti contesti psicologici e sociali, dove è ragionevole assumere che anche le variabili esogene possano contenere errori.
In molte situazioni di ricerca, le variabili esogene (come i punteggi dei questionari o le misure di osservazione) non sono perfettamente accurate e possono contenere errore. Impostare fixed.x = FALSE
consente di modellare questa incertezza, offrendo una rappresentazione più realistica dei dati.
summary(fit) |>
print()
lavaan 0.6-19 ended normally after 27 iterations
Estimator ML
Optimization method NLMINB
Number of model parameters 26
Number of observations 1000
Number of clusters [clus] 110
Model Test User Model:
Test statistic 3.863
Degrees of freedom 17
P-value (Chi-square) 1.000
Parameter Estimates:
Standard errors Standard
Information Observed
Observed information based on Hessian
Level 1 [within]:
Latent Variables:
Estimate Std.Err z-value P(>|z|)
fw =~
y1 1.000
y2 0.999 0.033 30.735 0.000
y3 0.995 0.033 29.804 0.000
y4 1.017 0.033 30.364 0.000
Regressions:
Estimate Std.Err z-value P(>|z|)
fw ~
x1 0.973 0.042 23.287 0.000
x2 0.510 0.038 13.422 0.000
Covariances:
Estimate Std.Err z-value P(>|z|)
x1 ~~
x2 0.032 0.032 1.014 0.311
Intercepts:
Estimate Std.Err z-value P(>|z|)
x1 0.007 0.031 0.222 0.825
x2 0.014 0.032 0.440 0.660
Variances:
Estimate Std.Err z-value P(>|z|)
.y1 0.981 0.057 17.151 0.000
.y2 0.948 0.056 17.015 0.000
.y3 1.070 0.060 17.700 0.000
.y4 1.014 0.059 17.182 0.000
.fw 0.980 0.071 13.888 0.000
x1 0.985 0.044 22.361 0.000
x2 1.017 0.045 22.361 0.000
Level 2 [clus]:
Latent Variables:
Estimate Std.Err z-value P(>|z|)
fb =~
y1 1.000
y2 0.960 0.073 13.078 0.000
y3 0.924 0.074 12.452 0.000
y4 0.949 0.075 12.631 0.000
Regressions:
Estimate Std.Err z-value P(>|z|)
fb ~
w 0.344 0.078 4.429 0.000
Intercepts:
Estimate Std.Err z-value P(>|z|)
.y1 -0.083 0.074 -1.128 0.259
.y2 -0.077 0.071 -1.081 0.280
.y3 -0.045 0.071 -0.637 0.524
.y4 -0.030 0.072 -0.418 0.676
w 0.006 0.086 0.070 0.944
Variances:
Estimate Std.Err z-value P(>|z|)
.y1 0.000
.y2 0.000
.y3 0.000
.y4 0.000
.fb 0.361 0.078 4.643 0.000
w 0.815 0.110 7.416 0.000
fitMeasures(fit) |>
print()
npar fmin chisq
26.000 3.913 3.863
df pvalue baseline.chisq
17.000 1.000 3283.563
baseline.df baseline.pvalue cfi
24.000 0.000 1.000
tli nnfi rfi
1.006 1.006 0.998
nfi pnfi ifi
0.999 0.707 1.004
rni logl unrestricted.logl
1.004 -9527.429 -9525.497
aic bic ntotal
19106.857 19234.459 1000.000
bic2 rmsea rmsea.ci.lower
19151.882 0.000 0.000
rmsea.ci.upper rmsea.ci.level rmsea.pvalue
0.000 0.900 1.000
rmsea.close.h0 rmsea.notclose.pvalue rmsea.notclose.h0
0.050 0.000 0.080
srmr srmr_within srmr_between
0.022 0.004 0.017
Quando calcoliamo l’ICC utilizzando lavaan
, otteniamo valori distinti per ciascuna variabile osservata all’interno del modello multilivello. Questi valori rappresentano la proporzione di varianza in ogni variabile che è attribuibile alle differenze tra i gruppi, considerando le relazioni specificate nel modello SEM. In altre parole, l’ICC di ciascun item riflette quanto le differenze tra i gruppi influenzano quella particolare variabile, nel contesto delle dipendenze definite dal modello.
Per ottenere l’ICC per ciascuno dei quattro item, è possibile utilizzare il comando:
lavInspect(fit, "icc") |>
print()
y1 y2 y3 y4 x1 x2
0.125 0.121 0.106 0.115 0.000 0.000
Nel caso di y1
, la stima di ICC fornita dal modello SEM multilivello è molto simile al risultato ottenuto con lmer
.
55.6 Riflessioni Conclusive
In questo capitolo, abbiamo illustrato il modello di equazioni strutturali multilivello utilizzando lavaan
. Come evidenziato dall’esempio, l’implementazione in lavaan
è molto diretta, richiedendo solo l’inclusione dell’opzione cluster
nella funzione sem
. È importante sottolineare che, al momento, lavaan
supporta solo modelli SEM a due livelli.
Nell’ambito dei modelli SEM multilivello, abbiamo visto come l’interpretazione dei coefficienti di correlazione intra-classe (ICC) possa fornire intuizioni significative sulla variazione dei dati all’interno di gruppi o cluster. Un ICC basso, come quello osservato nell’esempio (0.129), indica che una porzione minore della variazione totale è attribuibile alle differenze tra i cluster. Nel contesto specifico dei nostri dati, dove ogni studente è considerato un cluster individuale, ciò suggerisce che fattori esterni agli studenti stessi potrebbero giocare un ruolo più significativo nella variazione osservata rispetto alle caratteristiche individuali degli studenti.
In conclusione, la modellazione di equazioni strutturali multilivello è uno strumento potente e flessibile nell’analisi di dati strutturati gerarchicamente. lavaan
, sebbene limitato ai modelli a due livelli, fornisce un approccio accessibile e diretto per questi tipi di analisi. Per modelli più complessi e a più livelli, Mplus offre soluzioni alternative che possono gestire una gamma più ampia di esigenze analitiche.
Informazioni sull’Ambiente di Sviluppo
sessionInfo()
R version 4.4.2 (2024-10-31)
Platform: aarch64-apple-darwin20
Running under: macOS Sequoia 15.1
Matrix products: default
BLAS: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRblas.0.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.4-arm64/Resources/lib/libRlapack.dylib; LAPACK version 3.12.0
locale:
[1] C
time zone: Europe/Rome
tzcode source: internal
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] lme4_1.1-35.5 Matrix_1.7-1 MASS_7.3-61 viridis_0.6.5
[5] viridisLite_0.4.2 ggpubr_0.6.0 ggExtra_0.10.1 gridExtra_2.3
[9] patchwork_1.3.0 bayesplot_1.11.1 semTools_0.5-6 semPlot_1.1.6
[13] lavaan_0.6-19 psych_2.4.6.26 scales_1.3.0 markdown_1.13
[17] knitr_1.49 lubridate_1.9.3 forcats_1.0.0 stringr_1.5.1
[21] dplyr_1.1.4 purrr_1.0.2 readr_2.1.5 tidyr_1.3.1
[25] tibble_3.2.1 ggplot2_3.5.1 tidyverse_2.0.0 here_1.0.1
loaded via a namespace (and not attached):
[1] rstudioapi_0.17.1 jsonlite_1.8.9 magrittr_2.0.3
[4] TH.data_1.1-2 estimability_1.5.1 farver_2.1.2
[7] nloptr_2.1.1 rmarkdown_2.29 vctrs_0.6.5
[10] minqa_1.2.8 base64enc_0.1-3 rstatix_0.7.2
[13] htmltools_0.5.8.1 broom_1.0.7 Formula_1.2-5
[16] htmlwidgets_1.6.4 plyr_1.8.9 sandwich_3.1-1
[19] emmeans_1.10.5 zoo_1.8-12 uuid_1.2-1
[22] igraph_2.1.1 mime_0.12 lifecycle_1.0.4
[25] pkgconfig_2.0.3 R6_2.5.1 fastmap_1.2.0
[28] shiny_1.9.1 digest_0.6.37 OpenMx_2.21.13
[31] fdrtool_1.2.18 colorspace_2.1-1 rprojroot_2.0.4
[34] Hmisc_5.2-0 fansi_1.0.6 timechange_0.3.0
[37] abind_1.4-8 compiler_4.4.2 withr_3.0.2
[40] glasso_1.11 htmlTable_2.4.3 backports_1.5.0
[43] carData_3.0-5 ggsignif_0.6.4 corpcor_1.6.10
[46] gtools_3.9.5 tools_4.4.2 pbivnorm_0.6.0
[49] foreign_0.8-87 zip_2.3.1 httpuv_1.6.15
[52] nnet_7.3-19 glue_1.8.0 quadprog_1.5-8
[55] promises_1.3.0 nlme_3.1-166 lisrelToR_0.3
[58] grid_4.4.2 pbdZMQ_0.3-13 checkmate_2.3.2
[61] cluster_2.1.6 reshape2_1.4.4 generics_0.1.3
[64] gtable_0.3.6 tzdb_0.4.0 data.table_1.16.2
[67] hms_1.1.3 car_3.1-3 utf8_1.2.4
[70] sem_3.1-16 pillar_1.9.0 IRdisplay_1.1
[73] rockchalk_1.8.157 later_1.3.2 splines_4.4.2
[76] cherryblossom_0.1.0 lattice_0.22-6 survival_3.7-0
[79] kutils_1.73 tidyselect_1.2.1 miniUI_0.1.1.1
[82] pbapply_1.7-2 airports_0.1.0 stats4_4.4.2
[85] xfun_0.49 qgraph_1.9.8 arm_1.14-4
[88] stringi_1.8.4 pacman_0.5.1 boot_1.3-31
[91] evaluate_1.0.1 codetools_0.2-20 mi_1.1
[94] cli_3.6.3 RcppParallel_5.1.9 IRkernel_1.3.2
[97] rpart_4.1.23 xtable_1.8-4 repr_1.1.7
[100] munsell_0.5.1 Rcpp_1.0.13-1 coda_0.19-4.1
[103] png_0.1-8 XML_3.99-0.17 parallel_4.4.2
[106] usdata_0.3.1 jpeg_0.1-10 mvtnorm_1.3-2
[109] openxlsx_4.2.7.1 crayon_1.5.3 openintro_2.5.0
[112] rlang_1.1.4 multcomp_1.4-26 mnormt_2.1.1