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.