compareLavaan: Prepare a table to compare fit measures of confirmatory...

Description Usage Arguments Details Value Author(s) Examples

View source: R/modelcomparison.R

Description

If the parameter nesting is not specified, then this function attempts to discern which models are nested and they are ordered accordingly. The user can override that by specifing a nesting structure. This uses a new notation to represent nesting of models. See the parameter nesting. The syntax uses the symbols ">" and "+" in an obvious way to indicate that one model is the superset or on the same level as another. If the

Usage

1
2
3
compareLavaan(models, fitmeas = c("chisq", "df", "pvalue", "rmsea",
  "cfi", "tli", "srmr", "aic", "bic"), nesting = NULL, scaled = TRUE,
  chidif = TRUE, digits = 3, ...)

Arguments

models

list of lavaan cfa or sem models. Model names can be supplied. See examples.

fitmeas

A vector of fit measures. One or more of these c("chisq", "df", "pvalue", "rmsea", "cfi", "tli", "srmr", "aic", "bic", "srmr", "aic", "bic", "srmr_mplus"). Other fit measures present in the lavaan objects will be allowed; fit measures that are requested but not found are ignored.

nesting

character string indicating the nesting structure of the models. Must only contain model names, ">", and "+" separated by spaces. The model to the left of a ">" is the parent model for all models to the right of the same ">", up until another ">" is reached. When multiple models are nested in the same parent, they are separated by a "+".

scaled

should scaled versions of the fit measures requested be used if available? The scaled statistic is determined by the model estimation method. The defaul value is TRUE.

chidif

should the nested models be compared by using the anova function? The anova function may pass the model comparison on to another lavaan function. The results are added to the last three columns of the comparison table. The default value is TRUE.

digits

The digits argument that will be passed to xtable.

...

Arguments that will be passed to print.xtable. These arguments can be used to control table caption, label, and so forth. See ?print.xtable. If type = "latex" or "html", this function sets additional default values for print.xtable that can be overridden by specifying arguments here. Default type is an R data.frame, which is printed on screen. Note the print.xtable parameter print.results determines whether the markup is displayed before it is returned. The file parameter can specify a file into which the markup is to be saved.

Details

In May 2018, the output approach was changed. The functions xtable and print.xtable are used to render the final result and any of the arguments allowed by print.xtable can be used here (via the ... argument). We have some default settings for some print.xtable, such as type = NULL, file = NULL, print.results = TRUE, and math.style.exponents = TRUE. There are some other specific defaults for type = "latex" and type = "html", but they can all be overridden by the user. We include a model legend at the bottom of the table, indicating which models are compared by the Chi-squared statistic.

If the type argument is not specified, then the output will be a simple text display of the model table. If type is either "latex" or "html", then a marked up table will be displayed and the file argument can be used to ask for a saved version. If the user wants to simply save the result in a file, and not display on screen, insert the argument print.results = FALSE.

Value

If type = NULL, a data.frame object includes an attribute called "noteinfo". If type = "tex", return is a character vector created by xtable. If type = "html", a vector of HTML markup created by xtable.

Author(s)

Ben Kite <bakite@ku.edu> and Paul Johnson <pauljohn@ku.edu>

Examples

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
library(lavaan)
library(xtable)
set.seed(123)
genmodel <- "f1 =~ .7*v1 + .7*v2 + .7*v3 + .7*v4 + .7*v5 + .7*v6
f1 ~~ 1*f1"
genmodel2 <- "f1 =~ .7*v1 + .7*v2 + .7*v3 + .7*v4 + .7*v5 + .2*v6
f1 ~~ 1*f1"
##'
dat1 <- simulateData(genmodel, sample.nobs = 300)
dat2 <- simulateData(genmodel2, sample.nobs = 300)
dat1$group <- 0
dat2$group <- 1
dat <- rbind(dat1, dat2)
## In order from less constrained to restricted
## Model cc1 configural model
cc1.model <- "
              f1 =~ 1*v1 + v2 + v3 + v4 + v5 + v6
    		  f1 ~~ f1
    		  f1 ~0*1
    		 "
## Model2: cc2 partial weak model (AKA partial metric)
cc2.model <- "
              f1 =~ 1*v1 + c(L2,L2)*v2 + c(L3,L3)*v3 + c(L4,L4)*v4 + c(L5,L5)*v5 + v6
    		  f1 ~~ f1
    		  f1 ~0*1
    		"
