Skip to content

Commit 9e524d9

Browse files
committed
lavTestLRT(): add RMSEA if a robust test statistic is used (but only if data is complete)
1 parent c5f65f6 commit 9e524d9

File tree

6 files changed

+61
-45
lines changed

6 files changed

+61
-45
lines changed

DESCRIPTION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
Package: lavaan
22
Title: Latent Variable Analysis
3-
Version: 0.6-20.2325
3+
Version: 0.6-20.2326
44
Authors@R: c(person(given = "Yves", family = "Rosseel",
55
role = c("aut", "cre"),
66
email = "Yves.Rosseel@UGent.be",

R/lav_options.R

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,8 @@ lav_options_set <- function(opt = NULL) { # nolint
367367
))) {
368368
lav_msg_stop(gettextf(
369369
"missing=%1$s is not allowed for estimator %2$s",
370-
dQuote(opt$missing), dQuote(lav_options_estimatorgroup(opt$estimator))))
370+
dQuote(opt$missing),
371+
dQuote(lav_options_estimatorgroup(opt$estimator.orig))))
371372
}
372373
} else if (opt$missing == "ml.x") {
373374
if (opt$.categorical) {
@@ -381,7 +382,8 @@ lav_options_set <- function(opt = NULL) { # nolint
381382
))) {
382383
lav_msg_stop(gettextf(
383384
"missing=%1$s is not allowed for estimator %2$s",
384-
dQuote(opt$missing), dQuote(lav_options_estimatorgroup(opt$estimator))))
385+
dQuote(opt$missing),
386+
dQuote(lav_options_estimatorgroup(opt$estimator.orig))))
385387
}
386388
} else if (opt$missing == "two.stage") {
387389
if (opt$.categorical) {
@@ -395,7 +397,8 @@ lav_options_set <- function(opt = NULL) { # nolint
395397
))) {
396398
lav_msg_stop(gettextf(
397399
"missing=%1$s is not allowed for estimator %2$s",
398-
dQuote(opt$missing), dQuote(lav_options_estimatorgroup(opt$estimator))))
400+
dQuote(opt$missing),
401+
dQuote(lav_options_estimatorgroup(opt$estimator.orig))))
399402
}
400403
} else if (opt$missing == "robust.two.stage") {
401404
if (opt$.categorical) {
@@ -409,7 +412,8 @@ lav_options_set <- function(opt = NULL) { # nolint
409412
))) {
410413
lav_msg_stop(gettextf(
411414
"missing=%1$s is not allowed for estimator %2$s",
412-
dQuote(opt$missing), dQuote(lav_options_estimatorgroup(opt$estimator))))
415+
dQuote(opt$missing),
416+
dQuote(lav_options_estimatorgroup(opt$estimator.orig))))
413417
}
414418
} else if (opt$missing == "doubly.robust") {
415419
if (opt$estimator != "pml") {

R/lav_sam_step1_local.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -371,7 +371,7 @@ lav_sam_step1_local <- function(STEP1 = NULL, FIT = NULL, Y = NULL,
371371
# EETA is constrained somehow
372372
stop("not ready yet")
373373
# EETA[[b]] <- lav_sam_eeta_con(YBAR = YBAR, LAMBDA = LAMBDA[[b]],
374-
# THETA = THETA[[b]],
374+
# THETA = THETA[[b]],
375375
# L.veta = L.veta[[b]])
376376

377377
}

R/lav_sam_utils.R

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -951,8 +951,8 @@ lav_sam_veta_partable <- function(lavobject, block = 1L) {
951951
VETA
952952
}
953953

954-
lav_sam_veta_con <- function(S = NULL, LAMBDA = NULL, THETA = NULL,
955-
L.veta = NULL, local.M.method = "ML",
954+
lav_sam_veta_con <- function(S = NULL, LAMBDA = NULL, THETA = NULL,
955+
L.veta = NULL, local.M.method = "ML",
956956
tol = 1e-07, max.iter = 100L) {
957957

958958
# first do GLS/ULS

R/lav_test_LRT.R

Lines changed: 46 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
# method = "Satorra.Bentler.2010"
1212
# method = "mean.var.adjusted.PLRT"
1313
#
14-
# - 0.6-13: RMSEA.D (also known as 'RDR') is added to the table (unless scaled)
14+
# - 0.6-13: RMSEA.D (also known as 'RDR') is added to the table (also if scaled,
15+
# since 0.6-20)
1516
# - 0.6-13: fix multiple-group UG^2 bug in Satorra.2000 (reported by
1617
# Gronneberg, Foldnes and Moss)
1718
#
@@ -291,14 +292,6 @@ lavTestLRT <- function(object, ..., method = "default", test = "default",
291292
"satorra.2000")) {
292293
c.delta <- rep(as.numeric(NA), length(STAT))
293294
}
294-
# new in 0.6-13
295-
if (!scaled) {
296-
RMSEA.delta <- c(NA, lav_fit_rmsea(
297-
X2 = STAT.delta[-1],
298-
df = Df.delta[-1],
299-
N = ntotal, G = ngroups
300-
))
301-
}
302295

303296
# check for negative values in STAT.delta
304297
# but with a tolerance (0.6-12)!
@@ -366,9 +359,28 @@ lavTestLRT <- function(object, ..., method = "default", test = "default",
366359
}
367360
}
368361

362+
# unname
363+
STAT.delta <- unname(STAT.delta)
364+
Df.delta <- unname(Df.delta)
365+
if (scaled) {
366+
c.delta <- unname(c.delta)
367+
}
368+
369369
# Pvalue
370370
Pvalue.delta <- pchisq(STAT.delta, Df.delta, lower.tail = FALSE)
371371

372+
# new in 0.6-13: RMSEA (RMSEA.D or RDR)
373+
if (object@Options$missing == "listwise") {
374+
RMSEA.delta <- c(NA, lav_fit_rmsea(
375+
X2 = STAT.delta[-1],
376+
df = Df.delta[-1],
377+
N = ntotal,
378+
G = ngroups,
379+
c.hat = ifelse (scaled, c.delta[-1], rep(1, length(STAT.delta) - 1L))
380+
))
381+
}
382+
383+
# AIC/BIC
372384
aic <- bic <- rep(NA, length(mods))
373385
if (estimator == "ML") {
374386
aic <- sapply(mods, FUN = AIC)
@@ -391,33 +403,32 @@ lavTestLRT <- function(object, ..., method = "default", test = "default",
391403
row.names = names(mods),
392404
check.names = FALSE
393405
)
406+
} else if (object@Options$missing == "listwise") {
407+
val <- data.frame(
408+
Df = Df,
409+
AIC = aic,
410+
BIC = bic,
411+
Chisq = STAT,
412+
"Chisq diff" = STAT.delta,
413+
"RMSEA" = RMSEA.delta,
414+
"Df diff" = Df.delta,
415+
"Pr(>Chisq)" = Pvalue.delta,
416+
row.names = names(mods),
417+
check.names = FALSE
418+
)
394419
} else {
395-
if (scaled) {
396-
val <- data.frame(
397-
Df = Df,
398-
AIC = aic,
399-
BIC = bic,
400-
Chisq = STAT,
401-
"Chisq diff" = STAT.delta,
402-
"Df diff" = Df.delta,
403-
"Pr(>Chisq)" = Pvalue.delta,
404-
row.names = names(mods),
405-
check.names = FALSE
406-
)
407-
} else {
408-
val <- data.frame(
409-
Df = Df,
410-
AIC = aic,
411-
BIC = bic,
412-
Chisq = STAT,
413-
"Chisq diff" = STAT.delta,
414-
"RMSEA" = RMSEA.delta,
415-
"Df diff" = Df.delta,
416-
"Pr(>Chisq)" = Pvalue.delta,
417-
row.names = names(mods),
418-
check.names = FALSE
419-
)
420-
}
420+
val <- data.frame(
421+
Df = Df,
422+
AIC = aic,
423+
BIC = bic,
424+
Chisq = STAT,
425+
"Chisq diff" = STAT.delta,
426+
#"RMSEA" = RMSEA.delta, # if missing, not yet...
427+
"Df diff" = Df.delta,
428+
"Pr(>Chisq)" = Pvalue.delta,
429+
row.names = names(mods),
430+
check.names = FALSE
431+
)
421432
}
422433

423434
# catch Df.delta == 0 cases (reported by Florian Zsok in Zurich)

R/xxx_sam.R

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ sam <- function(model = NULL,
189189
# check for gamma.unbiased
190190
if (is.null(dotdotdot$gamma.unbiased)) {
191191
# put in TRUE in dotdotdot # lavaan default is still FALSE
192-
dotdotdot$gamma.unbiased <- TRUE
192+
dotdotdot$gamma.unbiased <- TRUE
193193
}
194194

195195

@@ -312,7 +312,8 @@ sam <- function(model = NULL,
312312
STEP1 <- lav_sam_step1_local(
313313
STEP1 = STEP1, FIT = FIT,
314314
sam.method = sam.method,
315-
local.options = local.options
315+
local.options = local.options,
316+
return.cov.iveta2 = (se %in% c("local", "local.nt"))
316317
)
317318
}
318319

0 commit comments

Comments
 (0)