# Falls Du librarian noch nicht hast, die nächste Zeile auskommentieren und ausführen
# install.packages("librarian")
librarian::shelf(qgraph)
Big Five Strukturgleichungs-Modell mit echtem Datensatz in R berechnen (Paket lavaan)
Zu diesem Artikel gibt es auch ein Video auf Youtube:
Heute machen wir mal etwas richtig cooles. Wir fitten das Big Five Fünf-Faktoren-Modell an einem echten Datensatz in R. Das ist gar nicht so schwer wie man meint und man lernt einiges im Prozess. Unter anderem, dass das Gesamt-Modell überhaupt nicht berechenbar ist. Aber eins nach dem anderen.
Woher bekommen wir einen echten Big Five Datensatz? Big Five ist nicht gleich Big Five. Der bedeutsamste Big Five Fragebogen ist der NEO-PI-R. Die Hauptpublikation von Costa und Mccrae zum NEO-PI-R hat mehr als 20000 Zitationen1. Wir hätten also natürlich gerne einen Datensatz zum NEO-PI-R.
Im Paket qgraph
gibt es aus einer Studie von Dolan et al. (2009)2 den Datensatz big5
. Das ist zwar nur die niederländische Version des NEO-PI-R, aber immerhin!
Wir installieren und laden erst mal das Paket:
Nun laden wir die Daten und werfen einen Blick darauf:
data(big5)
big5[1:10, 1:10]
N1 E2 O3 A4 C5 N6 E7 O8 A9 C10
[1,] 2 4 4 2 4 3 3 4 5 3
[2,] 3 4 5 3 4 2 5 4 3 3
[3,] 4 1 3 2 5 4 3 1 1 3
[4,] 4 4 3 2 4 4 2 4 2 1
[5,] 5 4 4 2 4 2 2 4 2 2
[6,] 2 4 5 3 4 2 5 2 4 2
[7,] 2 4 5 3 4 2 5 5 2 1
[8,] 1 4 2 3 3 2 4 3 3 2
[9,] 4 3 4 3 4 2 4 4 5 1
[10,] 2 2 4 4 3 2 4 5 3 2
In den Zeilen sind die Personen, in den Spalten die Items. Es gibt insgesamt 240 Items, denn das NEO-PI-R-Modell hat pro Faktor 6 Facetten und jede Facette besteht aus 8 Items. Um das vollständige Modell zu fitten, müssen wir natürlich wissen welches Item zu welcher Facette gehört.
Zuordnung von Items zu Facetten
Die Struktur des NEO-PI-R sieht folgendermaßen aus:
- N1 -> Faktor N, Facette 1, Item 1
- E2 -> Faktor E, Facette 1, Item 1
- O3 -> Faktor O, Facette 1, Item 1,
- …
- N6 -> Faktor N, Facette 2, Item 1,
- …
- N31 -> Faktor N, Facette 1, Item 2
Der Abstand zwischen Items einer einzigen Facette beträgt also 30. Denn, die Anzahl der Faktoren multipliziert mit der Anzahl der Facetten ist: \(5\cdot 6=30\).
Wenn wir also unser Modell fitten müssen N1, N31, N61, N91, N121, N151, N181, N211 zur Facette N1 zugeordnet werden. Und E2, E32, …, E212 zur Facette E2, und so weiter.
Am einfachsten ist es zunächst eine Tabelle mit Items, Facetten und Faktoren zu erstellen, aus der wir uns dann ziemlich flott die lavaan-Syntax extrahieren können.
item <- 1:240
facet <- rep(1:6, each = 5) # Jede Facette kommt 5 vor
factor <- c("N", "E", "O", "A", "C")
item_table <- data.frame(item, facet, factor)
item_table$facet <- paste0("facet", item_table$factor, item_table$facet)
item_table$item <- paste0(item_table$factor, item_table$item)
head(item_table, 30)
item facet factor
1 N1 facetN1 N
2 E2 facetE1 E
3 O3 facetO1 O
4 A4 facetA1 A
5 C5 facetC1 C
6 N6 facetN2 N
7 E7 facetE2 E
8 O8 facetO2 O
9 A9 facetA2 A
10 C10 facetC2 C
11 N11 facetN3 N
12 E12 facetE3 E
13 O13 facetO3 O
14 A14 facetA3 A
15 C15 facetC3 C
16 N16 facetN4 N
17 E17 facetE4 E
18 O18 facetO4 O
19 A19 facetA4 A
20 C20 facetC4 C
21 N21 facetN5 N
22 E22 facetE5 E
23 O23 facetO5 O
24 A24 facetA5 A
25 C25 facetC5 C
26 N26 facetN6 N
27 E27 facetE6 E
28 O28 facetO6 O
29 A29 facetA6 A
30 C30 facetC6 C
Nun müssen wir daraus nur noch die lavaan-Syntax erstellen.
lavaan Syntax
Die Syntax für lavaan sieht so aus:
- AV ~ UV1 + UV2…
- Latente Variable =~ manifesteVariable1 + manifesteVariable2 + …
Der erste Fall ist also eine einfache Regression, im zweiten Fall definieren wir latente Variablen.
Machen wir zunächst die Facetten-Syntax. Dafür benutzen wir aggregate und aggregieren über Faktoren und Facetten auf die Items. Die angewandte Funktion paste
t uns den nötigen String:
syntax_table <- aggregate(item ~ factor + facet, data = item_table, paste,
collapse = " + ")
syntax_table
factor facet item
1 A facetA1 A4 + A34 + A64 + A94 + A124 + A154 + A184 + A214
2 A facetA2 A9 + A39 + A69 + A99 + A129 + A159 + A189 + A219
3 A facetA3 A14 + A44 + A74 + A104 + A134 + A164 + A194 + A224
4 A facetA4 A19 + A49 + A79 + A109 + A139 + A169 + A199 + A229
5 A facetA5 A24 + A54 + A84 + A114 + A144 + A174 + A204 + A234
6 A facetA6 A29 + A59 + A89 + A119 + A149 + A179 + A209 + A239
7 C facetC1 C5 + C35 + C65 + C95 + C125 + C155 + C185 + C215
8 C facetC2 C10 + C40 + C70 + C100 + C130 + C160 + C190 + C220
9 C facetC3 C15 + C45 + C75 + C105 + C135 + C165 + C195 + C225
10 C facetC4 C20 + C50 + C80 + C110 + C140 + C170 + C200 + C230
11 C facetC5 C25 + C55 + C85 + C115 + C145 + C175 + C205 + C235
12 C facetC6 C30 + C60 + C90 + C120 + C150 + C180 + C210 + C240
13 E facetE1 E2 + E32 + E62 + E92 + E122 + E152 + E182 + E212
14 E facetE2 E7 + E37 + E67 + E97 + E127 + E157 + E187 + E217
15 E facetE3 E12 + E42 + E72 + E102 + E132 + E162 + E192 + E222
16 E facetE4 E17 + E47 + E77 + E107 + E137 + E167 + E197 + E227
17 E facetE5 E22 + E52 + E82 + E112 + E142 + E172 + E202 + E232
18 E facetE6 E27 + E57 + E87 + E117 + E147 + E177 + E207 + E237
19 N facetN1 N1 + N31 + N61 + N91 + N121 + N151 + N181 + N211
20 N facetN2 N6 + N36 + N66 + N96 + N126 + N156 + N186 + N216
21 N facetN3 N11 + N41 + N71 + N101 + N131 + N161 + N191 + N221
22 N facetN4 N16 + N46 + N76 + N106 + N136 + N166 + N196 + N226
23 N facetN5 N21 + N51 + N81 + N111 + N141 + N171 + N201 + N231
24 N facetN6 N26 + N56 + N86 + N116 + N146 + N176 + N206 + N236
25 O facetO1 O3 + O33 + O63 + O93 + O123 + O153 + O183 + O213
26 O facetO2 O8 + O38 + O68 + O98 + O128 + O158 + O188 + O218
27 O facetO3 O13 + O43 + O73 + O103 + O133 + O163 + O193 + O223
28 O facetO4 O18 + O48 + O78 + O108 + O138 + O168 + O198 + O228
29 O facetO5 O23 + O53 + O83 + O113 + O143 + O173 + O203 + O233
30 O facetO6 O28 + O58 + O88 + O118 + O148 + O178 + O208 + O238
Jetzt fügen wir linke und rechte Seite zusammen:
facet_syntax <- paste0(syntax_table$facet, " =~ ", syntax_table$item)
facet_syntax
[1] "facetA1 =~ A4 + A34 + A64 + A94 + A124 + A154 + A184 + A214"
[2] "facetA2 =~ A9 + A39 + A69 + A99 + A129 + A159 + A189 + A219"
[3] "facetA3 =~ A14 + A44 + A74 + A104 + A134 + A164 + A194 + A224"
[4] "facetA4 =~ A19 + A49 + A79 + A109 + A139 + A169 + A199 + A229"
[5] "facetA5 =~ A24 + A54 + A84 + A114 + A144 + A174 + A204 + A234"
[6] "facetA6 =~ A29 + A59 + A89 + A119 + A149 + A179 + A209 + A239"
[7] "facetC1 =~ C5 + C35 + C65 + C95 + C125 + C155 + C185 + C215"
[8] "facetC2 =~ C10 + C40 + C70 + C100 + C130 + C160 + C190 + C220"
[9] "facetC3 =~ C15 + C45 + C75 + C105 + C135 + C165 + C195 + C225"
[10] "facetC4 =~ C20 + C50 + C80 + C110 + C140 + C170 + C200 + C230"
[11] "facetC5 =~ C25 + C55 + C85 + C115 + C145 + C175 + C205 + C235"
[12] "facetC6 =~ C30 + C60 + C90 + C120 + C150 + C180 + C210 + C240"
[13] "facetE1 =~ E2 + E32 + E62 + E92 + E122 + E152 + E182 + E212"
[14] "facetE2 =~ E7 + E37 + E67 + E97 + E127 + E157 + E187 + E217"
[15] "facetE3 =~ E12 + E42 + E72 + E102 + E132 + E162 + E192 + E222"
[16] "facetE4 =~ E17 + E47 + E77 + E107 + E137 + E167 + E197 + E227"
[17] "facetE5 =~ E22 + E52 + E82 + E112 + E142 + E172 + E202 + E232"
[18] "facetE6 =~ E27 + E57 + E87 + E117 + E147 + E177 + E207 + E237"
[19] "facetN1 =~ N1 + N31 + N61 + N91 + N121 + N151 + N181 + N211"
[20] "facetN2 =~ N6 + N36 + N66 + N96 + N126 + N156 + N186 + N216"
[21] "facetN3 =~ N11 + N41 + N71 + N101 + N131 + N161 + N191 + N221"
[22] "facetN4 =~ N16 + N46 + N76 + N106 + N136 + N166 + N196 + N226"
[23] "facetN5 =~ N21 + N51 + N81 + N111 + N141 + N171 + N201 + N231"
[24] "facetN6 =~ N26 + N56 + N86 + N116 + N146 + N176 + N206 + N236"
[25] "facetO1 =~ O3 + O33 + O63 + O93 + O123 + O153 + O183 + O213"
[26] "facetO2 =~ O8 + O38 + O68 + O98 + O128 + O158 + O188 + O218"
[27] "facetO3 =~ O13 + O43 + O73 + O103 + O133 + O163 + O193 + O223"
[28] "facetO4 =~ O18 + O48 + O78 + O108 + O138 + O168 + O198 + O228"
[29] "facetO5 =~ O23 + O53 + O83 + O113 + O143 + O173 + O203 + O233"
[30] "facetO6 =~ O28 + O58 + O88 + O118 + O148 + O178 + O208 + O238"
Das gleiche nochmal aber für die Facetten-Faktoren-Beziehung:
syntax_table2 <- aggregate(facet ~ factor, data = syntax_table, paste,
collapse = " + ")
syntax_table2
factor facet
1 A facetA1 + facetA2 + facetA3 + facetA4 + facetA5 + facetA6
2 C facetC1 + facetC2 + facetC3 + facetC4 + facetC5 + facetC6
3 E facetE1 + facetE2 + facetE3 + facetE4 + facetE5 + facetE6
4 N facetN1 + facetN2 + facetN3 + facetN4 + facetN5 + facetN6
5 O facetO1 + facetO2 + facetO3 + facetO4 + facetO5 + facetO6
factor_syntax <- paste0(syntax_table2$factor, " =~ ", syntax_table2$facet)
factor_syntax
[1] "A =~ facetA1 + facetA2 + facetA3 + facetA4 + facetA5 + facetA6"
[2] "C =~ facetC1 + facetC2 + facetC3 + facetC4 + facetC5 + facetC6"
[3] "E =~ facetE1 + facetE2 + facetE3 + facetE4 + facetE5 + facetE6"
[4] "N =~ facetN1 + facetN2 + facetN3 + facetN4 + facetN5 + facetN6"
[5] "O =~ facetO1 + facetO2 + facetO3 + facetO4 + facetO5 + facetO6"
Modell rechnen
Zunächst müssen wir das lavaan
-Paket installieren und laden:3
librarian::shelf(lavaan)
Das folgende ist zwar der richtige Code, wird aber nicht klappen, denn das Modell ist viel zu groß um es in den Speicher zu laden:
fit <- sem(model = c(facet_syntax, factor_syntax), data = big5)
Üblicherweise wird einfach jeder Faktor einzeln gefittet4, was wir hier auch machen. Zunächst probieren wir es mit dem Faktor Agreeableness:
fitA <- sem(model = c(facet_syntax[1:6], factor_syntax[1]), data = big5)
summary(fitA, standardized = TRUE)
lavaan 0.6.14 ended normally after 86 iterations
Estimator ML
Optimization method NLMINB
Number of model parameters 102
Number of observations 500
Model Test User Model:
Test statistic 2684.788
Degrees of freedom 1074
P-value (Chi-square) 0.000
Parameter Estimates:
Standard errors Standard
Information Expected
Information saturated (h1) model Structured
Latent Variables:
Estimate Std.Err z-value P(>|z|) Std.lv Std.all
facetA1 =~
A4 1.000 0.524 0.556
A34 1.020 0.106 9.584 0.000 0.535 0.586
A64 0.914 0.106 8.637 0.000 0.479 0.503
A94 0.573 0.073 7.834 0.000 0.300 0.442
A124 0.656 0.076 8.630 0.000 0.344 0.503
A154 0.915 0.095 9.641 0.000 0.479 0.591
A184 1.012 0.096 10.553 0.000 0.530 0.688
A214 0.866 0.093 9.343 0.000 0.454 0.563
facetA2 =~
A9 1.000 0.536 0.516
A39 1.619 0.149 10.849 0.000 0.868 0.768
A69 0.846 0.116 7.302 0.000 0.453 0.405
A99 0.756 0.111 6.814 0.000 0.405 0.371
A129 0.380 0.083 4.582 0.000 0.204 0.233
A159 1.497 0.138 10.883 0.000 0.802 0.774
A189 1.390 0.133 10.474 0.000 0.745 0.711
A219 1.022 0.113 9.032 0.000 0.548 0.548
facetA3 =~
A14 1.000 0.515 0.515
A44 0.507 0.088 5.770 0.000 0.261 0.319
A74 0.827 0.113 7.293 0.000 0.426 0.432
A104 0.644 0.073 8.822 0.000 0.332 0.578
A134 0.727 0.099 7.368 0.000 0.375 0.438
A164 0.331 0.058 5.721 0.000 0.171 0.316
A194 0.962 0.102 9.399 0.000 0.495 0.650
A224 1.106 0.116 9.558 0.000 0.570 0.674
facetA4 =~
A19 1.000 0.356 0.411
A49 0.762 0.157 4.846 0.000 0.272 0.311
A79 1.551 0.250 6.211 0.000 0.552 0.473
A109 1.432 0.218 6.574 0.000 0.510 0.539
A139 0.909 0.180 5.059 0.000 0.324 0.331
A169 1.446 0.223 6.494 0.000 0.515 0.523
A199 1.006 0.178 5.640 0.000 0.358 0.395
A229 1.031 0.187 5.504 0.000 0.367 0.379
facetA5 =~
A24 1.000 0.507 0.513
A54 0.712 0.108 6.575 0.000 0.361 0.365
A84 1.532 0.148 10.337 0.000 0.777 0.748
A114 0.514 0.083 6.200 0.000 0.261 0.339
A144 1.123 0.119 9.438 0.000 0.570 0.619
A174 1.129 0.124 9.102 0.000 0.573 0.581
A204 0.699 0.101 6.899 0.000 0.355 0.388
A234 1.343 0.132 10.206 0.000 0.681 0.725
facetA6 =~
A29 1.000 0.231 0.259
A59 1.610 0.382 4.210 0.000 0.371 0.406
A89 1.357 0.353 3.840 0.000 0.313 0.315
A119 1.926 0.439 4.392 0.000 0.444 0.474
A149 1.401 0.335 4.187 0.000 0.323 0.399
A179 1.940 0.428 4.533 0.000 0.447 0.552
A209 1.693 0.386 4.385 0.000 0.390 0.471
A239 -0.089 0.221 -0.401 0.688 -0.020 -0.022
A =~
facetA1 1.000 0.629 0.629
facetA2 1.127 0.169 6.658 0.000 0.694 0.694
facetA3 1.137 0.172 6.599 0.000 0.728 0.728
facetA4 0.705 0.127 5.539 0.000 0.653 0.653
facetA5 0.807 0.135 5.982 0.000 0.524 0.524
facetA6 0.531 0.126 4.210 0.000 0.758 0.758
Variances:
Estimate Std.Err z-value P(>|z|) Std.lv Std.all
.A4 0.615 0.044 14.110 0.000 0.615 0.691
.A34 0.548 0.040 13.821 0.000 0.548 0.657
.A64 0.675 0.047 14.521 0.000 0.675 0.747
.A94 0.371 0.025 14.890 0.000 0.371 0.805
.A124 0.350 0.024 14.525 0.000 0.350 0.747
.A154 0.428 0.031 13.764 0.000 0.428 0.651
.A184 0.313 0.025 12.372 0.000 0.313 0.526
.A214 0.443 0.032 14.040 0.000 0.443 0.683
.A9 0.791 0.053 14.789 0.000 0.791 0.734
.A39 0.524 0.045 11.678 0.000 0.524 0.410
.A69 1.047 0.069 15.262 0.000 1.047 0.836
.A99 1.031 0.067 15.366 0.000 1.031 0.863
.A129 0.720 0.046 15.651 0.000 0.720 0.946
.A159 0.431 0.037 11.518 0.000 0.431 0.401
.A189 0.543 0.042 12.884 0.000 0.543 0.494
.A219 0.699 0.048 14.602 0.000 0.699 0.700
.A14 0.734 0.051 14.254 0.000 0.734 0.734
.A44 0.600 0.039 15.325 0.000 0.600 0.898
.A74 0.793 0.053 14.829 0.000 0.793 0.814
.A104 0.220 0.016 13.645 0.000 0.220 0.666
.A134 0.592 0.040 14.794 0.000 0.592 0.808
.A164 0.262 0.017 15.336 0.000 0.262 0.900
.A194 0.335 0.027 12.628 0.000 0.335 0.577
.A224 0.390 0.032 12.199 0.000 0.390 0.546
.A19 0.623 0.043 14.407 0.000 0.623 0.831
.A49 0.688 0.046 15.075 0.000 0.688 0.903
.A79 1.056 0.076 13.811 0.000 1.056 0.776
.A109 0.634 0.049 12.963 0.000 0.634 0.709
.A139 0.849 0.057 14.962 0.000 0.849 0.890
.A169 0.703 0.053 13.196 0.000 0.703 0.726
.A199 0.696 0.048 14.539 0.000 0.696 0.844
.A229 0.805 0.055 14.658 0.000 0.805 0.857
.A24 0.720 0.049 14.564 0.000 0.720 0.737
.A54 0.850 0.056 15.279 0.000 0.850 0.867
.A84 0.476 0.042 11.309 0.000 0.476 0.441
.A114 0.523 0.034 15.361 0.000 0.523 0.885
.A144 0.522 0.038 13.621 0.000 0.522 0.617
.A174 0.643 0.046 14.022 0.000 0.643 0.662
.A204 0.710 0.047 15.196 0.000 0.710 0.850
.A234 0.419 0.035 11.875 0.000 0.419 0.475
.A29 0.741 0.048 15.310 0.000 0.741 0.933
.A59 0.699 0.048 14.425 0.000 0.699 0.835
.A89 0.887 0.059 15.039 0.000 0.887 0.900
.A119 0.680 0.049 13.758 0.000 0.680 0.775
.A149 0.552 0.038 14.481 0.000 0.552 0.841
.A179 0.456 0.036 12.678 0.000 0.456 0.695
.A209 0.534 0.039 13.791 0.000 0.534 0.778
.A239 0.899 0.057 15.808 0.000 0.899 1.000
.facetA1 0.166 0.030 5.570 0.000 0.604 0.604
.facetA2 0.149 0.029 5.172 0.000 0.519 0.519
.facetA3 0.125 0.027 4.698 0.000 0.471 0.471
.facetA4 0.073 0.020 3.685 0.000 0.574 0.574
.facetA5 0.187 0.035 5.389 0.000 0.725 0.725
.facetA6 0.023 0.010 2.271 0.023 0.425 0.425
A 0.109 0.024 4.479 0.000 1.000 1.000
Die summary
ist recht ausführlich und man kann sie nicht direkt weiterverarbeiten. Aber über parameterEstimates
und standardizedSolution
bekommen wir einen schönen dataframe:
standardizedSolution(fitA)[1:(48+6), ] # 6 Facetten * 8 Items + 6 Facetten
lhs op rhs est.std se z pvalue ci.lower ci.upper
1 facetA1 =~ A4 0.556 0.037 15.117 0.000 0.484 0.628
2 facetA1 =~ A34 0.586 0.035 16.549 0.000 0.516 0.655
3 facetA1 =~ A64 0.503 0.039 12.902 0.000 0.427 0.580
4 facetA1 =~ A94 0.442 0.041 10.668 0.000 0.361 0.523
5 facetA1 =~ A124 0.503 0.039 12.878 0.000 0.426 0.579
6 facetA1 =~ A154 0.591 0.035 16.823 0.000 0.522 0.660
7 facetA1 =~ A184 0.688 0.030 22.626 0.000 0.629 0.748
8 facetA1 =~ A214 0.563 0.036 15.475 0.000 0.492 0.635
9 facetA2 =~ A9 0.516 0.037 13.966 0.000 0.444 0.589
10 facetA2 =~ A39 0.768 0.024 32.027 0.000 0.721 0.815
11 facetA2 =~ A69 0.405 0.041 9.790 0.000 0.324 0.486
12 facetA2 =~ A99 0.371 0.043 8.716 0.000 0.287 0.454
13 facetA2 =~ A129 0.233 0.046 5.058 0.000 0.143 0.324
14 facetA2 =~ A159 0.774 0.024 32.715 0.000 0.727 0.820
15 facetA2 =~ A189 0.711 0.027 26.257 0.000 0.658 0.764
16 facetA2 =~ A219 0.548 0.036 15.428 0.000 0.478 0.617
17 facetA3 =~ A14 0.515 0.039 13.103 0.000 0.438 0.592
18 facetA3 =~ A44 0.319 0.046 6.935 0.000 0.229 0.410
19 facetA3 =~ A74 0.432 0.043 10.146 0.000 0.348 0.515
20 facetA3 =~ A104 0.578 0.037 15.764 0.000 0.506 0.650
21 facetA3 =~ A134 0.438 0.042 10.344 0.000 0.355 0.521
22 facetA3 =~ A164 0.316 0.046 6.851 0.000 0.226 0.407
23 facetA3 =~ A194 0.650 0.033 19.496 0.000 0.585 0.716
24 facetA3 =~ A224 0.674 0.032 20.870 0.000 0.611 0.737
25 facetA4 =~ A19 0.411 0.047 8.734 0.000 0.319 0.503
26 facetA4 =~ A49 0.311 0.050 6.251 0.000 0.214 0.409
27 facetA4 =~ A79 0.473 0.045 10.485 0.000 0.385 0.562
28 facetA4 =~ A109 0.539 0.043 12.539 0.000 0.455 0.624
29 facetA4 =~ A139 0.331 0.049 6.727 0.000 0.235 0.428
30 facetA4 =~ A169 0.523 0.044 12.015 0.000 0.438 0.608
31 facetA4 =~ A199 0.395 0.048 8.298 0.000 0.301 0.488
32 facetA4 =~ A229 0.379 0.048 7.885 0.000 0.284 0.473
33 facetA5 =~ A24 0.513 0.038 13.455 0.000 0.438 0.588
34 facetA5 =~ A54 0.365 0.044 8.360 0.000 0.279 0.450
35 facetA5 =~ A84 0.748 0.027 27.842 0.000 0.695 0.800
36 facetA5 =~ A114 0.339 0.044 7.634 0.000 0.252 0.426
37 facetA5 =~ A144 0.619 0.033 18.632 0.000 0.554 0.684
38 facetA5 =~ A174 0.581 0.035 16.573 0.000 0.512 0.650
39 facetA5 =~ A204 0.388 0.043 9.045 0.000 0.304 0.472
40 facetA5 =~ A234 0.725 0.028 25.909 0.000 0.670 0.780
41 facetA6 =~ A29 0.259 0.051 5.072 0.000 0.159 0.359
42 facetA6 =~ A59 0.406 0.047 8.558 0.000 0.313 0.499
43 facetA6 =~ A89 0.315 0.050 6.333 0.000 0.218 0.413
44 facetA6 =~ A119 0.474 0.045 10.456 0.000 0.385 0.563
45 facetA6 =~ A149 0.399 0.048 8.378 0.000 0.306 0.492
46 facetA6 =~ A179 0.552 0.043 12.860 0.000 0.468 0.637
47 facetA6 =~ A209 0.471 0.045 10.370 0.000 0.382 0.560
48 facetA6 =~ A239 -0.022 0.054 -0.403 0.687 -0.127 0.084
49 A =~ facetA1 0.629 0.043 14.669 0.000 0.545 0.713
50 A =~ facetA2 0.694 0.039 17.998 0.000 0.618 0.769
51 A =~ facetA3 0.728 0.040 18.128 0.000 0.649 0.806
52 A =~ facetA4 0.653 0.048 13.483 0.000 0.558 0.748
53 A =~ facetA5 0.524 0.046 11.300 0.000 0.433 0.615
54 A =~ facetA6 0.758 0.046 16.318 0.000 0.667 0.849
Eine Abbildung lässt sich leicht über lavaanPlot
erstellen, aber diese ist auch etwas unübersichtlich durch das schon recht große Modell:
embed_plot_pdf(plot0, "plot0.pdf")
Fitten wir noch die anderen Faktoren. Da wir faul sind, wollen wir das ganze natürlich automatisieren. Das können wir leicht über eine Hilfsfunktion, die die richtigen Facetten und Items raussucht. Dann müssen wir nur noch das Functional lapply
darüber jagen:
sem_helper <- function(factor) {
themodel <- c(grep(factor, facet_syntax, value = TRUE),
grep(factor, factor_syntax, value = TRUE))
sem(model = themodel, data = big5)
}
sems <- lapply(c("A", "C", "E", "N", "O"), sem_helper)
sems_std <- lapply(sems, function(x) standardizedSolution(x)[1:(48+6), ])
sems_std_df <- plyr::ldply(sems_std, "data.frame")
Schauen wir uns mal die schlechtesten Faktorladungen an:
librarian::shelf(dplyr)
sems_std_df %>%
arrange(est.std) %>%
slice(1:20)
lhs op rhs est.std se z pvalue ci.lower ci.upper
1 E =~ facetE4 -0.77210453 0.03115245 -24.7847111 0.000000e+00 -0.83316221 -0.711046846
2 facetE4 =~ E227 -0.76723932 0.02535654 -30.2580445 0.000000e+00 -0.81693722 -0.717541414
3 facetE4 =~ E107 -0.73188948 0.02709607 -27.0109052 0.000000e+00 -0.78499681 -0.678782148
4 facetE4 =~ E137 -0.64433718 0.03157497 -20.4065783 0.000000e+00 -0.70622299 -0.582451369
5 facetE4 =~ E47 -0.54438599 0.03640589 -14.9532409 0.000000e+00 -0.61574022 -0.473031763
6 facetE4 =~ E77 -0.26364406 0.04606861 -5.7228562 1.047479e-08 -0.35393688 -0.173351232
7 facetE4 =~ E197 -0.24332106 0.04651459 -5.2310693 1.685323e-07 -0.33448799 -0.152154136
8 facetC1 =~ C35 -0.14604111 0.04842129 -3.0160517 2.560896e-03 -0.24094508 -0.051137127
9 facetE4 =~ E167 -0.08824671 0.04874610 -1.8103335 7.024408e-02 -0.18378732 0.007293902
10 facetA6 =~ A239 -0.02160141 0.05363318 -0.4027621 6.871232e-01 -0.12672051 0.083517687
11 facetN4 =~ N46 0.01122344 0.04976938 0.2255090 8.215833e-01 -0.08632275 0.108769628
12 facetO6 =~ O88 0.16700690 0.05668401 2.9462790 3.216221e-03 0.05590829 0.278105517
13 facetE5 =~ E52 0.17549144 0.05126533 3.4231992 6.188870e-04 0.07501324 0.275969638
14 facetC3 =~ C105 0.20419603 0.04918169 4.1518712 3.297679e-05 0.10780169 0.300590360
15 facetO6 =~ O208 0.20631639 0.05620800 3.6705875 2.419936e-04 0.09615073 0.316482053
16 facetO6 =~ O58 0.22008321 0.05602054 3.9286163 8.543601e-05 0.11028497 0.329881457
17 facetO4 =~ O168 0.22729572 0.05251574 4.3281445 1.503708e-05 0.12436676 0.330224677
18 facetN4 =~ N166 0.23018254 0.04750376 4.8455647 1.262521e-06 0.13707688 0.323288193
19 facetA2 =~ A129 0.23330738 0.04612596 5.0580490 4.235676e-07 0.14290216 0.323712608
20 facetC3 =~ C165 0.25649767 0.04818210 5.3235053 1.017865e-07 0.16206249 0.350932855
Huiuiui, E4 wurde anscheinend nicht umkodiert, denn die Ladungen sind fast alle negativ. Ein häufiger Fehler, der auf diesem Niveau der Publikation allerdings nicht passieren darf. Für das Modell ist es natürlich nicht so ganz so wichtig, denn der Fit bleibt gleich.
Allerdings sind auch Items C35, E167 und A239 sehr problematisch. Negative Ladungen sollte nie auftreten. Für C35 habe ich schon eine Vermutung was los ist, aber dazu später.
Schauen wir uns mal die besten Ladungen an:
sems_std_df %>%
arrange(desc(est.std)) %>%
slice(1:20)
lhs op rhs est.std se z pvalue ci.lower ci.upper
1 N =~ facetN1 0.9686899 0.01397068 69.33733 0 0.9413078 0.9960719
2 E =~ facetE6 0.9251787 0.02450739 37.75102 0 0.8771451 0.9732123
3 N =~ facetN6 0.9201446 0.01759590 52.29314 0 0.8856573 0.9546319
4 N =~ facetN3 0.9192523 0.01520762 60.44683 0 0.8894460 0.9490587
5 C =~ facetC1 0.9020884 0.02630235 34.29687 0 0.8505367 0.9536401
6 C =~ facetC5 0.8891235 0.02172692 40.92267 0 0.8465395 0.9317075
7 facetO1 =~ O63 0.8499725 0.01735081 48.98749 0 0.8159655 0.8839794
8 C =~ facetC3 0.8420555 0.03257672 25.84838 0 0.7782063 0.9059047
9 N =~ facetN4 0.8328335 0.02720093 30.61784 0 0.7795206 0.8861463
10 C =~ facetC4 0.8183424 0.02622797 31.20113 0 0.7669365 0.8697482
11 facetN3 =~ N191 0.8165254 0.01802394 45.30227 0 0.7811991 0.8518517
12 E =~ facetE1 0.8120647 0.03014162 26.94164 0 0.7529882 0.8711412
13 O =~ facetO2 0.7970076 0.04072730 19.56937 0 0.7171836 0.8768317
14 facetE6 =~ E177 0.7957048 0.02207473 36.04596 0 0.7524391 0.8389705
15 facetO1 =~ O3 0.7888331 0.02090975 37.72561 0 0.7478507 0.8298154
16 facetC4 =~ C110 0.7868876 0.02315101 33.98934 0 0.7415124 0.8322627
17 facetA2 =~ A159 0.7738501 0.02365462 32.71455 0 0.7274879 0.8202123
18 facetE3 =~ E72 0.7687956 0.02426004 31.68979 0 0.7212468 0.8163444
19 facetA2 =~ A39 0.7678677 0.02397561 32.02703 0 0.7208763 0.8148590
20 facetE2 =~ E217 0.7665395 0.02642218 29.01121 0 0.7147530 0.8183260
Faktor N und C funktionieren am besten.
Schauen wir uns mal die Varianzaufklärung pro Faktor und Facette an:
sems_std_df %>%
group_by(lhs) %>%
summarize(r2 = sum(est.std^2) / n()) %>%
arrange(r2)
# A tibble: 35 × 2
lhs r2
<chr> <dbl>
1 facetO6 0.117
2 facetA6 0.155
3 facetO4 0.180
4 facetC3 0.181
5 facetA4 0.183
6 facetE5 0.194
7 facetC1 0.206
8 facetN5 0.211
9 facetN4 0.211
10 facetC2 0.242
# … with 25 more rows
O6 funktioniert am schlechtesten. Wenn ihr wissen wollt, was die Facetten sind, lohnt sich ein Blick auf einen freien Klon vom NEO-PI-R, den IPIP-NEO-120:
https://ipip.ori.org/30FacetNEO-PI-RItems.htm
Die Facetten sind fast identisch zum NEO-PI-R. Wir sehen auf der Website von IPIP, dass O6 Liberalismus ist (im NEO-PI-R heißt die Facette etwas anders, aber meint das gleiche). Ich glaube zu wissen, warum diese Facette nicht funktioniert, da ich dazu einen Artikel geschrieben habe. Der befindet sich allerdings noch im Review-Prozess. Sobald dieser durch ist, werde ich den Blog-Eintrag aktualisieren und meine Erklärung vorstellen.
Das war’s auch schon für heute. Wir haben gelernt, wie man einen echten Big Five Datensatz in R fittet. Interessanterweise geht es überhaupt nicht das Gesamt-Modell zu fitten. Man muss jeden Faktor einzeln berechnen, was aber wohl kaum zu Abweichungen im Vergleich zum Gesamtmodell führen würde.
Wenn Du Anmerkungen hast, hinterlasse sie gerne unter dem Artikel. Dafür brauchst Du einen github-Account, der aber schnell eingerichtet.
Footnotes
https://scholar.google.com/scholar?cites=14207675757160667030&as_sdt=2005&sciodt=0,5&hl=de↩︎
Dolan, C. V., Oort, F. J., Stoel, R. D., & Wicherts, J. M. (2009). Testing measurement invariance in the target rotates multigroup exploratory factor model. Structural Equation Modeling, 16, 295<96>314.↩︎
Wenn Du immer noch nicht
librarian
hast, installiere es vorab↩︎Siehe z. B. Kajonius, P. J., & Johnson, J. A. (2019). Assessing the structure of the five factor model of personality (IPIP-NEO-120) in the public domain. Europe’s Journal of Psychology, 15(2), 260–275. https://doi.org/10/gh8gk3↩︎