40. La struttura delle medie#
source("../_common.R")
40.1. L’impiego delle Medie nei Modelli di Equazioni Strutturali (SEM)#
Nei modelli di equazioni strutturali (SEM), simili all’analisi fattoriale, esaminiamo principalmente le relazioni di covarianza tra le variabili. Una caratteristica distintiva dei modelli SEM rispetto all’analisi fattoriale tradizionale è la possibilità di includere le medie sia delle variabili osservate che di quelle latenti. Questo è particolarmente utile in modelli come quelli di analisi fattoriale confermativa (CFA) longitudinale, dove le ipotesi si concentrano sulle medie dei costrutti analizzati.
40.1.1. Interpretazione delle Intercette nei Modelli SEM#
In un modello SEM, l’intercetta di una variabile indicatore (denotata con \( \tau \)) indica la media stimata di quella variabile. Il valore di \( \tau \) rappresenta il valore atteso dell’indicatore quando il fattore latente a cui è associato è zero. La relazione generale per un indicatore \( y \) in un modello SEM è data dalla formula:
dove:
\( y \) è il punteggio osservato dell’indicatore.
\( \lambda \) rappresenta il carico fattoriale, che indica quanto fortemente l’indicatore è influenzato dal fattore latente.
\( \tau \) è l’intercetta, cioè la media stimata dell’indicatore.
\( \varepsilon \) è l’errore di misura associato all’indicatore.
40.1.2. Struttura delle Medie nel Modello CFA#
Nel contesto di un modello CFA, la struttura delle medie è descritta dalla formula:
qui:
\( \Lambda \) è la matrice dei carichi fattoriali.
\( \mu_{\text{lat}} \) è il vettore che rappresenta le medie dei costrutti latenti.
\( \tau \) è il vettore delle intercette degli indicatori.
40.1.3. Utilizzo delle Medie nel Software lavaan#
Nel software lavaan, utilizzato per l’analisi SEM, è possibile stimare le intercette inserendo l’opzione meanstructure = TRUE nella sintassi del modello. Questo comando permette di includere automaticamente una costante “1” in tutte le equazioni del modello, facilitando così il calcolo delle intercette per le variabili endogene. È necessario fornire i dati originali o una matrice di covarianza, insieme alle medie di tutte le variabili interessate.
40.2. Un Esempio Pratico#
Utilizziamo il dataset HolzingerSwineford1939 per costruire un modello di misurazione con tre costrutti latenti (visual, textual, speed), ciascuno definito da tre indicatori (x1, x2, x3, ecc.).
data(HolzingerSwineford1939)
glimpse(HolzingerSwineford1939)
Rows: 301
Columns: 15
$ id <int> 1, 2, 3, 4, 5, 6, 7, 8, 9, 11, 12, 13, 14, 15, 16, 17, 18, 19, …
$ sex <int> 1, 2, 2, 1, 2, 2, 1, 2, 2, 2, 1, 1, 2, 2, 1, 2, 2, 1, 2, 2, 1, …
$ ageyr <int> 13, 13, 13, 13, 12, 14, 12, 12, 13, 12, 12, 12, 12, 12, 12, 12,…
$ agemo <int> 1, 7, 1, 2, 2, 1, 1, 2, 0, 5, 2, 11, 7, 8, 6, 1, 11, 5, 8, 3, 1…
$ school <fct> Pasteur, Pasteur, Pasteur, Pasteur, Pasteur, Pasteur, Pasteur, …
$ grade <int> 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, …
$ x1 <dbl> 3.333333, 5.333333, 4.500000, 5.333333, 4.833333, 5.333333, 2.8…
$ x2 <dbl> 7.75, 5.25, 5.25, 7.75, 4.75, 5.00, 6.00, 6.25, 5.75, 5.25, 5.7…
$ x3 <dbl> 0.375, 2.125, 1.875, 3.000, 0.875, 2.250, 1.000, 1.875, 1.500, …
$ x4 <dbl> 2.333333, 1.666667, 1.000000, 2.666667, 2.666667, 1.000000, 3.3…
$ x5 <dbl> 5.75, 3.00, 1.75, 4.50, 4.00, 3.00, 6.00, 4.25, 5.75, 5.00, 3.5…
$ x6 <dbl> 1.2857143, 1.2857143, 0.4285714, 2.4285714, 2.5714286, 0.857142…
$ x7 <dbl> 3.391304, 3.782609, 3.260870, 3.000000, 3.695652, 4.347826, 4.6…
$ x8 <dbl> 5.75, 6.25, 3.90, 5.30, 6.30, 6.65, 6.20, 5.15, 4.65, 4.55, 5.7…
$ x9 <dbl> 6.361111, 7.916667, 4.416667, 4.861111, 5.916667, 7.500000, 4.8…
hs_model <- "
visual =~ NA*x1 + x2 + x3
textual =~ NA*x4 + x5 + x6
speed =~ NA*x7 + x8 + x9
visual ~~ 1*visual
textual ~~ 1 * textual
speed ~~ 1 * speed
"
Utilizziamo l’argomento meanstructure = TRUE per richiedere la stima delle intercette degli indicatori \( \tau \).
Ogni costrutto latente è definito in relazione ai suoi indicatori, dove le intercette degli indicatori (\(\tau\)) non sono fissate a priori, ma stimate dal modello.
Le varianze dei costrutti latenti sono fissate a 1, mentre le loro medie sono fissate a 0 (come evidenziato dall’output, righe 34-36).
Nel caso presente, poiché le medie dei costrutti latenti sono fissate a zero, la media predetta per gli indicatori corrisponde alle intercette stimate.
fit <- cfa(hs_model,
data = HolzingerSwineford1939,
meanstructure = TRUE
)
params <- parameterEstimates(fit)
print(params)
lhs op rhs est se z pvalue ci.lower ci.upper
1 visual =~ x1 0.900 0.081 11.128 0 0.741 1.058
2 visual =~ x2 0.498 0.077 6.429 0 0.346 0.650
3 visual =~ x3 0.656 0.074 8.817 0 0.510 0.802
4 textual =~ x4 0.990 0.057 17.474 0 0.879 1.101
5 textual =~ x5 1.102 0.063 17.576 0 0.979 1.224
6 textual =~ x6 0.917 0.054 17.082 0 0.811 1.022
7 speed =~ x7 0.619 0.070 8.903 0 0.483 0.756
8 speed =~ x8 0.731 0.066 11.090 0 0.602 0.860
9 speed =~ x9 0.670 0.065 10.305 0 0.543 0.797
10 visual ~~ visual 1.000 0.000 NA NA 1.000 1.000
11 textual ~~ textual 1.000 0.000 NA NA 1.000 1.000
12 speed ~~ speed 1.000 0.000 NA NA 1.000 1.000
13 x1 ~~ x1 0.549 0.114 4.833 0 0.326 0.772
14 x2 ~~ x2 1.134 0.102 11.146 0 0.934 1.333
15 x3 ~~ x3 0.844 0.091 9.317 0 0.667 1.022
16 x4 ~~ x4 0.371 0.048 7.779 0 0.278 0.465
17 x5 ~~ x5 0.446 0.058 7.642 0 0.332 0.561
18 x6 ~~ x6 0.356 0.043 8.277 0 0.272 0.441
19 x7 ~~ x7 0.799 0.081 9.823 0 0.640 0.959
20 x8 ~~ x8 0.488 0.074 6.573 0 0.342 0.633
21 x9 ~~ x9 0.566 0.071 8.003 0 0.427 0.705
22 visual ~~ textual 0.459 0.064 7.189 0 0.334 0.584
23 visual ~~ speed 0.471 0.073 6.461 0 0.328 0.613
24 textual ~~ speed 0.283 0.069 4.117 0 0.148 0.418
25 x1 ~1 4.936 0.067 73.473 0 4.804 5.067
26 x2 ~1 6.088 0.068 89.855 0 5.955 6.221
27 x3 ~1 2.250 0.065 34.579 0 2.123 2.378
28 x4 ~1 3.061 0.067 45.694 0 2.930 3.192
29 x5 ~1 4.341 0.074 58.452 0 4.195 4.486
30 x6 ~1 2.186 0.063 34.667 0 2.062 2.309
31 x7 ~1 4.186 0.063 66.766 0 4.063 4.309
32 x8 ~1 5.527 0.058 94.854 0 5.413 5.641
33 x9 ~1 5.374 0.058 92.546 0 5.260 5.488
34 visual ~1 0.000 0.000 NA NA 0.000 0.000
35 textual ~1 0.000 0.000 NA NA 0.000 0.000
36 speed ~1 0.000 0.000 NA NA 0.000 0.000
40.2.1. Interpretazione delle Medie Stimate#
La media dei punteggi osservati per gli indicatori (x1, x2, x3, ecc.) viene calcolata attraverso le intercette stimate dal modello. È fondamentale distinguere tra la media empirica, calcolata direttamente dai dati, e la media predetta dal modello. La media predetta degli indicatori in un modello dove la media dei costrutti latenti è fissata a zero è influenzata esclusivamente dalle loro intercette.
40.2.2. Calcolo delle Medie Osservate e Predette in R#
Consideriamo gli indicatori x1, x2, x3. Per calcolare la media osservata di questi indicatori, usiamo le loro intercette stimate.
intercepts <- params$est[params$op == "~1"][1:9] # Intercette degli indicatori (τ)
Questo ci fornisce le intercette degli indicatori:
intercepts |> print()
[1] 4.935770 6.088040 2.250415 3.060908 4.340532 2.185572 4.185902 5.527076
[9] 5.374123
Per ottenere la media osservata dei punteggi di x1, x2, x3, calcoliamo la media aritmetica delle loro intercette:
mean_observed_scores <- mean(intercepts[1:3])
print(mean_observed_scores)
[1] 4.424742
Questo valore rappresenta la media osservata calcolata come la media aritmetica delle intercette di x1, x2, x3. Nel contesto del nostro modello CFA, dove la media dei costrutti latenti è fissata a zero, la media predetta degli indicatori corrisponde alla media osservata:
mean((HolzingerSwineford1939$x1 + HolzingerSwineford1939$x2 + HolzingerSwineford1939$x3) / 3)
mean_predicted_scores <- mean_observed_scores
print(mean_predicted_scores)
[1] 4.424742
40.2.3. Medie di Costrutti Latenti Non Zero#
In situazioni in cui le medie dei costrutti latenti non sono fissate a zero, la media predetta degli indicatori è influenzata sia dalle intercette sia dai carichi fattoriali. Per esempio, se la media del costrutto latente fosse diversa da zero, l’equazione per calcolare la media di un indicatore (come x1) includerebbe il contributo del costrutto latente:
dove:
\(\mu_{\text{latente}}\) è la media stimata del costrutto latente.
\(\lambda_{x1}\) è il carico dell’indicatore
x1.\(\tau_{x1}\) è l’intercetta stimata dell’indicatore
x1.
Esaminiamo un esempio nel quale le medie dei fattori latenti non sono fissate a zero. Per ottenere questo risultato è necessario identificare il modello introducendo due vincoli:
l’intercetta degli indicatori è fissata a zero;
una delle intercette delle variabili latenti è fissata a zero.
hs_model <- "
visual =~ NA*x1 + x2 + x3
textual =~ NA*x4 + x5 + x6
speed =~ NA*x7 + x8 + x9
visual ~~ 1*visual
textual ~~ 1*textual
speed ~~ 1*speed
x1 ~ 0*1 # Setting the intercepts of the manifest
x4 ~ 0*1 # variables to zero
x7 ~ 0*1
visual ~ 0*1 # Setting the mean of visual to zero
textual ~ 1 # freely estimating the mean of textual
speed ~ 1 # freely estimating the mean of speed
"
# Fit del modello con la struttura delle medie
fit <- cfa(hs_model, data = HolzingerSwineford1939, meanstructure = TRUE)
params <- parameterEstimates(fit)
print(params)
lhs op rhs est se z pvalue ci.lower ci.upper
1 visual =~ x1 4.983 0.212 23.538 0.000 4.568 5.398
2 visual =~ x2 1.702 0.093 18.248 0.000 1.519 1.885
3 visual =~ x3 2.243 0.106 21.099 0.000 2.035 2.451
4 textual =~ x4 1.783 0.081 21.945 0.000 1.624 1.942
5 textual =~ x5 1.985 0.090 22.007 0.000 1.808 2.162
6 textual =~ x6 1.652 0.076 21.702 0.000 1.502 1.801
7 speed =~ x7 1.136 0.072 15.882 0.000 0.996 1.277
8 speed =~ x8 1.341 0.070 19.127 0.000 1.204 1.478
9 speed =~ x9 1.229 0.068 17.979 0.000 1.095 1.363
10 visual ~~ visual 1.000 0.000 NA NA 1.000 1.000
11 textual ~~ textual 1.000 0.000 NA NA 1.000 1.000
12 speed ~~ speed 1.000 0.000 NA NA 1.000 1.000
13 x1 ~1 0.000 0.000 NA NA 0.000 0.000
14 x4 ~1 0.000 0.000 NA NA 0.000 0.000
15 x7 ~1 0.000 0.000 NA NA 0.000 0.000
16 visual ~1 0.000 0.000 NA NA 0.000 0.000
17 textual ~1 0.885 0.054 16.405 0.000 0.779 0.990
18 speed ~1 2.845 0.187 15.207 0.000 2.478 3.211
19 x1 ~~ x1 0.890 0.257 3.457 0.001 0.385 1.394
20 x2 ~~ x2 1.134 0.100 11.368 0.000 0.938 1.329
21 x3 ~~ x3 0.844 0.087 9.719 0.000 0.674 1.015
22 x4 ~~ x4 0.371 0.045 8.239 0.000 0.283 0.459
23 x5 ~~ x5 0.446 0.055 8.116 0.000 0.338 0.554
24 x6 ~~ x6 0.356 0.041 8.679 0.000 0.276 0.437
25 x7 ~~ x7 0.799 0.077 10.411 0.000 0.649 0.950
26 x8 ~~ x8 0.488 0.062 7.915 0.000 0.367 0.608
27 x9 ~~ x9 0.566 0.062 9.132 0.000 0.445 0.688
28 visual ~~ textual 0.870 0.016 53.410 0.000 0.838 0.902
29 visual ~~ speed 0.877 0.019 47.025 0.000 0.840 0.913
30 textual ~~ speed 0.783 0.027 28.490 0.000 0.729 0.837
31 x2 ~1 4.460 0.064 69.660 0.000 4.335 4.586
32 x3 ~1 0.106 0.058 1.814 0.070 -0.008 0.220
33 x5 ~1 0.934 0.075 12.485 0.000 0.787 1.080
34 x6 ~1 -0.649 0.064 -10.085 0.000 -0.775 -0.523
35 x8 ~1 0.588 0.236 2.496 0.013 0.126 1.050
36 x9 ~1 0.847 0.226 3.742 0.000 0.403 1.291
In sintesi, la media predetta degli indicatori in un modello SEM può variare a seconda della configurazione delle medie dei costrutti latenti e del contributo dei carichi fattoriali.
40.3. Session Info#
sessionInfo()
R version 4.3.3 (2024-02-29)
Platform: x86_64-apple-darwin20 (64-bit)
Running under: macOS Sonoma 14.3.1
Matrix products: default
BLAS: /Library/Frameworks/R.framework/Versions/4.3-x86_64/Resources/lib/libRblas.0.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/4.3-x86_64/Resources/lib/libRlapack.dylib; LAPACK version 3.11.0
locale:
[1] en_US.UTF-8/UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
time zone: Europe/Rome
tzcode source: internal
attached base packages:
[1] stats graphics grDevices utils datasets methods base
other attached packages:
[1] ggokabeito_0.1.0 viridis_0.6.5 viridisLite_0.4.2 ggpubr_0.6.0
[5] ggExtra_0.10.1 bayesplot_1.11.1 gridExtra_2.3 patchwork_1.2.0
[9] semTools_0.5-6.920 semPlot_1.1.6 lavaan_0.6-17 psych_2.4.1
[13] scales_1.3.0 markdown_1.12 knitr_1.45 lubridate_1.9.3
[17] forcats_1.0.0 stringr_1.5.1 dplyr_1.1.4 purrr_1.0.2
[21] readr_2.1.5 tidyr_1.3.1 tibble_3.2.1 ggplot2_3.5.0
[25] tidyverse_2.0.0 here_1.0.1
loaded via a namespace (and not attached):
[1] rstudioapi_0.15.0 jsonlite_1.8.8 magrittr_2.0.3
[4] TH.data_1.1-2 estimability_1.5 nloptr_2.0.3
[7] rmarkdown_2.26 vctrs_0.6.5 minqa_1.2.6
[10] base64enc_0.1-3 rstatix_0.7.2 htmltools_0.5.7
[13] broom_1.0.5 Formula_1.2-5 htmlwidgets_1.6.4
[16] plyr_1.8.9 sandwich_3.1-0 emmeans_1.10.0
[19] zoo_1.8-12 uuid_1.2-0 igraph_2.0.2
[22] mime_0.12 lifecycle_1.0.4 pkgconfig_2.0.3
[25] Matrix_1.6-5 R6_2.5.1 fastmap_1.1.1
[28] shiny_1.8.0 digest_0.6.34 OpenMx_2.21.11
[31] fdrtool_1.2.17 colorspace_2.1-0 rprojroot_2.0.4
[34] Hmisc_5.1-1 fansi_1.0.6 timechange_0.3.0
[37] abind_1.4-5 compiler_4.3.3 withr_3.0.0
[40] glasso_1.11 htmlTable_2.4.2 backports_1.4.1
[43] carData_3.0-5 ggsignif_0.6.4 MASS_7.3-60.0.1
[46] corpcor_1.6.10 gtools_3.9.5 tools_4.3.3
[49] pbivnorm_0.6.0 foreign_0.8-86 zip_2.3.1
[52] httpuv_1.6.14 nnet_7.3-19 glue_1.7.0
[55] quadprog_1.5-8 nlme_3.1-164 promises_1.2.1
[58] lisrelToR_0.3 grid_4.3.3 pbdZMQ_0.3-11
[61] checkmate_2.3.1 cluster_2.1.6 reshape2_1.4.4
[64] generics_0.1.3 gtable_0.3.4 tzdb_0.4.0
[67] data.table_1.15.2 hms_1.1.3 car_3.1-2
[70] utf8_1.2.4 sem_3.1-15 pillar_1.9.0
[73] IRdisplay_1.1 rockchalk_1.8.157 later_1.3.2
[76] splines_4.3.3 lattice_0.22-5 survival_3.5-8
[79] kutils_1.73 tidyselect_1.2.0 miniUI_0.1.1.1
[82] pbapply_1.7-2 stats4_4.3.3 xfun_0.42
[85] qgraph_1.9.8 arm_1.13-1 stringi_1.8.3
[88] boot_1.3-29 evaluate_0.23 codetools_0.2-19
[91] mi_1.1 cli_3.6.2 RcppParallel_5.1.7
[94] IRkernel_1.3.2 rpart_4.1.23 xtable_1.8-4
[97] repr_1.1.6 munsell_0.5.0 Rcpp_1.0.12
[100] coda_0.19-4.1 png_0.1-8 XML_3.99-0.16.1
[103] parallel_4.3.3 ellipsis_0.3.2 jpeg_0.1-10
[106] lme4_1.1-35.1 mvtnorm_1.2-4 openxlsx_4.2.5.2
[109] crayon_1.5.2 rlang_1.1.3 multcomp_1.4-25
[112] mnormt_2.1.1