File: partialInvariance.Rd

package info (click to toggle)
r-cran-semtools 0.5.7-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 3,204 kB
  • sloc: makefile: 2
file content (300 lines) | stat: -rw-r--r-- 13,064 bytes parent folder | download
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
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/partialInvariance.R
\name{partialInvariance}
\alias{partialInvariance}
\alias{partialInvarianceCat}
\title{Partial Measurement Invariance Testing Across Groups}
\usage{
partialInvariance(fit, type, free = NULL, fix = NULL, refgroup = 1,
  poolvar = TRUE, p.adjust = "none", fbound = 2, return.fit = FALSE,
  method = "satorra.bentler.2001")

partialInvarianceCat(fit, type, free = NULL, fix = NULL, refgroup = 1,
  poolvar = TRUE, p.adjust = "none", return.fit = FALSE,
  method = "satorra.bentler.2001")
}
\arguments{
\item{fit}{A list of models for invariance testing. Each model should be
assigned by appropriate names (see details). The result from
\code{\link[=measurementInvariance]{measurementInvariance()}} or
\code{\link[=measurementInvarianceCat]{measurementInvarianceCat()}} could be used in this argument
directly.}

\item{type}{The types of invariance testing: "metric", "scalar", "strict",
or "means"}

\item{free}{A vector of variable names that are free across groups in
advance. If partial mean invariance is tested, this argument represents a
vector of factor names that are free across groups.}

\item{fix}{A vector of variable names that are constrained to be equal
across groups in advance. If partial mean invariance is tested, this
argument represents a vector of factor names that are fixed across groups.}

\item{refgroup}{The reference group used to make the effect size comparison
with the other groups.}

\item{poolvar}{If \code{TRUE}, the variances are pooled across group for
standardization. Otherwise, the variances of the reference group are used
for standardization.}

\item{p.adjust}{The method used to adjust p values. See
\code{\link[stats:p.adjust]{stats::p.adjust()}} for the options for adjusting p values. The
default is to not use any corrections.}

\item{fbound}{The z-scores of factor that is used to calculate the effect
size of the loading difference proposed by Millsap and Olivera-Aguilar
(2012).}

\item{return.fit}{Return the submodels fitted by this function}

\item{method}{The method used to calculate likelihood ratio test. See
\code{\link[lavaan:lavTestLRT]{lavaan::lavTestLRT()}} for available options}
}
\value{
A list of results are provided. The list will consists of at least
two elements:
\enumerate{
\item \code{estimates}: The results of parameter estimates including pooled
estimates (\code{poolest}), the estimates for each group, standardized
estimates for each group (\code{std}), the difference in standardized
values, and the effect size statistic (\emph{q} for factor loading
difference and \emph{h} for error variance difference). See the details of
this effect size statistic by running \code{vignette("partialInvariance")}.
In the \code{partialInvariance} function, the additional effect statistics
proposed by Millsap and Olivera-Aguilar (2012) are provided. For factor
loading, the additional outputs are the observed mean difference
(\code{diff_mean}), the mean difference if factor scores are low
(\code{low_fscore}), and the mean difference if factor scores are high
(\code{high_fscore}). The low factor score is calculated by (a) finding the
factor scores that its \emph{z} score equals -\code{bound} (the default is
\eqn{-2}) from all groups and (b) picking the minimum value among the
factor scores. The high factor score is calculated by (a) finding the
factor scores that its \emph{z} score equals \code{bound} (default = 2)
from all groups and (b) picking the maximum value among the factor scores.
For measurement intercepts, the additional outputs are the observed means
difference (\code{diff_mean}) and the proportion of the differences in the
intercepts over the observed means differences (\code{propdiff}). For error
variances, the additional outputs are the proportion of the difference in
error variances over the difference in observed variances (\code{propdiff}).

\item \code{results}: Statistical tests as well as the change in CFI are
provided. \eqn{\chi^2} and \emph{p} value are provided for all methods.

\item \code{models}: The submodels used in the \code{free} and \code{fix}
methods, as well as the nested and parent models. The nested and parent
models will be changed from the original models if \code{free} or
\code{fit} arguments are specified.
}
}
\description{
This test will provide partial invariance testing by (a) freeing a parameter
one-by-one from nested model and compare with the original nested model or
(b) fixing (or constraining) a parameter one-by-one from the parent model
and compare with the original parent model. This function only works with
congeneric models. The \code{partialInvariance} is used for continuous
variable. The \code{partialInvarianceCat} is used for categorical variables.
}
\details{
There are four types of partial invariance testing:

\itemize{
\item Partial weak invariance. The model named 'fit.configural'
from the list of models is compared with the model named 'fit.loadings'.
Each loading will be freed or fixed from the metric and configural
invariance models respectively. The modified models are compared with the
original model. Note that the objects in the list of models must have the
names of "fit.configural" and "fit.loadings". Users may use "metric",
"weak", "loading", or "loadings" in the \code{type} argument. Note that, for
testing invariance on marker variables, other variables will be assigned as
marker variables automatically.

\item Partial strong invariance. The model
named 'fit.loadings' from the list of models is compared with the model
named either 'fit.intercepts' or 'fit.thresholds'. Each intercept will be
freed or fixed from the scalar and metric invariance models respectively.
The modified models are compared with the original model. Note that the
objects in the list of models must have the names of "fit.loadings" and
either "fit.intercepts" or "fit.thresholds". Users may use "scalar",
"strong", "intercept", "intercepts", "threshold", or "thresholds" in the
\code{type} argument. Note that, for testing invariance on marker variables,
other variables will be assigned as marker variables automatically. Note
that if all variables are dichotomous, scalar invariance testing is not
available.

\item Partial strict invariance. The model named either
'fit.intercepts' or 'fit.thresholds' (or 'fit.loadings') from the list of
models is compared with the model named 'fit.residuals'. Each residual
variance will be freed or fixed from the strict and scalar (or metric)
invariance models respectively. The modified models are compared with the
original model. Note that the objects in the list of models must have the
names of "fit.residuals" and either "fit.intercepts", "fit.thresholds", or
"fit.loadings". Users may use "strict", "residual", "residuals", "error", or
"errors" in the \code{type} argument.

\item Partial mean invariance. The
model named either 'fit.intercepts' or 'fit.thresholds' (or 'fit.residuals'
or 'fit.loadings') from the list of models is compared with the model named
'fit.means'. Each factor mean will be freed or fixed from the means and
scalar (or strict or metric) invariance models respectively. The modified
models are compared with the original model. Note that the objects in the
list of models must have the names of "fit.means" and either
"fit.residuals", "fit.intercepts", "fit.thresholds", or "fit.loadings".
Users may use "means" or "mean" in the \code{type} argument. }

Two types of comparisons are used in this function:
\enumerate{
\item \code{free}: The nested model is used as a template. Then, one
parameter indicating the differences between two models is free. The new
model is compared with the nested model. This process is repeated for all
differences between two models. The likelihood-ratio test and the difference
in CFI are provided.

\item \code{fix}: The parent model is used as a template. Then, one parameter
indicating the differences between two models is fixed or constrained to be
equal to other parameters. The new model is then compared with the parent
model. This process is repeated for all differences between two models. The
likelihood-ratio test and the difference in CFI are provided.

\item \code{wald}: This method is similar to the \code{fix} method. However,
instead of building a new model and compare them with likelihood-ratio test,
multivariate wald test is used to compare equality between parameter
estimates. See \code{\link[lavaan:lavTestWald]{lavaan::lavTestWald()}} for further details. Note
that if any rows of the contrast cannot be summed to 0, the Wald test is not
provided, such as comparing two means where one of the means is fixed as 0.
This test statistic is not as accurate as likelihood-ratio test provided in
\code{fix}. I provide it here in case that likelihood-ratio test fails to
converge.
}

Note that this function does not adjust for the inflated Type I error rate
from multiple tests. The degree of freedom of all tests would be the number
of groups minus 1.

The details of standardized estimates and the effect size used for each
parameters are provided in the vignettes by running
\code{vignette("partialInvariance")}.
}
\examples{

## Conduct weak invariance testing manually by using fixed-factor
## method of scale identification

library(lavaan)

conf <- "
f1 =~ NA*x1 + x2 + x3
f2 =~ NA*x4 + x5 + x6
f1 ~~ c(1, 1)*f1
f2 ~~ c(1, 1)*f2
"

weak <- "
f1 =~ NA*x1 + x2 + x3
f2 =~ NA*x4 + x5 + x6
f1 ~~ c(1, NA)*f1
f2 ~~ c(1, NA)*f2
"

configural <- cfa(conf, data = HolzingerSwineford1939, std.lv = TRUE, group="school")
weak <- cfa(weak, data = HolzingerSwineford1939, group="school", group.equal="loadings")
models <- list(fit.configural = configural, fit.loadings = weak)
partialInvariance(models, "metric")

\donttest{
partialInvariance(models, "metric", free = "x5") # "x5" is free across groups in advance
partialInvariance(models, "metric", fix = "x4") # "x4" is fixed across groups in advance

## Use the result from the measurementInvariance function
HW.model <- ' visual =~ x1 + x2 + x3
              textual =~ x4 + x5 + x6
              speed =~ x7 + x8 + x9 '

models2 <- measurementInvariance(model = HW.model, data=HolzingerSwineford1939,
                                 group="school")
partialInvariance(models2, "scalar")

## Conduct weak invariance testing manually by using fixed-factor
## method of scale identification for dichotomous variables

f <- rnorm(1000, 0, 1)
u1 <- 0.9*f + rnorm(1000, 1, sqrt(0.19))
u2 <- 0.8*f + rnorm(1000, 1, sqrt(0.36))
u3 <- 0.6*f + rnorm(1000, 1, sqrt(0.64))
u4 <- 0.7*f + rnorm(1000, 1, sqrt(0.51))
u1 <- as.numeric(cut(u1, breaks = c(-Inf, 0, Inf)))
u2 <- as.numeric(cut(u2, breaks = c(-Inf, 0.5, Inf)))
u3 <- as.numeric(cut(u3, breaks = c(-Inf, 0, Inf)))
u4 <- as.numeric(cut(u4, breaks = c(-Inf, -0.5, Inf)))
g <- rep(c(1, 2), 500)
dat2 <- data.frame(u1, u2, u3, u4, g)

configural2 <- "
f1 =~ NA*u1 + u2 + u3 + u4
u1 | c(t11, t11)*t1
u2 | c(t21, t21)*t1
u3 | c(t31, t31)*t1
u4 | c(t41, t41)*t1
f1 ~~ c(1, 1)*f1
f1 ~ c(0, NA)*1
u1 ~~ c(1, 1)*u1
u2 ~~ c(1, NA)*u2
u3 ~~ c(1, NA)*u3
u4 ~~ c(1, NA)*u4
"

outConfigural2 <- cfa(configural2, data = dat2, group = "g",
                      parameterization = "theta", estimator = "wlsmv",
                      ordered = c("u1", "u2", "u3", "u4"))

weak2 <- "
f1 =~ NA*u1 + c(f11, f11)*u1 + c(f21, f21)*u2 + c(f31, f31)*u3 + c(f41, f41)*u4
u1 | c(t11, t11)*t1
u2 | c(t21, t21)*t1
u3 | c(t31, t31)*t1
u4 | c(t41, t41)*t1
f1 ~~ c(1, NA)*f1
f1 ~ c(0, NA)*1
u1 ~~ c(1, 1)*u1
u2 ~~ c(1, NA)*u2
u3 ~~ c(1, NA)*u3
u4 ~~ c(1, NA)*u4
"

outWeak2 <- cfa(weak2, data = dat2, group = "g", parameterization = "theta",
                estimator = "wlsmv", ordered = c("u1", "u2", "u3", "u4"))
modelsCat <- list(fit.configural = outConfigural2, fit.loadings = outWeak2)

partialInvarianceCat(modelsCat, type = "metric")

partialInvarianceCat(modelsCat, type = "metric", free = "u2")
partialInvarianceCat(modelsCat, type = "metric", fix = "u3")

## Use the result from the measurementInvarianceCat function

model <- ' f1 =~ u1 + u2 + u3 + u4
           f2 =~ u5 + u6 + u7 + u8'

modelsCat2 <- measurementInvarianceCat(model = model, data = datCat, group = "g",
	                                      parameterization = "theta",
	                                      estimator = "wlsmv", strict = TRUE)

partialInvarianceCat(modelsCat2, type = "scalar")
}

}
\references{
Millsap, R. E., & Olivera-Aguilar, M. (2012). Investigating
measurement invariance using confirmatory factor analysis. In R. H. Hoyle
(Ed.), \emph{Handbook of structural equation modeling} (pp. 380--392). New
York, NY: Guilford.
}
\seealso{
\code{\link[=measurementInvariance]{measurementInvariance()}} for measurement invariance for
continuous variables; \code{\link[=measurementInvarianceCat]{measurementInvarianceCat()}} for measurement
invariance for categorical variables; \code{\link[lavaan:lavTestWald]{lavaan::lavTestWald()}} for
multivariate Wald test
}
\author{
Sunthud Pornprasertmanit (\email{psunthud@gmail.com})
}