Zunächst installieren wir Pakete, die wir benötigen, um die folgenden Analysen durchzuführen.

if (!require('rstudioapi')) install.packages('rstudioapi')
if (!require('lavaan')) install.packages('lavaan')
if (!require('semPlot')) install.packages('semPlot')

Jetzt laden wir die installierten Pakete. Das Paket “rstudioapi” enthält die Funktion getActiveDocumentContext(), die es uns später erleichtert, das Working Directory zu setzen. Das Paket “lavaan” benötigen wir, da es eine Funktion namens sem() enthält, mit der wir Strukturgleichungsmodelle berechnen können. Das Paket “semPlot” enthält eine Funktion namens semPaths(), mit der wir die Pfade von Strukturgleichungsmodellen plotten können.

library(rstudioapi)
library(lavaan)
library(semPlot)

Nun schalten wir die wissenschaftliche Notation ab, um möglichst viele Nachkommastellen im Output zu erhalten (das kann vor allem für p-Werte wichtig sein, die sonst schwer zu interpretieren sind).

options(scipen=999)

Hier setzen wir das Working Directory auf den Pfad, in dem sich auch dieses Notebook befindet. Dadurch findet R alle nötigen Dateien, so lange sich diese im selben Ordner wie dieses Notebook auf Ihrem Rechner befinden.

setwd(dirname(getActiveDocumentContext()$path))

Wir wollen die folgende Hypothese mittels eines Strukturgleichungsmodells überprüfen: Depression beeinflusst die Stärke des Immunsystems; diese Variable wiederum beeinflusst die Belastung durch Krankheiten.Wir laden uns zunächst den Datensatz “Depression.RData” ein und lassen ihn uns ausgeben, um zu sehen, welche Variablen vorliegen.

load('depression.RData')
depression

Wir können sehen, dass wir jeweils drei Messungen der latenten Variablen Depression (dep1-3), Immunsystem (imm1-3) und Krankheitsbelastung (kra1-3) vorliegen haben. Im ersten Schritt spezifizieren wir entsprechend unserer Hypothese ein Model, welches wir dann im zweiten Schritt mit dem Paket “lavaan” testen können. Zur Spezifikation des Modells nutzt “lavaan” eine Notation, die sehr ungewöhnlich im Vergleich mit anderen Paketen ist. Zunächst einmal wird das gesamte Modell in einem einzigen String spezifiziert. Des Weiteren nutzt “lavaan” Zeilenumbrüche, um einzelne Variablen voneinander abzutrennen. Untenstehend spezifizieren wir einen String namens “depmodel”. Die ersten drei Zeilen beschreiben, welche beobachteten Variablen gemeinsam welche latenten Variablen messen. Zum Beispiel beschreibt die erste Zeile, dass die latente Variable “Depression” (wir könnten ihr einen beliebigen Namen geben) durch die drei Variablen dep1-3 gemessen wird. Wie Sie sehen können, wird die latente Variable durch das kombinierte Symbol “=~” von den beobachteten Variablen getrennt wird. Die beobachteten Variablen werden wiederum durch “+” Zeichen voneinander abgetrennt. In den letzten beiden Zeilen beschreiben wir die vermuteten Zusammenhänge der latenten Variablen untereinander. Die vierte Zeile beschreibt, dass Depression das Immunsystem beeinflusst. Die fünfte Zeile beschreibt, dass das Immunsystem wiederum die Krankheitsbelastung beeinflusst. Eine einfache Tilde (~) beschreibt im Paket “lavaan” also gerichtete Zusammenhänge zwischen zwei Variablen. Ähnlich zur linearen Regression wird die beinflussende Variable dabei hinter die Tilde gesetzt und die beeinflusste Variable vor die Tilde. Im Buchkapitel haben Sie gelernt, dass nicht gerichtete korrelative Zusammenhänge durch gekrümmte Doppelpfeile darsgestellt werden. Diese Art von Zusammenhang kommt in unserem Beispielmodell nicht vor. Im Paket “lavaan” werden solche Zusammenhänge mit zwei aufeinanderfolgenden Tilden (~~) dargestellt.

depmodel <- 'Depression =~  dep1 + dep2 + dep3
            Immun =~ imm1 + imm2 + imm3
            Krankheit =~ kra1 + kra2 +kra3
            Immun ~ Depression
            Krankheit ~ Immun'

Wir nutzen nun die Funktion sem() aus dem Paket “lavaan”, um das eben spezifizierte Modell fitten zu lassen. Zu diesem Zweck übergeben wir der Funktion vier Argumente:

Die Ergebnisse der Berechung des Strukturgleichungsmodells packen wir in ein Objekt namens “depmodel.fit”.

depmodel.fit <- sem(model = depmodel, data = depression, se = 'bootstrap', mimic = 'Mplus')

Mittels der Funktion summary() lassen wir uns nun die Ergebnisse ausgeben. Dabei übergeben wir der Funktion summary aber noch drei Argumente:

