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:

\[ y = \tau + \lambda \cdot \text{fattore latente} + \varepsilon, \]

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:

\[ \text{media(variabile latente)} = \Lambda \mu_{\text{lat}} + \tau, \]

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) 
4.42474160196013
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:

\[ \text{media predetta}(x1) = \mu_{\text{latente}} \cdot \lambda_{x1} + \tau_{x1}, \]

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