diff --git a/DESCRIPTION b/DESCRIPTION index d71f604..f427055 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: mxsem Type: Package Title: Specify 'OpenMx' Models with a 'lavaan'-Style Syntax -Version: 0.0.10 +Version: 0.1.0 Authors@R: c(person(given = "Jannik H.", family = "Orzek", role = c("aut", "cre", "cph"), email = "jannik.orzek@mailbox.org", @@ -20,7 +20,7 @@ Imports: dplyr, utils LinkingTo: Rcpp -RoxygenNote: 7.2.3 +RoxygenNote: 7.3.1 Encoding: UTF-8 Suggests: knitr, diff --git a/R/check_modifier_for_algebra.R b/R/check_modifier_for_algebra.R index 1341580..5cb14b1 100644 --- a/R/check_modifier_for_algebra.R +++ b/R/check_modifier_for_algebra.R @@ -6,7 +6,7 @@ #' @param parameter_table parameter table #' @param directed symbol used to indicate directed effects (regressions and loadings) #' @param undirected symbol used to indicate undirected effects (variances and covariances) -#' @return parameter_table +#' @returns data.frame with parameters (parameter table) #' @keywords internal check_modifier_for_algebra <- function(parameter_table, directed, diff --git a/R/extract_algebra_elements.R b/R/extract_algebra_elements.R index eb538e4..61a5737 100644 --- a/R/extract_algebra_elements.R +++ b/R/extract_algebra_elements.R @@ -3,7 +3,7 @@ #' extract all variables/parameters from an mxAlgebra #' @param mxAlgebra_formula formula embedded in mxAlgebra #' @param extracted used in recursive function calls; don't set this manually -#' @return vector with names of variables and parameters used in the function call +#' @returns vector with names of variables and parameters used in the function call #' @keywords internal extract_algebra_elements <- function(mxAlgebra_formula, extracted = c()){ diff --git a/R/mxsem.R b/R/mxsem.R index be14410..c204f3e 100644 --- a/R/mxsem.R +++ b/R/mxsem.R @@ -211,7 +211,7 @@ NULL #' @param undirected symbol used to indicate undirected effects (variances and covariances) #' @param return_parameter_table if set to TRUE, the internal parameter table is returend #' together with the mxModel -#' @return mxModel object that can be fitted with mxRun or mxTryHard. If return_parameter_table +#' @returns mxModel object that can be fitted with mxRun or mxTryHard. If return_parameter_table #' is TRUE, a list with the mxModel and the parameter table is returned. #' @export #' @import OpenMx diff --git a/R/mxsem_group_by.R b/R/mxsem_group_by.R index e342e20..ca06078 100644 --- a/R/mxsem_group_by.R +++ b/R/mxsem_group_by.R @@ -26,7 +26,7 @@ #' group specific. For instance, if parameters = "a" and use_grepl = TRUE, all parameters #' whose label contains the letter "a" will be group specific. If use_grep = FALSE #' only the parameter that has the label "a" is group specific. -#' @return mxModel with multiple groups. Use get_groups to extract the groups +#' @returns mxModel with multiple groups. Use get_groups to extract the groups #' @export #' @examples #' # THE FOLLOWING EXAMPLE IS ADAPTED FROM @@ -144,7 +144,7 @@ mxsem_group_by <- function(mxModel, #' #' returns a list of groups for a multi group model #' @param multi_group_model multi group model created with mxsem_group_by -#' @return list with data for each group +#' @returns list with data for each group #' @export #' @examples #' # THE FOLLOWING EXAMPLE IS ADAPTED FROM @@ -228,6 +228,7 @@ summarize_multi_group_model <- function(multi_group_model){ #' @param x object from summarize_multi_group_model #' @param ... not used #' @method print multi_group_parameters +#' @returns nothing #' @export print.multi_group_parameters <- function(x, ...){ console_width <- getOption("width") diff --git a/R/set_starting_values.R b/R/set_starting_values.R index 3db381d..6858238 100644 --- a/R/set_starting_values.R +++ b/R/set_starting_values.R @@ -4,7 +4,7 @@ #' omxSetParameters. #' @param mx_model model of class mxModel #' @param values vector with labeled parameter values -#' @return mxModel with changed parameter values +#' @returns mxModel with changed parameter values #' @export #' @examples #' library(mxsem) diff --git a/R/simulate_data.R b/R/simulate_data.R index 7764857..61bd100 100644 --- a/R/simulate_data.R +++ b/R/simulate_data.R @@ -4,7 +4,7 @@ #' simulate data for a latent growth curve model with five measurement occasions. #' The time-distance between these occasions differs between subjects. #' @param N sample size -#' @return data set with columns y1-y5 (observations) and t_1-t_5 (time of +#' @returns data set with columns y1-y5 (observations) and t_1-t_5 (time of #' observation) #' @export #' @importFrom stats rnorm @@ -51,7 +51,7 @@ simulate_latent_growth_curve <- function(N = 100){ #' #' simulate data for a moderated nonlinear factor analysis. #' @param N sample size -#' @return data set with variables x1-x3 and y1-y3 representing repeated measurements +#' @returns data set with variables x1-x3 and y1-y3 representing repeated measurements #' of an affect measure. It is assumed that the autoregressive effect is different #' depending on covariate k #' @export diff --git a/R/unicode_arrows.R b/R/unicode_arrows.R index b334668..4c2651e 100644 --- a/R/unicode_arrows.R +++ b/R/unicode_arrows.R @@ -2,7 +2,7 @@ #' #' this function returns the unicode for directed arrows #' -#' @return returns unicode for directed arrows +#' @returns returns unicode for directed arrows #' @export unicode_directed <- function() return("\u2192") @@ -11,7 +11,7 @@ unicode_directed <- function() #' #' this function returns the unicode for undirected arrows #' -#' @return returns unicode for undirected arrows +#' @returns returns unicode for undirected arrows #' @export unicode_undirected <- function() return("\u2194") diff --git a/man/check_modifier_for_algebra.Rd b/man/check_modifier_for_algebra.Rd index 8110206..f41d574 100644 --- a/man/check_modifier_for_algebra.Rd +++ b/man/check_modifier_for_algebra.Rd @@ -14,7 +14,7 @@ check_modifier_for_algebra(parameter_table, directed, undirected) \item{undirected}{symbol used to indicate undirected effects (variances and covariances)} } \value{ -parameter_table +data.frame with parameters (parameter table) } \description{ takes in the parameter table and checks if any of the modifiers therein diff --git a/man/print.multi_group_parameters.Rd b/man/print.multi_group_parameters.Rd index f5655f8..f7baf7f 100644 --- a/man/print.multi_group_parameters.Rd +++ b/man/print.multi_group_parameters.Rd @@ -11,6 +11,9 @@ \item{...}{not used} } +\value{ +nothing +} \description{ print the multi_group_parameters } diff --git a/vignettes/Moderated-Nonlinear-Factor-Analysis.mxsemmd.Rmd b/vignettes/Moderated-Nonlinear-Factor-Analysis.mxsemmd.Rmd new file mode 100644 index 0000000..155e813 --- /dev/null +++ b/vignettes/Moderated-Nonlinear-Factor-Analysis.mxsemmd.Rmd @@ -0,0 +1,465 @@ +--- +title: "Moderated-Nonlinear-Factor-Analysis" +output: rmarkdown::html_vignette +bibliography: mxsem.bib +csl: apa.csl +vignette: > + %\VignetteIndexEntry{Moderated-Nonlinear-Factor-Analysis} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} + %\DeclareUnicodeCharacter{2194}{$\leftrightarrow$} + %\DeclareUnicodeCharacter{2192}{$\rightarrow$} +--- + + + +Moderated nonlinear factor analysis (MNLFA) has been proposed by @bauerMoreGeneralModel2017 +to assess measurement invariance. The general idea is that parameters within +the model (that is, loadings, regressions, intercepts, and (co-)variances) may +differ across individuals. These differences are predicted using covariates such +as age and gender. For instance, @kolbeAssessingMeasurementInvariance2022 demonstrate +MNLFA using the following model: + +![](figures/mnlfa.png) + +The loading `lSi_1` may differ linearly by age and gender [@kolbeAssessingMeasurementInvariance2022]. +That is `lSi_1 = lSi0_1 + lSi1_1*Age + lSi2_1*Male`. +If `lSi1_1` or `lSi2_1` are non-zero, this suggests measurement non-invariance. + +MNLFA is a powerful procedure, but specifying the models can be tedious. +@kolbeAssessingMeasurementInvariance2022 provide an in-depth introduction using +**OpenMx** using the DS14 data set by @denolletPredictiveValueSocial2013 +included in the **mokken** [@MokkenScaleAnalysis2007] package. + +The script for the tutorial by @kolbeAssessingMeasurementInvariance2022 can +be found on osf at https://osf.io/527zr. The following pre-processing steps +are taken directly from that script: + + +```r +# code copied from Laura Kolbe, Terrence D. Jorgensen, Suzanne Jak, and Dylan Molenaar +# at https://osf.io/527zr + +library(mokken) +#> Loading required package: poLCA +#> Loading required package: scatterplot3d +#> Loading required package: MASS + +## Load data +data("DS14", package="mokken") + +## Save as data frame +DS14 <- data.frame(DS14) + +## Recode negatively worded items +DS14$Si1 <- 4 - DS14$Si1. +DS14$Si3 <- 4 - DS14$Si3. + +## Standardize age +DS14$Age <- (DS14$Age - mean(DS14$Age))/sd(DS14$Age) +# mean-centering age is another option, but caused convergence difficulties with +# this dataset + +## Change order of variables +DS14 <- DS14[,c("Male","Age","Si1","Si3","Si6","Si8","Si10","Si11","Si14", + "Na2","Na4","Na5","Na7","Na9","Na12", "Na13")] + +## Check data +head(DS14) +#> Male Age Si1 Si3 Si6 Si8 Si10 Si11 Si14 Na2 Na4 Na5 Na7 Na9 Na12 Na13 +#> 1 1 0.03136864 2 2 2 3 2 2 4 3 2 2 3 2 4 2 +#> 2 1 -0.44266587 2 1 2 2 2 4 2 0 0 0 0 0 3 0 +#> 3 1 -0.82189349 3 3 2 2 2 2 1 3 1 1 2 2 1 1 +#> 4 1 -0.63227968 2 2 1 2 3 1 1 3 0 0 0 1 1 0 +#> 5 1 0.03136864 2 3 2 3 3 2 3 2 2 2 3 2 3 1 +#> 6 0 -0.06343826 0 0 0 0 0 0 0 3 1 2 1 2 4 2 +``` + +## Model specification + +We want to specify the configural model outlined in @kolbeAssessingMeasurementInvariance2022. +In this model, all loadings, intercepts, variances and co-variances are predicted +with the covariates `Age` and `Male`. The only parameter that is constant across +all subjects are the latent variances of `Si` and `Na`, which are fixed to 1 for +scaling. + +For demonstrative purposes, we will first set up a confirmatory factor analysis +without the `Age` and `Male` covariates. Using **mxsem**, the syntax could look +as follows: + + + +```r +cfa_syntax <- " + +# loadings +Si =~ lSi_1*Si1 + + lSi_3*Si3 + + lSi_6*Si6 + + lSi_8*Si8 + + lSi_10*Si10 + + lSi_11*Si11 + + lSi_14*Si14 + +Na =~ lNa_2*Na2 + + lNa_4*Na4 + + lNa_5*Na5 + + lNa_7*Na7 + + lNa_9*Na9 + + lNa_12*Na12 + + lNa_13*Na13 + +# latent variances and covariances +Si ~~ 1*Si +Na ~~ 1*Na + cov*Si + +# manifest variances +Si1 ~~ vSi_1*Si1 +Si3 ~~ vSi_3*Si3 +Si6 ~~ vSi_6*Si6 +Si8 ~~ vSi_8*Si8 +Si10 ~~ vSi_10*Si10 +Si11 ~~ vSi_11*Si11 +Si14 ~~ vSi_14*Si14 + +Na2 ~~ vNa_2*Na2 +Na4 ~~ vNa_4*Na4 +Na5 ~~ vNa_5*Na5 +Na7 ~~ vNa_7*Na7 +Na9 ~~ vNa_9*Na9 +Na12 ~~ vNa_12*Na12 +Na13 ~~ vNa_13*Na13 + +# intercepts +Si1 ~ iSi_1*1 +Si3 ~ iSi_3*1 +Si6 ~ iSi_6*1 +Si8 ~ iSi_8*1 +Si10 ~ iSi_10*1 +Si11 ~ iSi_11*1 +Si14 ~ iSi_14*1 + +Na2 ~ iNa_2*1 +Na4 ~ iNa_4*1 +Na5 ~ iNa_5*1 +Na7 ~ iNa_7*1 +Na9 ~ iNa_9*1 +Na12 ~ iNa_12*1 +Na13 ~ iNa_13*1 +" +``` + +We want to predict each and every parameter in this model using `Age` and `Male`. + +* `lSi_1 = lSi0_1 + lSi1_1*Age + lSi2_1*Male` +* `lSi_3 = lSi0_3 + lSi1_3*Age + lSi2_3*Male` +* ... +* `iNa_4 = iNa0_4 + iNa1_4*Age + iNa2_4*Male` +* ... + +With **mxsem**, this can be implemented as follows: + + +```r +mnlfa_syntax <- " +==== MNLFA ==== + +SI =~ {lSi_1 := lSi0_1 + lSi1_1*data.Age + lSi2_1*data.Male }*Si1 + + {lSi_3 := lSi0_3 + lSi1_3*data.Age + lSi2_3*data.Male }*Si3 + + {lSi_6 := lSi0_6 + lSi1_6*data.Age + lSi2_6*data.Male }*Si6 + + {lSi_8 := lSi0_8 + lSi1_8*data.Age + lSi2_8*data.Male }*Si8 + + {lSi_10 := lSi0_10 + lSi1_10*data.Age + lSi2_10*data.Male}*Si10 + + {lSi_11 := lSi0_11 + lSi1_11*data.Age + lSi2_11*data.Male}*Si11 + + {lSi_14 := lSi0_14 + lSi1_14*data.Age + lSi2_14*data.Male}*Si14 + +NA =~ {lNa_2 := lNa0_2 + lNa1_2*data.Age + lNa2_2*data.Male }*Na2 + + {lNa_4 := lNa0_4 + lNa1_4*data.Age + lNa2_4*data.Male }*Na4 + + {lNa_5 := lNa0_5 + lNa1_5*data.Age + lNa2_5*data.Male }*Na5 + + {lNa_7 := lNa0_7 + lNa1_7*data.Age + lNa2_7*data.Male }*Na7 + + {lNa_9 := lNa0_9 + lNa1_9*data.Age + lNa2_9*data.Male }*Na9 + + {lNa_12 := lNa0_12 + lNa1_12*data.Age + lNa2_12*data.Male}*Na12 + + {lNa_13 := lNa0_13 + lNa1_13*data.Age + lNa2_13*data.Male}*Na13 + +SI ~~ 1*SI +NA ~~ 1*NA + {cov := cov0 + cov1*data.Age + cov2*data.Male }*SI + +Si1 ~~ {vSi_1 := exp(vSi0_1 + vSi1_1*data.Age + vSi2_1*data.Male )}*Si1 +Si3 ~~ {vSi_3 := exp(vSi0_3 + vSi1_3*data.Age + vSi2_3*data.Male )}*Si3 +Si6 ~~ {vSi_6 := exp(vSi0_6 + vSi1_6*data.Age + vSi2_6*data.Male )}*Si6 +Si8 ~~ {vSi_8 := exp(vSi0_8 + vSi1_8*data.Age + vSi2_8*data.Male )}*Si8 +Si10 ~~ {vSi_10 := exp(vSi0_10 + vSi1_10*data.Age + vSi2_10*data.Male)}*Si10 +Si11 ~~ {vSi_11 := exp(vSi0_11 + vSi1_11*data.Age + vSi2_11*data.Male)}*Si11 +Si14 ~~ {vSi_14 := exp(vSi0_14 + vSi1_14*data.Age + vSi2_14*data.Male)}*Si14 + +Na2 ~~ {vNa_2 := exp(vNa0_2 + vNa1_2*data.Age + vNa2_2*data.Male )}*Na2 +Na4 ~~ {vNa_4 := exp(vNa0_4 + vNa1_4*data.Age + vNa2_4*data.Male )}*Na4 +Na5 ~~ {vNa_5 := exp(vNa0_5 + vNa1_5*data.Age + vNa2_5*data.Male )}*Na5 +Na7 ~~ {vNa_7 := exp(vNa0_7 + vNa1_7*data.Age + vNa2_7*data.Male )}*Na7 +Na9 ~~ {vNa_9 := exp(vNa0_9 + vNa1_9*data.Age + vNa2_9*data.Male )}*Na9 +Na12 ~~ {vNa_12 := exp(vNa0_12 + vNa1_12*data.Age + vNa2_12*data.Male)}*Na12 +Na13 ~~ {vNa_13 := exp(vNa0_13 + vNa1_13*data.Age + vNa2_13*data.Male)}*Na13 + +Si1 ~ {iSi_1 := iSi0_1 + iSi1_1*data.Age + iSi2_1*data.Male }*1 +Si3 ~ {iSi_3 := iSi0_3 + iSi1_3*data.Age + iSi2_3*data.Male }*1 +Si6 ~ {iSi_6 := iSi0_6 + iSi1_6*data.Age + iSi2_6*data.Male }*1 +Si8 ~ {iSi_8 := iSi0_8 + iSi1_8*data.Age + iSi2_8*data.Male }*1 +Si10 ~ {iSi_10 := iSi0_10 + iSi1_10*data.Age + iSi2_10*data.Male}*1 +Si11 ~ {iSi_11 := iSi0_11 + iSi1_11*data.Age + iSi2_11*data.Male}*1 +Si14 ~ {iSi_14 := iSi0_14 + iSi1_14*data.Age + iSi2_14*data.Male}*1 + +Na2 ~ {iNa_2 := iNa0_2 + iNa1_2*data.Age + iNa2_2*data.Male }*1 +Na4 ~ {iNa_4 := iNa0_4 + iNa1_4*data.Age + iNa2_4*data.Male }*1 +Na5 ~ {iNa_5 := iNa0_5 + iNa1_5*data.Age + iNa2_5*data.Male }*1 +Na7 ~ {iNa_7 := iNa0_7 + iNa1_7*data.Age + iNa2_7*data.Male }*1 +Na9 ~ {iNa_9 := iNa0_9 + iNa1_9*data.Age + iNa2_9*data.Male }*1 +Na12 ~ {iNa_12 := iNa0_12 + iNa1_12*data.Age + iNa2_12*data.Male}*1 +Na13 ~ {iNa_13 := iNa0_13 + iNa1_13*data.Age + iNa2_13*data.Male}*1 +" +``` + +Note how each parameter is redefined exactly as outlined above. However, there +are some important details: + +1. The variance parameters (e.g., `vNa_2`), have been transformed with an `exp`-function. +This exponential function ensures that variances are always positive. +2. All transformations must be embraced in curly braces. This ensures that **mxsem** +sees them as algebras and knows how to specify them in **OpenMx**. +3. The covariates `Age` and `Male` must be specified with the `data.`-prefix to +let **OpenMx** know that the values can be found in the data set. + +Finally, we pass the syntax to the `mxsem()`-function to create an **OpenMx** model: + + +```r +library(mxsem) +mnlfa_model <- mxsem(model = mnlfa_syntax, + data = DS14, + # we scaled the latent variables manually, + # so we will set all automatic scalings to FALSE: + scale_loadings = FALSE, + scale_latent_variances = FALSE) +``` + + +## Fitting the model + +The model can now be fitted using `mxRun()` or `mxTryHard()`. + + + +```r +mnlfa_model <- mxRun(mnlfa_model) +summary(mnlfa_model) +``` + +
+Show summary + +``` +#> Summary of MNLFA +#> +#> free parameters: +#> name matrix row col Estimate Std.Error A +#> 1 lSi0_1 new_parameters 1 1 0.7335132438 0.13014259 +#> 2 lSi1_1 new_parameters 1 2 -0.1154254859 0.05221606 ! +#> 3 lSi2_1 new_parameters 1 3 0.1400286503 0.13842043 +#> 4 lSi0_3 new_parameters 1 4 0.3015782269 0.16698194 +#> 5 lSi1_3 new_parameters 1 5 -0.0879323806 0.05924893 +#> 6 lSi2_3 new_parameters 1 6 0.4591409572 0.17600719 +#> 7 lSi0_6 new_parameters 1 7 0.9194296826 0.15083646 +#> 8 lSi1_6 new_parameters 1 8 -0.0706498200 0.04992898 +#> 9 lSi2_6 new_parameters 1 9 -0.0979268804 0.15834908 +#> 10 lSi0_8 new_parameters 1 10 1.0701238128 0.12909755 +#> 11 lSi1_8 new_parameters 1 11 0.0561234444 0.04935638 +#> 12 lSi2_8 new_parameters 1 12 -0.0853303894 0.13773342 +#> 13 lSi0_10 new_parameters 1 13 1.1310725384 0.14861613 +#> 14 lSi1_10 new_parameters 1 14 -0.0484480471 0.05808300 +#> 15 lSi2_10 new_parameters 1 15 -0.1777563818 0.15842175 +#> 16 lSi0_11 new_parameters 1 16 0.7556453882 0.13468991 +#> 17 lSi1_11 new_parameters 1 17 -0.0525072503 0.05104562 +#> 18 lSi2_11 new_parameters 1 18 -0.0430455977 0.14344742 ! +#> 19 lSi0_14 new_parameters 1 19 0.6896194563 0.11909184 +#> 20 lSi1_14 new_parameters 1 20 0.1111536860 0.04814864 +#> 21 lSi2_14 new_parameters 1 21 0.1527644391 0.12792708 +#> 22 lNa0_2 new_parameters 1 22 0.7798765704 0.15330398 +#> 23 lNa1_2 new_parameters 1 23 -0.0757615406 0.05656212 +#> 24 lNa2_2 new_parameters 1 24 -0.0933489066 0.16463571 +#> 25 lNa0_4 new_parameters 1 25 1.0847614818 0.12749259 +#> 26 lNa1_4 new_parameters 1 26 -0.0943803248 0.04226512 +#> 27 lNa2_4 new_parameters 1 27 -0.2833533846 0.13476123 +#> 28 lNa0_5 new_parameters 1 28 0.5882977934 0.13857929 +#> 29 lNa1_5 new_parameters 1 29 -0.0689102945 0.05228898 +#> 30 lNa2_5 new_parameters 1 30 0.1443499799 0.14916484 +#> 31 lNa0_7 new_parameters 1 31 1.1002294496 0.12071028 +#> 32 lNa1_7 new_parameters 1 32 -0.0872053171 0.04421125 +#> 33 lNa2_7 new_parameters 1 33 -0.1714469053 0.12909793 +#> 34 lNa0_9 new_parameters 1 34 0.7460504309 0.12926455 +#> 35 lNa1_9 new_parameters 1 35 -0.0247286638 0.04320843 +#> 36 lNa2_9 new_parameters 1 36 -0.0758240491 0.13720476 +#> 37 lNa0_12 new_parameters 1 37 0.8353126873 0.14344193 +#> 38 lNa1_12 new_parameters 1 38 -0.0472960393 0.05227695 +#> 39 lNa2_12 new_parameters 1 39 0.0720072128 0.15334385 +#> 40 lNa0_13 new_parameters 1 40 1.3331780393 0.12221639 +#> 41 lNa1_13 new_parameters 1 41 -0.0808880606 0.03986926 +#> 42 lNa2_13 new_parameters 1 42 -0.4766565469 0.12830609 +#> 43 cov0 new_parameters 1 43 0.5021308989 0.10205429 +#> 44 cov1 new_parameters 1 44 0.0184185153 0.04156460 +#> 45 cov2 new_parameters 1 45 -0.0494766127 0.11067074 +#> 46 vSi0_1 new_parameters 1 46 -0.3207921437 0.19411340 +#> 47 vSi1_1 new_parameters 1 47 -0.0242559678 0.07039287 +#> 48 vSi2_1 new_parameters 1 48 -0.1741243216 0.20884743 +#> 49 vSi0_3 new_parameters 1 49 0.4646166674 0.17569299 +#> 50 vSi1_3 new_parameters 1 50 0.0600874965 0.06277472 +#> 51 vSi2_3 new_parameters 1 51 -0.4775700274 0.18976243 +#> 52 vSi0_6 new_parameters 1 52 -0.0244158405 0.19926680 +#> 53 vSi1_6 new_parameters 1 53 0.0410837351 0.07265658 +#> 54 vSi2_6 new_parameters 1 54 -0.4232699330 0.21468956 +#> 55 vSi0_8 new_parameters 1 55 -0.7723689259 0.27106479 +#> 56 vSi1_8 new_parameters 1 56 -0.1785978996 0.09287264 +#> 57 vSi2_8 new_parameters 1 57 0.0830338358 0.28444387 +#> 58 vSi0_10 new_parameters 1 58 -0.3311375892 0.23075346 +#> 59 vSi1_10 new_parameters 1 59 0.0456637852 0.06899717 +#> 60 vSi2_10 new_parameters 1 60 0.1333979308 0.24267213 +#> 61 vSi0_11 new_parameters 1 61 -0.1991709907 0.19190984 +#> 62 vSi1_11 new_parameters 1 62 0.0764535825 0.07264657 +#> 63 vSi2_11 new_parameters 1 63 -0.0606475820 0.20458983 +#> 64 vSi0_14 new_parameters 1 64 -0.4409584817 0.19529868 +#> 65 vSi1_14 new_parameters 1 65 -0.0797038127 0.07834774 +#> 66 vSi2_14 new_parameters 1 66 -0.1140400370 0.21056361 +#> 67 vNa0_2 new_parameters 1 67 0.0992622309 0.18032888 +#> 68 vNa1_2 new_parameters 1 68 0.0624813513 0.06505584 +#> 69 vNa2_2 new_parameters 1 69 0.0822169751 0.19346911 +#> 70 vNa0_4 new_parameters 1 70 -0.7374873652 0.19598278 +#> 71 vNa1_4 new_parameters 1 71 0.0972335635 0.08014757 +#> 72 vNa2_4 new_parameters 1 72 -0.0004451435 0.21177285 +#> 73 vNa0_5 new_parameters 1 73 0.0329558309 0.17531962 +#> 74 vNa1_5 new_parameters 1 74 0.0691105866 0.06830554 +#> 75 vNa2_5 new_parameters 1 75 -0.0541634887 0.18906937 +#> 76 vNa0_7 new_parameters 1 76 -1.0160612343 0.20635638 +#> 77 vNa1_7 new_parameters 1 77 0.0793410921 0.07893334 +#> 78 vNa2_7 new_parameters 1 78 0.2789485894 0.22287341 +#> 79 vNa0_9 new_parameters 1 79 -0.2587533897 0.17904848 +#> 80 vNa1_9 new_parameters 1 80 0.1619891836 0.07162976 +#> 81 vNa2_9 new_parameters 1 81 -0.2160735722 0.19344063 +#> 82 vNa0_12 new_parameters 1 82 -0.0164029315 0.17729436 +#> 83 vNa1_12 new_parameters 1 83 -0.0209998036 0.07046769 +#> 84 vNa2_12 new_parameters 1 84 -0.1532819223 0.19241813 +#> 85 vNa0_13 new_parameters 1 85 -2.0960702046 0.48764485 +#> 86 vNa1_13 new_parameters 1 86 -0.1933346065 0.09005244 +#> 87 vNa2_13 new_parameters 1 87 1.1069581616 0.49511747 ! +#> 88 iSi0_1 new_parameters 1 88 0.9952882447 0.13531678 +#> 89 iSi1_1 new_parameters 1 89 -0.1033698432 0.04990618 +#> 90 iSi2_1 new_parameters 1 90 0.3313792976 0.14486821 +#> 91 iSi0_3 new_parameters 1 91 1.7153301594 0.15882131 +#> 92 iSi1_3 new_parameters 1 92 -0.0212118700 0.05376226 +#> 93 iSi2_3 new_parameters 1 93 0.1107780411 0.16873339 +#> 94 iSi0_6 new_parameters 1 94 1.3003161822 0.16241184 +#> 95 iSi1_6 new_parameters 1 95 -0.0662085248 0.04953397 +#> 96 iSi2_6 new_parameters 1 96 -0.0985231564 0.17029509 +#> 97 iSi0_8 new_parameters 1 97 1.2459902378 0.15344866 +#> 98 iSi1_8 new_parameters 1 98 -0.0384614530 0.05215684 +#> 99 iSi2_8 new_parameters 1 99 0.0272620714 0.16303817 +#> 100 iSi0_10 new_parameters 1 100 1.2622340899 0.16982847 +#> 101 iSi1_10 new_parameters 1 101 -0.0522932418 0.05638036 +#> 102 iSi2_10 new_parameters 1 102 0.2239994196 0.17980240 +#> 103 iSi0_11 new_parameters 1 103 1.3729267192 0.14277081 +#> 104 iSi1_11 new_parameters 1 104 0.0040182174 0.04931093 +#> 105 iSi2_11 new_parameters 1 105 0.2206742243 0.15169650 +#> 106 iSi0_14 new_parameters 1 106 1.2037219787 0.12879249 +#> 107 iSi1_14 new_parameters 1 107 0.0151275075 0.04845845 +#> 108 iSi2_14 new_parameters 1 108 -0.0330127497 0.13896479 +#> 109 iNa0_2 new_parameters 1 109 2.3325064450 0.16097657 +#> 110 iNa1_2 new_parameters 1 110 -0.0846593860 0.05642019 +#> 111 iNa2_2 new_parameters 1 111 -0.5228700906 0.17168038 +#> 112 iNa0_4 new_parameters 1 112 1.2264649066 0.15542294 +#> 113 iNa1_4 new_parameters 1 113 -0.1588700333 0.04639092 +#> 114 iNa2_4 new_parameters 1 114 -0.3757878233 0.16264619 +#> 115 iNa0_5 new_parameters 1 115 1.7177420528 0.14292380 +#> 116 iNa1_5 new_parameters 1 116 -0.1539340834 0.05332530 +#> 117 iNa2_5 new_parameters 1 117 -0.0524636694 0.15367092 +#> 118 iNa0_7 new_parameters 1 118 1.2867668224 0.15118486 +#> 119 iNa1_7 new_parameters 1 119 -0.1371967464 0.04985913 +#> 120 iNa2_7 new_parameters 1 120 -0.3688511958 0.15999312 +#> 121 iNa0_9 new_parameters 1 121 1.1235341187 0.14007640 +#> 122 iNa1_9 new_parameters 1 122 -0.0732935616 0.04481360 +#> 123 iNa2_9 new_parameters 1 123 -0.2102908281 0.14786186 +#> 124 iNa0_12 new_parameters 1 124 2.5622357820 0.15684363 +#> 125 iNa1_12 new_parameters 1 125 -0.2614878020 0.05576601 +#> 126 iNa2_12 new_parameters 1 126 -0.8435588012 0.16748883 +#> 127 iNa0_13 new_parameters 1 127 1.3901921017 0.16530797 +#> 128 iNa1_13 new_parameters 1 128 -0.1506084353 0.04603598 +#> 129 iNa2_13 new_parameters 1 129 -0.5924378266 0.17173327 +#> +#> Model Statistics: +#> | Parameters | Degrees of Freedom | Fit (-2lnL units) +#> Model: 129 7435 20762.43 +#> Saturated: 119 7445 NA +#> Independence: 28 7536 NA +#> Number of observations/statistics: 541/7564 +#> +#> Information Criteria: +#> | df Penalty | Parameters Penalty | Sample-Size Adjusted +#> AIC: 5892.426 21020.43 21102.03 +#> BIC: -26029.146 21574.28 21164.78 +#> CFI: NA +#> TLI: 1 (also known as NNFI) +#> RMSEA: 0 [95% CI (NA, NA)] +#> Prob(RMSEA <= 0.05): NA +#> To get additional fit indices, see help(mxRefModels) +#> timestamp: 2024-07-27 22:22:32 +#> Wall clock time: 506.5577 secs +#> optimizer: SLSQP +#> OpenMx version number: 2.21.11 +#> Need help? See help(mxSummary) +``` +
+ +Checking the regression coefficients `lSi1_1`, `lSi1_2`, ... will tell us if +there is a linear change across age or if individuals with `Male = 0` differ +from individuals with `Male = 1`. + +## Plotting Individual Parameters + +MNLFA predicts individual parameter values (e.g., `lSi_1`) using definition +variables. To get a better picture of the individual parameters, **mxsem** +provides the `get_individual_algebra_results` function. This function will compute +for each algebra the individual parameters. Depending on the sample size and +the number of algebras in the model, this may take some time. Therefore, we will +only extract the individual parameter values for `lSi_1` as an example. + + +```r +lSi_1 <- get_individual_algebra_results(mxModel = mnlfa_model, + algebra_names = "lSi_1", + progress_bar = FALSE) +head(lSi_1$lSi_1) +#> person Age Male algebra_result +#> 1 1 0.03136864 1 0.8699212 +#> 2 2 -0.44266587 1 0.9246368 +#> 3 3 -0.82189349 1 0.9684093 +#> 4 4 -0.63227968 1 0.9465231 +#> 5 5 0.03136864 1 0.8699212 +#> 6 6 -0.06343826 0 0.7408356 +``` + +The function will return a list with data frames for all requested algebras. Here, +the list has only one element: `lSi_1`. The data frame will have fields for the +person, the definition variables used in the algebra (`Age` and `Male` in this case) +and the person specific parameter (`algebra_result`). We can plot these results +as follows: + + +```r +library(ggplot2) +ggplot(data = lSi_1$lSi_1, + aes(x = Age, + y = algebra_result, + color = factor(Male))) + + ylab("Individual Parameter Value for lSi_1") + + geom_point() +``` + + +![](figures/mnlfa_lS_1.png) + +## References diff --git a/vignettes/figures/mnlfa_lS_1.png b/vignettes/figures/mnlfa_lS_1.png index a7c1538..2cc6e70 100644 Binary files a/vignettes/figures/mnlfa_lS_1.png and b/vignettes/figures/mnlfa_lS_1.png differ