summary(depmodel.fit, standardized=TRUE, rsquare=TRUE, fit.measures=TRUE)
## lavaan 0.6-10 ended normally after 38 iterations
## 
##   Estimator                                         ML
##   Optimization method                           NLMINB
##   Number of model parameters                        29
##                                                       
##   Number of observations                           400
##   Number of missing patterns                         1
##                                                       
## Model Test User Model:
##                                                       
##   Test statistic                                21.891
##   Degrees of freedom                                25
##   P-value (Chi-square)                           0.642
## 
## Model Test Baseline Model:
## 
##   Test statistic                              3094.445
##   Degrees of freedom                                36
##   P-value                                        0.000
## 
## User Model versus Baseline Model:
## 
##   Comparative Fit Index (CFI)                    1.000
##   Tucker-Lewis Index (TLI)                       1.001
## 
## Loglikelihood and Information Criteria:
## 
##   Loglikelihood user model (H0)              -6643.575
##   Loglikelihood unrestricted model (H1)      -6632.629
##                                                       
##   Akaike (AIC)                               13345.150
##   Bayesian (BIC)                             13460.902
##   Sample-size adjusted Bayesian (BIC)        13368.883
## 
## Root Mean Square Error of Approximation:
## 
##   RMSEA                                          0.000
##   90 Percent confidence interval - lower         0.000
##   90 Percent confidence interval - upper         0.034
##   P-value RMSEA <= 0.05                          0.997
## 
## Standardized Root Mean Square Residual:
## 
##   SRMR                                           0.028
## 
## Parameter Estimates:
## 
##   Standard errors                            Bootstrap
##   Number of requested bootstrap draws             1000
##   Number of successful bootstrap draws            1000
## 
## Latent Variables:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   Depression =~                                                         
##     dep1              1.000                               1.826    0.877
##     dep2              0.980    0.043   22.600    0.000    1.790    0.875
##     dep3              1.058    0.049   21.519    0.000    1.932    0.873
##   Immun =~                                                              
##     imm1              1.000                               2.225    0.909
##     imm2              0.991    0.036   27.610    0.000    2.206    0.900
##     imm3              0.988    0.035   27.927    0.000    2.197    0.915
##   Krankheit =~                                                          
##     kra1              1.000                               2.313    0.926
##     kra2              1.001    0.034   29.581    0.000    2.317    0.917
##     kra3              1.013    0.031   32.739    0.000    2.342    0.928
## 
## Regressions:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##   Immun ~                                                               
##     Depression        0.499    0.062    8.079    0.000    0.410    0.410
##   Krankheit ~                                                           
##     Immun             0.472    0.053    8.886    0.000    0.454    0.454
## 
## Intercepts:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .dep1             -0.020    0.102   -0.192    0.848   -0.020   -0.009
##    .dep2             -0.056    0.099   -0.570    0.569   -0.056   -0.028
##    .dep3              0.029    0.109    0.266    0.791    0.029    0.013
##    .imm1             -0.090    0.121   -0.743    0.457   -0.090   -0.037
##    .imm2             -0.105    0.123   -0.850    0.395   -0.105   -0.043
##    .imm3             -0.132    0.121   -1.090    0.276   -0.132   -0.055
##    .kra1              0.067    0.121    0.550    0.582    0.067    0.027
##    .kra2             -0.005    0.123   -0.041    0.968   -0.005   -0.002
##    .kra3             -0.026    0.124   -0.207    0.836   -0.026   -0.010
##     Depression        0.000                               0.000    0.000
##    .Immun             0.000                               0.000    0.000
##    .Krankheit         0.000                               0.000    0.000
## 
## Variances:
##                    Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
##    .dep1              0.997    0.104    9.617    0.000    0.997    0.230
##    .dep2              0.979    0.107    9.120    0.000    0.979    0.234
##    .dep3              1.170    0.114   10.264    0.000    1.170    0.239
##    .imm1              1.035    0.105    9.848    0.000    1.035    0.173
##    .imm2              1.137    0.119    9.556    0.000    1.137    0.189
##    .imm3              0.943    0.104    9.034    0.000    0.943    0.163
##    .kra1              0.887    0.098    9.085    0.000    0.887    0.142
##    .kra2              1.020    0.112    9.111    0.000    1.020    0.160
##    .kra3              0.886    0.089   10.006    0.000    0.886    0.139
##     Depression        3.335    0.309   10.796    0.000    1.000    1.000
##    .Immun             4.119    0.342   12.059    0.000    0.832    0.832
##    .Krankheit         4.246    0.339   12.512    0.000    0.794    0.794
## 
## R-Square:
##                    Estimate
##     dep1              0.770
##     dep2              0.766
##     dep3              0.761
##     imm1              0.827
##     imm2              0.811
##     imm3              0.837
##     kra1              0.858
##     kra2              0.840
##     kra3              0.861
##     Immun             0.168
##     Krankheit         0.206

Da die Ausgabe - wie Sie sehen können - sehr ausführlich ist, wollen wir hier nur die wichtigsten Teile der Ausgabe genauer besprechen:

Nun nutzen wir noch die Funktion semPaths() aus dem Paket “semPlot”, um das geschätzte Modell zu plotten. Wir übergeben der Funktion die folgenden Argumente:

semPaths(object = depmodel.fit, whatLabels = 'stand', edge.label.cex = 0.8)

Kreise repräsentieren latente Variablen, Quadrate beobachtete Variablen und Dreiecke die Fehlerterme. Gekrümmte Pfeile repräsentieren standardisierte Varianzen der Variablen. Die durchgezogenen geraden Pfeile repräsentieren freie Regressionsparameter und gestrichelte Pfeile fixierte Regressionsparameter.