## Model 3: weak model (AKA metric)
cc3.model <- "
            f1 =~ 1*v1 + c(L2,L2)*v2 + c(L3,L3)*v3 + c(L4,L4)*v4 + c(L5,L5)*v5 + c(L6,L6)*v6
    		f1 ~~ f1
    		 f1 ~0*1
    		"
## Model 4: scalar model (AKA strong)
cc4.model <- "
              f1 =~ 1*v1 + c(L2,L2)*v2 + c(L3,L3)*v3 + c(L4,L4)*v4 + c(L5,L5)*v5 + v6
    		  f1 ~~ f1
    		  f1 ~ c(0,NA)*1
    		  v1 ~ c(I1,I1)*1
    		  v2 ~ c(I2,I2)*1
    		  v3 ~ c(I3,I3)*1
    		  v4 ~ c(I4,I4)*1
    		  v5 ~ c(I5,I5)*1
    		  v6 ~ c(I6,I6)*1
    		"

## Reload saved models if available: avoids slow re-estimation that bothers CRAN
cc1 <-  tryCatch(readRDS(system.file("cfa/cc1.rds", package = "semTable")),
                 error = function(e) cfa(cc1.model, data=dat, group="group",
                                         meanstructure=TRUE, estimator = "MLR"))
cc2 <- tryCatch(readRDS(system.file("cfa/cc2.rds", package = "semTable")),
                error = function(e) cfa(cc2.model, data=dat, group="group",
                                        meanstructure=TRUE, estimator = "MLR"))
cc3 <- tryCatch(readRDS(system.file("cfa/cc3.rds", package = "semTable")),
                 error = function(e) cfa(cc3.model, data=dat, group="group",
                                         meanstructure=TRUE, estimator = "MLR"))
cc4 <- tryCatch(readRDS(system.file("cfa/cc4.rds", package = "semTable")),
                error = function(e) cfa(cc4.model, data=dat, group="group",
                                        meanstructure=TRUE, estimator = "MLR"))

models <- list(cc1, cc2, cc3, cc4)
## Note, nesting is not specified, so built-in nesting detection applies
compareLavaan(models)
compareLavaan(models, type = "latex")
compareLavaan(models, type = "html")
##'
## Now we specify model labels in the list
models <- list("Configural" = cc1,  "PartialMetric" = cc2, "Metric" = cc3, "Scalar" = cc4)
## The model labels are used in the nesting parameter
compareLavaan(models, nesting = "Configural > PartialMetric > Metric > Scalar")
##' Previous incorrect, treat cc2 and cc3 as children of cc1 instead:
compareLavaan(models, nesting = "Configural > PartialMetric + Metric > Scalar")
##' 
compareLavaan(models, fitmeas = c("chisq", "df", "cfi", "rmsea", "tli"),
              nesting = "Configural > Metric + PartialMetric > Scalar")

compareLavaan(models, fitmeas = c("chisq", "df", "cfi", "rmsea", "tli"),
             nesting = "Configural > PartialMetric + Metric > Scalar")
##'
## Creates output file
## compareLavaan(models, fitmeas = c("chisq", "df", "cfi", "rmsea", "tli"),
## nesting = "Configural > Metric + PartialMetric > Scalar", type = "tex",
## file = "/tmp/table.tex")

Example output

This is lavaan 0.6-7
lavaan is BETA software! Please report any bugs.
       chisq.scaled df.scaled pvalue.scaled rmsea.scaled cfi.scaled tli.scaled
Model1       14.230        18         0.714        0.000      1.000      1.013
Model2       19.670        22         0.604        0.000      1.000      1.006
Model3       39.065        23         0.020        0.048      0.967      0.958
Model4       22.476        27         0.713        0.000      1.000      1.010
        srmr      aic      bic     dchi ddf npval
