Fits the standard ladder of multiple group invariance models for a measurement model of any number of factors and reports the comparison table researchers actually use: configural invariance (same pattern, all parameters free by group), metric (equal loadings; required before comparing relations involving the factor), scalar (equal loadings and intercepts; required before comparing factor means), and strict (equal residual variances as well; required before comparing observed-score variances). With ordered indicators a thresholds rung comes first, because thresholds rather than intercepts carry the location information (Wu & Estabrook, 2016); with dichotomous indicators the two are not separately identified, so that rung is folded into metric. Each rung is tested against the previous with a likelihood ratio test, scaled when the estimator in force carries a robust test, which is what declaring ordered items arranges, and the practical-fit changes (delta CFI, delta RMSEA) are reported alongside, since with large samples the chi square will flag trivial differences (Cheung & Rensvold, 2002, suggest delta CFI of about -.01 as a red flag). The fitted lavaan objects come back as an attribute, so score tests and partial invariance refits do not require refitting the ladder. Requires lavaan.
Usage
measurement_invariance(
data,
model = NULL,
group,
items = NULL,
levels = NULL,
ordered = NULL,
estimator = "ML",
missing = "listwise",
group_partial = NULL,
parameterization = c("delta", "theta"),
...
)Arguments
- data
A
data.framewith the items and the grouping variable.- model
The measurement model, given either as lavaan model syntax (a single string, or a character vector of lines that is collapsed with newlines, such as
c("visual =~ x1 + x2 + x3", "verbal =~ x4 + x5 + x6")) or as a named list mapping each factor name to a character vector of its item names, from which the syntax is built. Exactly one ofmodelanditemsmust be supplied.- group
Single character string naming the grouping column (two or more groups).
- items
Character vector (three or more) naming the indicator columns of a single factor. A convenience for the one-factor (congeneric) case of
cfa_1, equivalent tomodel = "f =~ item_1 + item_2 + ...". Exactly one ofmodelanditemsmust be supplied.- levels
Which rungs of the ladder to fit, in order: any leading subset of the ladder in force. With continuous indicators the ladder is
c("configural", "metric", "scalar", "strict"); with ordered indicators it isc("configural", "thresholds", "metric", "scalar", "strict"); when every indicator is ordered and dichotomous it isc("configural", "metric", "scalar"), because neither the thresholds nor the strict rung is identified for a two-category item (seeorderedbelow).NULL(the default) fits the whole ladder in force.- ordered
Ordered-categorical (including binary) items:
TRUEfor every indicator in the model, or a character vector naming the ordered ones.NULL(default) treats all indicators as continuous. Declaring ordered items switches the ladder and, unless the estimator already carries the mean and variance adjusted test, switches the estimator (seeestimatorbelow). The number of observed categories per declared item is counted before the ladder is built, because a dichotomous item has a single threshold that is not separately identified from the intercept of its underlying response (Millsap & Yun-Tein, 2004; Wu & Estabrook, 2016), and its residual variance is not a free parameter under either parameterization. When every declared item is dichotomous the thresholds rung is folded into metric, and the strict rung is dropped as well unless a continuous indicator is left to carry a residual variance; when only some declared items are dichotomous, both rungs are kept and a message names those items, whose thresholds and residual variances the rungs leave untested.- estimator
Estimator passed to lavaan. Defaults to
"ML"; use"MLR"for robust corrections, in which case the likelihood ratio tests use the scaled difference. Whenorderedis supplied, a maximum likelihood or generalized least squares (the"GLS"label; Browne, 1974) estimator is replaced by"WLSMV", and"DWLS"and"ULS"are replaced by"WLSMV"and"ULSMV". That second substitution changes only the test: in lavaan"WLSMV"is"DWLS"and"ULSMV"is"ULS"with the mean and variance adjusted statistic, which is what makes the rung-to-rung difference test asymptotically valid for ordered data. The one categorical estimator left alone is"WLS", the full weight matrix estimator of Browne (1984) and Muthén (1984), whose statistic is asymptotically chi square already and whose weight matrix a substitution would silently change.- missing
Missing data handling passed to lavaan: one of
"listwise"(the default),"ml"or"fiml"(full information maximum likelihood, the reason to reach for this argument with continuous items and incomplete cases), or"pairwise". Full information maximum likelihood is not available with the categorical estimator; asking for both is an error.- group_partial
Character vector of parameters to leave free across groups at every rung, passed to lavaan's
group.partial. Either user-supplied parameter labels or lavaan parameter specifications such as"visual =~ x2"or"x2 ~1". This is the partial invariance case of Byrne, Shavelson, and Muthén (1989).NULL(default) constrains everything the rung calls for.- parameterization
Identification of ordered indicators, passed to lavaan:
"delta"(the default, lavaan's) or"theta". Residual variances are free parameters only under"theta", so a strict rung requested with ordered items switches to"theta"with a message. Ignored when no item is ordered.- ...
Further arguments passed to
cfaat every rung (for examplestd.lv,orthogonal,cluster).
Value
A tidy wide data.frame (class dmar_tbl) with one
row per fitted level and columns level (label),
chi_square, df, p_chi_square (exact-fit test),
cfi, rmsea, and, from the second row on, the
step-comparison columns delta_chi_square, delta_df,
p_value (the likelihood ratio test against the previous rung),
delta_cfi, and delta_rmsea. delta_chi_square and
p_value are NA wherever delta_df is zero, since a
difference test on zero degrees of freedom tests nothing. Attributes
carry the non-numeric information: "fits", the named list of fitted
lavaan objects, one per level; "estimator", the estimator
actually used; "ordered", TRUE when any indicator was
declared ordered; "test", naming the chi square difference test
used (NA when a single rung was fit and nothing was compared);
"fit_indices", "standard" or "robust"
according to which version of the fit indices is tabled; and
"model", the lavaan syntax that was fitted.
Details
The models are nested by construction, each adding equality constraints
across groups to the previous. With continuous indicators the constraint
sets are none (beyond the configuration), then group.equal =
"loadings", then c("loadings", "intercepts"), then
c("loadings", "intercepts", "residuals").
The ordered ladder differs, and the difference is substantive rather than
cosmetic. For an ordered indicator the observed response is a coarsening
of an underlying continuous response at a set of thresholds, and it is
the thresholds, not an intercept, that locate the item on the latent
scale. Constraining loadings while leaving thresholds free across groups
therefore does not deliver what metric invariance is supposed to deliver,
and the accepted sequence (Millsap & Yun-Tein, 2004; Wu & Estabrook,
2016) constrains thresholds first: "thresholds", then
c("thresholds", "loadings") for metric, then
c("thresholds", "loadings", "intercepts") for scalar, then adding
"residuals" for strict. The intercept rung is not vacuous even
when every indicator is ordered: once thresholds and loadings are
constrained, lavaan frees the underlying-response intercepts in the
non-reference groups, and the scalar rung is what returns them to zero
and lets the latent means be estimated instead. Residual variances,
however, are free parameters only under the theta parameterization, so
parameterization switches to "theta" when a strict rung is
requested with ordered items.
Dichotomous items are the exception the ordered ladder has to make room for. A two-category item contributes one threshold, and that threshold, the intercept of the underlying response, and its residual variance are not separately identified: the data give one proportion per group per item, which pins down a single standardized location and nothing else (Millsap & Yun-Tein, 2004; Wu & Estabrook, 2016). Constraining thresholds alone across groups is then a reparameterization rather than a restriction, since lavaan frees the underlying-response intercepts by exactly as many parameters as the constraint removes, and the residual variances stay fixed at one in every group whichever parameterization is in force. So the function counts the observed categories of each declared ordered indicator before building the ladder, and a message explains what the count implies. When all of them are dichotomous the thresholds rung is folded into metric, which constrains thresholds and loadings together; the strict rung goes too when every indicator in the model was declared ordered, leaving configural, metric, scalar. A continuous indicator alongside dichotomous ones keeps the strict rung, since its residual variance is a free parameter. When only some declared items are dichotomous the full ordered ladder is kept, since the polytomous items still carry testable thresholds and residual variances, and the message names the dichotomous items so their contribution to those two rungs is not overread. Every rung that is dropped is one that would have cost zero degrees of freedom.
When the estimator carries a robust test, the difference between two chi
square statistics is not itself chi square distributed.
lavTestLRT then returns the scaled difference test
(the Satorra-Bentler or Satorra correction, chosen by lavaan to
match the test in force), and that is what delta_chi_square and
p_value report; the "test" attribute names the test used. In
that case the model-level chi_square, p_chi_square,
cfi, and rmsea columns are lavaan's scaled and robust
versions, so delta_chi_square will not equal the difference of
consecutive chi_square entries. That is a property of scaled
difference testing, not an inconsistency.
Which estimators carry such a test is worth being precise about, because
a naive chi square difference on ordered data is not asymptotically valid.
"MLM", "MLMV", "MLR", "WLSM", "WLSMV",
"ULSM", and "ULSMV" carry one. "DWLS" and
"ULS" do not, which is why declaring ordered items promotes them to
"WLSMV" and "ULSMV": the discrepancy function and hence the
parameter estimates are untouched, and only the statistic changes. The
remaining case is "WLS", the full weight matrix estimator, whose
statistic is asymptotically chi square under the theory of Browne (1984)
and Muthén (1984) and so needs no correction; the "test" attribute
reports the standard difference test there. The sample size that theory
asks for is large, which is why full weighted least squares is rarely the
right choice in practice, but that is a separate matter from whether the
difference test is the right one.
A rung whose constraints cost no degrees of freedom tests nothing, so
delta_chi_square and p_value are NA when
delta_df is zero rather than reporting a difference in chi square
that is numerical noise and can come out negative. The situation is
reported in a message. It arises with dichotomous items (the ladder above
avoids the two rungs where it is structural) and, for instance, with
group_partial specifications that free every parameter a rung would
constrain.
Failure at a rung does not end the conversation: partial invariance
(freeing the offending parameter) is the usual next step, for which
group_partial refits the whole ladder with named parameters free,
and the "fits" attribute gives the fitted objects to
lavTestScore for a score test of which constraint
is doing the damage. This function deliberately reports the standard
ladder rather than automating modification searches.
References
Browne, M. W. (1974). Generalized least squares estimators in the analysis of covariance structures. South African Statistical Journal, 8, 1–24.
Browne, M. W. (1984). Asymptotically distribution-free methods for the analysis of covariance structures. British Journal of Mathematical and Statistical Psychology, 37(1), 62–83.
Byrne, B. M., Shavelson, R. J., & Muthén, B. (1989). Testing for the equivalence of factor covariance and mean structures: The issue of partial measurement invariance. Psychological Bulletin, 105(3), 456–466.
Cheung, G. W., & Rensvold, R. B. (2002). Evaluating goodness-of-fit indexes for testing measurement invariance. Structural Equation Modeling, 9(2), 233–255. doi:10.1207/S15328007SEM0902_5
Meredith, W. (1993). Measurement invariance, factor analysis and factorial invariance. Psychometrika, 58(4), 525–543. doi:10.1007/BF02294825
Millsap, R. E. (2011). Statistical approaches to measurement invariance. Routledge.
Millsap, R. E., & Yun-Tein, J. (2004). Assessing factorial invariance in ordered-categorical measures. Multivariate Behavioral Research, 39(3), 479–515. doi:10.1207/s15327906mbr3903_4
Muthén, B. (1984). A general structural equation model with dichotomous, ordered categorical, and continuous latent variable indicators. Psychometrika, 49(1), 115–132.
Satorra, A., & Bentler, P. M. (2001). A scaled difference chi-square test statistic for moment structure analysis. Psychometrika, 66(4), 507–514. doi:10.1007/BF02296192
Wu, H., & Estabrook, R. (2016). Identification of confirmatory factor analysis models of different levels of invariance for ordered categorical outcomes. Psychometrika, 81(4), 1014–1045. doi:10.1007/s11336-016-9506-0
See also
cfa_1 and cfa_k for the
single-group measurement models; reliability_omega for
the reliability of the composite the model justifies;
compare_cov_structures for covariance-structure
comparisons outside the factor model;
lavTestScore for the score test that localizes a
failed rung.
Other multivariate and latent variable methods:
average_variance_extracted(),
bifactor_indices(),
cfa_1(),
cfa_2(),
cfa_k(),
ci_eigenvalue(),
common_method_marker(),
common_method_single_factor(),
dmacs(),
ecvi(),
htmt(),
irt_grm(),
irt_information(),
measurement_alignment(),
procrustes_phi(),
simple_structure()
Author
Ken Kelley kkelley@nd.edu
Examples
# Do the two schools measure the verbal and the reasoning construct
# in the same way? (Holzinger & Swineford, bundled.) The measurement
# model is a named list of factors; for a single factor, name its
# indicators with items = instead.
data(holzinger_swineford)
hs_factors <- list(
verbal = c("t6_paragraph_comprehension", "t7_sentence",
"t9_word_meaning"),
deduction = c("t20_deduction", "t22_problem_reasoning",
"t23_series_completion"))
# The bottom two rungs. Configural invariance asks whether the same
# pattern of loadings holds at both schools; metric adds the
# constraint that the loadings are equal across schools, and it is
# the rung that has to hold before a relation involving one of these
# factors is compared across them. Naming those two in levels = stops
# the ladder there, which is what keeps this example quick.
mi <- measurement_invariance(holzinger_swineford, hs_factors,
group = "school",
levels = c("configural", "metric"))
mi
#> level chi_square df p_chi_square cfi rmsea delta_chi_square delta_df
#> configural 22.5 16 0.1276 0.992 0.052 <NA> <NA>
#> metric 36.3 20 0.0140 0.979 0.0737 13.8 4
#> p_value delta_cfi delta_rmsea
#> <NA> <NA> <NA>
#> 0.0078 -0.0127 0.0217
# The fitted models travel with the table, so localizing a failed rung
# costs no refitting.
names(attr(mi, "fits"))
#> [1] "configural" "metric"
# The broom verbs: one row per rung of the ladder, and the model-level
# summary (estimator, test flavor, fit index flavor).
generics::tidy(mi)
#> term chi_square df p_chi_square cfi rmsea delta_chi_square
#> 1 configural 22.50471 16 0.12762979 0.9915883 0.05197395 NA
#> 2 metric 36.34593 20 0.01400184 0.9788619 0.07369221 13.84122
#> delta_df p_value delta_cfi delta_rmsea
#> 1 NA NA NA NA
#> 2 4 0.00781944 -0.0127264 0.02171826
generics::glance(mi)
#> n_levels estimator ordered test fit_indices
#> 1 2 ML FALSE standard chi square difference test standard
# Each of the calls below refits the ladder from the bottom, so they
# are shown here rather than run. Leaving levels = at its default
# fits the whole ladder, configural through metric, scalar, and
# strict:
# measurement_invariance(holzinger_swineford, hs_factors,
# group = "school")
#
# Partial invariance frees one loading across the schools at every
# rung (Byrne, Shavelson, & Muthén, 1989), so each constrained rung
# loses one degree of freedom relative to full invariance:
# measurement_invariance(holzinger_swineford, hs_factors,
# group = "school",
# group_partial = "verbal =~ t7_sentence")
#
# With the indicators coded as ordered categories, ordered = TRUE puts
# the thresholds rung first, because thresholds rather than intercepts
# carry the location information there, and makes the rung-to-rung
# tests the scaled difference tests:
# hs_ordered <- holzinger_swineford
# for (item in unlist(hs_factors, use.names = FALSE)) {
# hs_ordered[[item]] <- as.integer(cut(
# holzinger_swineford[[item]],
# breaks = quantile(holzinger_swineford[[item]],
# c(0, .25, .5, .75, 1)),
# include.lowest = TRUE))
# }
# mi_ordered <- measurement_invariance(hs_ordered, hs_factors,
# group = "school",
# ordered = TRUE)
# mi_ordered
# attr(mi_ordered, "test")
#
# The measurement model can also be given as lavaan syntax, and
# missing = "fiml" fits the ladder by full information maximum
# likelihood when continuous items have incomplete cases:
# hs_missing <- holzinger_swineford
# set.seed(113)
# hs_missing$t7_sentence[sample(nrow(hs_missing), 20)] <- NA
# measurement_invariance(
# hs_missing,
# model = "verbal =~ t6_paragraph_comprehension + t7_sentence +
# t9_word_meaning",
# group = "school", missing = "fiml")