Skip to contents
library(modsem)
#> This is modsem (1.0.20). Please report any bugs!
set.seed(2938472)

modsem implements a Monte-Carlo correction for LMS and QML models with ordinal data. Here we refer to these informally as MC-LMS-ORD and MC-QML-ORD.

The MC-LMS-ORD and MC-QML-ORD algorithms are based on Slupphaug, Mehmetoglu, and Mittner (2026) For a more direct implementation of the original algorithm, we recommend checking out the plssem package.

Example

Here we ordinalize the data in the oneInt dataset.

ordinalize <- function(x, probs = c(0, 0.35, 0.7, 1)) {
  x <- (x - mean(x)) / sd(x)
  cut(
    x,
    breaks = stats::quantile(x, probs = probs),
    include.lowest = TRUE,
    ordered_result = TRUE
  )
}

oneIntOrd <- as.data.frame(lapply(oneInt, ordinalize))

Now we can estimate our model, indicating which variables are ordinal, using the ordered= argument.

model <- "
  X =~ x1 + x2 + x3
  Z =~ z1 + z2 + z3
  Y =~ y1 + y2 + y3

  Y ~ X + Z + X:Z
"

fit_lms_ord <- modsem(
  model,
  data = oneIntOrd,
  method = "lms",
  ordered = colnames(oneIntOrd)
)

summary(fit_lms_ord)
#> 
#> modsem (1.0.20) ended normally after 81 iterations
#> 
#>   Estimator                                     MC-LMS
#>   Optimization method                    ROBBINS-MONRO
#>   Naive optimization method                 EMA-NLMINB
#>   Number of model parameters                        13
#> 
#>   Number of observations                          2000
#> 
#> Naive Loglikelihood and Information Criteria:
#>   Naive Loglikelihood                        -19223.44
#>   Naive Akaike (AIC)                          38472.87
#>   Naive Bayesian (BIC)                        38545.68
#>  
#> Numerical Integration:
#>   Points of integration (per dim)                   24
#>   Dimensions                                         1
#>   Total points of integration                       24
#> 
#> Fit Measures for Baseline Model (H0):
#>                                               Standard
#>   Chi-square                                     54.26
#>   Degrees of Freedom (Chi-square)                   33
#>   P-value (Chi-square)                           0.011
#>   RMSEA                                          0.018
#>                                                       
#>   Naive Loglikelihood                        -19343.47
#>   Naive Akaike (AIC)                          38710.94
#>   Naive Bayesian (BIC)                        38778.15
#>  
#> Comparative Fit to H0 (LRT test):
#>   Loglikelihood change                          120.04
#>   Difference test (D)                           240.07
#>   Degrees of freedom (D)                             1
#>   P-value (D)                                    0.000
#>  
#> 
#> Parameter Estimates:
#>   Coefficients                            standardized
#>   Information                                 observed
#>   Standard errors                            penalized
#>  
#> Latent Variables:
#>                  Estimate  Std.Error  z.value  P(>|z|)
#>   X =~          
#>     x1              0.933      0.061   15.176    0.000
#>     x2              0.900      0.064   14.030    0.000
#>     x3              0.918      0.061   15.156    0.000
#>   Z =~          
#>     z1              0.920      0.062   14.888    0.000
#>     z2              0.905      0.063   14.321    0.000
#>     z3              0.909      0.062   14.598    0.000
#>   Y =~          
#>     y1              0.975      0.057   17.212    0.000
#>     y2              0.958      0.066   14.511    0.000
#>     y3              0.965      0.062   15.529    0.000
#> 
#> Regressions:
#>                  Estimate  Std.Error  z.value  P(>|z|)
#>   Y ~           
#>     X               0.433      0.044    9.838    0.000
#>     Z               0.382      0.037   10.265    0.000
#>     X:Z             0.484      0.152    3.176    0.001
#> 
#> Covariances:
#>                  Estimate  Std.Error  z.value  P(>|z|)
#>   X ~~          
#>     Z               0.197      0.035    5.664    0.000
#> 
#> Thresholds:
#>                  Estimate  Std.Error  z.value  P(>|z|)
#>     x1|t1          -0.385                             
#>     x1|t2           0.524                             
#>     x2|t1          -0.385                             
#>     x2|t2           0.524                             
#>     x3|t1          -0.385                             
#>     x3|t2           0.524                             
#>     z1|t1          -0.385                             
#>     z1|t2           0.524                             
#>     z2|t1          -0.385                             
#>     z2|t2           0.524                             
#>     z3|t1          -0.385                             
#>     z3|t2           0.524                             
#>     y1|t1          -0.385                             
#>     y1|t2           0.524                             
#>     y2|t1          -0.385                             
#>     y2|t2           0.524                             
#>     y3|t1          -0.385                             
#>     y3|t2           0.524                             
#> 
#> Variances:
#>                  Estimate  Std.Error  z.value  P(>|z|)
#>    .x1              0.129                             
#>    .x2              0.191                             
#>    .x3              0.158                             
#>    .z1              0.154                             
#>    .z2              0.181                             
#>    .z3              0.174                             
#>    .y1              0.049                             
#>    .y2              0.083                             
#>    .y3              0.068                             
#>     X               1.000                             
#>     Z               1.000                             
#>    .Y               0.367