Model1 0.022 11011.18 11169.47        -   -     -
Model2 0.033 11008.58 11149.28   5.509a   4 0.239
Model3 0.061 11026.07 11162.37  20.409b   1     0
Model4 0.035 11001.36 11120.08 -16.582c   4     1
a = Model2 vs Model1 b = Model3 vs Model2 c = Model4 vs Model3
Warning message:
In lavTestLRT(object = new("lavaan", version = "0.6.3", call = lavaan::lavaan(model = cc4.model,  :
  lavaan WARNING: some restricted models fit better than less 
	 restricted models; either these models are not nested, or
	 the less restricted model failed to reach a global optimum.
% latex table generated in R 4.0.3 by xtable 1.8-4 package
% Thu Mar  4 10:39:04 2021
\begin{table}[ht]
\centering
\begin{tabular}{rrrrrrrrrrlll}
  \hline
 & $\chi^{2}$ & df & \textit{p}-value & rmsea & cfi & tli & srmr & aic & bic & $\Delta\chi^{2}$ & $\Delta df$ & \textit{p} \\ 
  \hline
Model1 & 14.23 & 18.00 & 0.71 & 0.00 & 1.00 & 1.01 & 0.02 & 11011.18 & 11169.47 & - & - & - \\ 
  Model2 & 19.67 & 22.00 & 0.60 & 0.00 & 1.00 & 1.01 & 0.03 & 11008.58 & 11149.28 & 5.509a & 4 & 0.239 \\ 
  Model3 & 39.06 & 23.00 & 0.02 & 0.05 & 0.97 & 0.96 & 0.06 & 11026.07 & 11162.37 & 20.409b & 1 & 0 \\ 
  Model4 & 22.48 & 27.00 & 0.71 & 0.00 & 1.00 & 1.01 & 0.04 & 11001.36 & 11120.08 & -16.582c & 4 & 1 \\ 
   \hline
\multicolumn{4}{l}{a = Model2 vs Model1} \\
\multicolumn{4}{l}{b = Model3 vs Model2} \\
\multicolumn{4}{l}{c = Model4 vs Model3} \\
 \hline
\end{tabular}
\end{table}
Warning message:
In lavTestLRT(object = new("lavaan", version = "0.6.3", call = lavaan::lavaan(model = cc4.model,  :
  lavaan WARNING: some restricted models fit better than less 
	 restricted models; either these models are not nested, or
	 the less restricted model failed to reach a global optimum.
<!-- html table generated in R 4.0.3 by xtable 1.8-4 package -->
<!-- Thu Mar  4 10:39:05 2021 -->
<table 0>
<tr> <th>  </th> <th> chisq </th> <th> df </th> <th> pvalue </th> <th> rmsea </th> <th> cfi </th> <th> tli </th> <th> srmr </th> <th> aic </th> <th> bic </th> <th> dchi </th> <th> ddf </th> <th> npval </th>  </tr>
  <tr> <td align="right"> Model1 </td> <td align="right"> 14.23 </td> <td align="right"> 18.00 </td> <td align="right"> 0.71 </td> <td align="right"> 0.00 </td> <td align="right"> 1.00 </td> <td align="right"> 1.01 </td> <td align="right"> 0.02 </td> <td align="right"> 11011.18 </td> <td align="right"> 11169.47 </td> <td> - </td> <td> - </td> <td> - </td> </tr>
  <tr> <td align="right"> Model2 </td> <td align="right"> 19.67 </td> <td align="right"> 22.00 </td> <td align="right"> 0.60 </td> <td align="right"> 0.00 </td> <td align="right"> 1.00 </td> <td align="right"> 1.01 </td> <td align="right"> 0.03 </td> <td align="right"> 11008.58 </td> <td align="right"> 11149.28 </td> <td> 5.509a </td> <td> 4 </td> <td> 0.239 </td> </tr>
  <tr> <td align="right"> Model3 </td> <td align="right"> 39.06 </td> <td align="right"> 23.00 </td> <td align="right"> 0.02 </td> <td align="right"> 0.05 </td> <td align="right"> 0.97 </td> <td align="right"> 0.96 </td> <td align="right"> 0.06 </td> <td align="right"> 11026.07 </td> <td align="right"> 11162.37 </td> <td> 20.409b </td> <td> 1 </td> <td> 0 </td> </tr>
  <tr> <td align="right"> Model4 </td> <td align="right"> 22.48 </td> <td align="right"> 27.00 </td> <td align="right"> 0.71 </td> <td align="right"> 0.00 </td> <td align="right"> 1.00 </td> <td align="right"> 1.01 </td> <td align="right"> 0.04 </td> <td align="right"> 11001.36 </td> <td align="right"> 11120.08 </td> <td> -16.582c </td> <td> 4 </td> <td> 1 </td> </tr>
   
<tr><td colspan="4">a = Model2 vs Model1</td></tr>
<tr><td colspan="4">b = Model3 vs Model2</td></tr>
<tr><td colspan="4">c = Model4 vs Model3</td></tr>
 </table>
Warning message:
In lavTestLRT(object = new("lavaan", version = "0.6.3", call = lavaan::lavaan(model = cc4.model,  :
  lavaan WARNING: some restricted models fit better than less 
	 restricted models; either these models are not nested, or
	 the less restricted model failed to reach a global optimum.
              chisq.scaled df.scaled pvalue.scaled rmsea.scaled cfi.scaled
Configural          14.230        18         0.714        0.000      1.000
PartialMetric       19.670        22         0.604        0.000      1.000
Metric              39.065        23         0.020        0.048      0.967
Scalar              22.476        27         0.713        0.000      1.000
              tli.scaled  srmr      aic      bic     dchi ddf npval
Configural         1.013 0.022 11011.18 11169.47        -   -     -
PartialMetric      1.006 0.033 11008.58 11149.28   5.509a   4 0.239
Metric             0.958 0.061 11026.07 11162.37  20.409b   1     0
Scalar             1.010 0.035 11001.36 11120.08 -16.582c   4     1
a = PartialMetric vs Configural b = Metric vs PartialMetric 
c = Scalar vs Metric
Warning message:
In lavTestLRT(object = new("lavaan", version = "0.6.3", call = lavaan::lavaan(model = cc4.model,  :
  lavaan WARNING: some restricted models fit better than less 
	 restricted models; either these models are not nested, or
	 the less restricted model failed to reach a global optimum.
              chisq.scaled df.scaled pvalue.scaled rmsea.scaled cfi.scaled
Configural          14.230        18         0.714        0.000      1.000
PartialMetric       19.670        22         0.604        0.000      1.000
Metric              39.065        23         0.020        0.048      0.967
Scalar              22.476        27         0.713        0.000      1.000
              tli.scaled  srmr      aic      bic     dchi ddf npval
Configural         1.013 0.022 11011.18 11169.47        -   -     -
PartialMetric      1.006 0.033 11008.58 11149.28   5.509a   4 0.239
Metric             0.958 0.061 11026.07 11162.37  25.527b   5     0
Scalar             1.010 0.035 11001.36 11120.08 -16.582c   4     1
a = PartialMetric vs Configural b = Metric vs Configural c = Scalar vs Metric
Warning message:
In lavTestLRT(object = new("lavaan", version = "0.6.3", call = lavaan::lavaan(model = cc4.model,  :
  lavaan WARNING: some restricted models fit better than less 
	 restricted models; either these models are not nested, or
	 the less restricted model failed to reach a global optimum.
              chisq.scaled df.scaled cfi.scaled rmsea.scaled tli.scaled    dchi
Configural          14.230        18      1.000        0.000      1.013       -
Metric              39.065        23      0.967        0.048      0.958 25.527a
PartialMetric       19.670        22      1.000        0.000      1.006  5.509b
Scalar              22.476        27      1.000        0.000      1.010  2.789c
              ddf npval
Configural      -     -
Metric          5     0
PartialMetric   4 0.239
Scalar          5 0.733
a = Metric vs Configural b = PartialMetric vs Configural 
c = Scalar vs PartialMetric
              chisq.scaled df.scaled cfi.scaled rmsea.scaled tli.scaled
Configural          14.230        18      1.000        0.000      1.013
PartialMetric       19.670        22      1.000        0.000      1.006
Metric              39.065        23      0.967        0.048      0.958
Scalar              22.476        27      1.000        0.000      1.010
                  dchi ddf npval
Configural           -   -     -
PartialMetric   5.509a   4 0.239
Metric         25.527b   5     0
Scalar        -16.582c   4     1
a = PartialMetric vs Configural b = Metric vs Configural c = Scalar vs Metric
Warning message:
In lavTestLRT(object = new("lavaan", version = "0.6.3", call = lavaan::lavaan(model = cc4.model,  :
  lavaan WARNING: some restricted models fit better than less 
	 restricted models; either these models are not nested, or
	 the less restricted model failed to reach a global optimum.

semTable documentation built on April 30, 2020, 1:05 a.m.