# Two outcomes on a shared predictor set. The residual covariance
# between the outcomes is estimated as part of the model, which is
# what separates this from two separate regressions. The fit asks
# for the Wald interval, a choice taken up below, and keeps the
# default effect_sizes = TRUE: the per-outcome effect sizes come
# back on the fit rather than in summary(), one row per outcome and
# predictor, giving the semi-partial R^2 and Cohen's f^2, and they
# are what fills the standardized coefficients in coef_table.
fit <- mlmr_mv(cbind(t6_paragraph_comprehension, t9_word_meaning) ~
t5_general_information + t7_sentence,
data = holzinger_swineford,
ci_method = "wald")
coef(fit) # matrix: rows = predictors, cols = outcomes
summary(fit)
fit$R2 # per-outcome R^2
fit$residual_cov # residual covariance among outcomes
print(fit$effect_sizes, row.names = FALSE)
# The interval menu is profile, Wald, and bootstrap. The default,
# ci_method = "profile", inverts the likelihood ratio test one
# coefficient at a time, and with two outcomes there are twice as
# many coefficients to profile; it is what a reported interval
# deserves, and leaving ci_method at its default asks for it. The
# fits on this page ask for the Wald or the bootstrap interval
# because those refits take longer than a help page should. The
# bootstrap resamples rows and takes percentile limits; it is what
# to ask for when the multivariate normality the likelihood assumes
# is doubtful. B = 10 keeps the example quick, since every resample
# refits the two-outcome model; a reported interval deserves the
# default B = 1000. boot_seed fixes the resamples, so the limits
# are reproducible rather than moving from run to run. The effect
# sizes cost one constrained refit per outcome and predictor, so this
# fit and the ones after it leave them off.
fit_boot <- mlmr_mv(cbind(t6_paragraph_comprehension, t9_word_meaning) ~
t5_general_information + t7_sentence,
data = holzinger_swineford,
ci_method = "boot", B = 10, boot_seed = 113,
effect_sizes = FALSE)
confint(fit_boot)
# FIML versus listwise when one outcome has missing values. The
# revised second-form test t26_flags was administered to only 145
# of the 301 students, so it carries real missingness. A row with
# t26_flags missing still informs the likelihood about the other
# outcome, about the predictors, and, through the residual
# covariance, about t26_flags itself, so no row is discarded. Notice
# the two sample sizes, and that the coefficients of the complete
# outcome differ between the fits: listwise deletion drops 156 of
# its observed rows along with the missing t26_flags values.
fit_fiml <- mlmr_mv(cbind(t6_paragraph_comprehension,
t26_flags) ~
t7_sentence + t9_word_meaning,
data = holzinger_swineford,
ci_method = "wald", effect_sizes = FALSE)
fit_lwd <- mlmr_mv(cbind(t6_paragraph_comprehension,
t26_flags) ~
t7_sentence + t9_word_meaning,
data = holzinger_swineford,
missing = "listwise", ci_method = "wald",
effect_sizes = FALSE)
c(N_fiml = nobs(fit_fiml), N_listwise = nobs(fit_lwd))
cbind(FIML = coef(fit_fiml)[, "t6_paragraph_comprehension"],
listwise = coef(fit_lwd)[, "t6_paragraph_comprehension"])
# Auxiliary variable (saturated correlates): the complete speed test
# t13_straight_and_curved_capitals informs the likelihood without
# entering either regression. Continuing from the model above, the
# coefficients of the complete outcome are unchanged to working
# precision, while those of t26_flags move, since the auxiliary
# carries information about the rows where t26_flags is missing.
fit_aux <- mlmr_mv(cbind(t6_paragraph_comprehension,
t26_flags) ~
t7_sentence + t9_word_meaning,
data = holzinger_swineford,
ci_method = "wald",
auxiliary = "t13_straight_and_curved_capitals",
effect_sizes = FALSE)
coef(fit_aux)
Run the code above in your browser using DataLab