Big Five Strukturgleichungs-Modell mit echtem Datensatz in R berechnen (Paket lavaan)

R
Faktorenanalyse
Big Five
Statistik
Autor:in

Johannes Titz

Veröffentlichungsdatum

14. März 2023

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:

# Falls Du librarian noch nicht hast, die nächste Zeile auskommentieren und ausführen
# install.packages("librarian")
librarian::shelf(qgraph)

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:

  1. AV ~ UV1 + UV2…
  2. 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 pastet 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:

librarian::shelf(lavaanPlot)
plot0 <- lavaanPlot(model = fitA,
                    graph_options = list(overlap = "true", fontsize = "10",
                                         rankdir = "LR"),
                    node_options = list(shape = "box", fontsize = "10"),
                    edge_options = list(color = "grey"),
                    coefs = TRUE, stand = TRUE)
embed_plot_pdf(plot0, "plot0.pdf")

SEM für Faktor Agreeableness

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.

Fußnoten

  1. https://scholar.google.com/scholar?cites=14207675757160667030&as_sdt=2005&sciodt=0,5&hl=de↩︎

  2. 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.↩︎

  3. Wenn Du immer noch nicht librarian hast, installiere es vorab↩︎

  4. 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↩︎