% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/modsem_da.R
\name{modsem_da}
\alias{modsem_da}
\title{Interaction between latent variables using LMS and QML approaches}
\usage{
modsem_da(
  model.syntax = NULL,
  data = NULL,
  group = NULL,
  method = "lms",
  verbose = NULL,
  optimize = NULL,
  nodes = NULL,
  missing = NULL,
  convergence.abs = NULL,
  convergence.rel = NULL,
  optimizer = NULL,
  center.data = NULL,
  standardize.data = NULL,
  standardize.out = NULL,
  standardize = NULL,
  mean.observed = NULL,
  cov.syntax = NULL,
  double = NULL,
  calc.se = NULL,
  FIM = NULL,
  EFIM.S = NULL,
  OFIM.hessian = NULL,
  EFIM.parametric = NULL,
  robust.se = NULL,
  R.max = NULL,
  max.iter = NULL,
  max.step = NULL,
  start = NULL,
  epsilon = NULL,
  quad.range = NULL,
  adaptive.quad = NULL,
  adaptive.frequency = NULL,
  adaptive.quad.tol = NULL,
  n.threads = NULL,
  algorithm = NULL,
  em.control = NULL,
  ordered = NULL,
  ordered.mc.reps = NULL,
  ordered.min.iter = 20L,
  ordered.max.iter = 250L,
  ordered.tol = 1e-04,
  ordered.rng.seed = NULL,
  ordered.fixed.seed = FALSE,
  ordered.polyak.juditsky = TRUE,
  ordered.pj.extrapolate = TRUE,
  ordered.se = c("delta", "penalized", "naive"),
  ordered.se.penalty = 0.25,
  ordered.delta.reps = NULL,
  ordered.delta.epsilon = 0.01,
  ordered.standardize = TRUE,
  cluster = NULL,
  cr1s = FALSE,
  sampling.weights = NULL,
  sampling.weights.normalization = NULL,
  rcs = FALSE,
  rcs.choose = NULL,
  rcs.scale.corrected = TRUE,
  orthogonal.x = NULL,
  orthogonal.y = NULL,
  auto.fix.first = NULL,
  auto.fix.single = NULL,
  auto.split.syntax = NULL,
  fix.composite.var = NULL,
  ...
)
}
\arguments{
\item{model.syntax}{\code{lavaan} syntax}

\item{data}{A dataframe with observed variables used in the model.}

\item{group}{Character. A variable name in the data frame defining the groups in a multiple
group analysis}

\item{method}{method to use:
\describe{
  \item{\code{"lms"}}{latent moderated structural equations (not passed to \code{lavaan}).}
  \item{\code{"qml"}}{quasi maximum likelihood estimation (not passed to \code{lavaan}).}
}}

\item{verbose}{should estimation progress be shown}

\item{optimize}{should starting parameters be optimized}

\item{nodes}{number of quadrature nodes (points of integration) used in \code{lms},
increased number gives better estimates but slower computation. How many are needed depends on the complexity of the model.
For simple models, somewhere between 16-24 nodes should be enough; for more complex models, higher numbers may be needed.
For models where there is an interaction effect between an endogenous and exogenous variable,
the number of nodes should be at least 32, but practically (e.g., ordinal/skewed data), more than 32 is recommended. In cases
where data is non-normal, it might be better to use the \code{qml} approach instead.
You can also consider setting \code{adaptive.quad = TRUE}.}

\item{missing}{How should missing values be handled? If \code{"listwise"} (default) missing values
are removed list-wise (alias: \code{"complete"} or \code{"casewise"}).
If \code{impute} values are imputed using \code{Amelia::amelia}.
If \code{"fiml"} (alias: \code{"ml"} or \code{"direct"}), full information maximum
likelihood (FIML) is used. FIML can be (very) computationally intensive.}

\item{convergence.abs}{Absolute convergence criterion.
Lower values give better estimates but slower computation. Not relevant when
using the QML approach. For the LMS approach the EM-algorithm stops whenever
the relative or absolute convergence criterion is reached.}

\item{convergence.rel}{Relative convergence criterion.
Lower values give better estimates but slower computation.
For the LMS approach the EM-algorithm stops whenever
the relative or absolute convergence criterion is reached.}

\item{optimizer}{optimizer to use, can be either \code{"nlminb"} or \code{"L-BFGS-B"}. For LMS, \code{"nlminb"} is recommended.
For QML, \code{"L-BFGS-B"} may be faster if there is a large number of iterations, but slower if there are few iterations.}

\item{center.data}{should data be centered before fitting model}

\item{standardize.data}{should data be scaled before fitting model, will be overridden by
\code{standardize} if \code{standardize} is set to \code{TRUE}.}

\item{standardize.out}{should output be standardized (note will alter the relationships of
  parameter constraints since parameters are scaled unevenly, even if they
  have the same label). This does not alter the estimation of the model, only the
  output.

\strong{NOTE}: It is recommended that you estimate the model normally and then standardize the output using
\code{\link{standardize_model}}, \code{\link{standardized_estimates}} or \code{summary(<modsem_da-object>, standardize=TRUE)}.}

\item{standardize}{will standardize the data before fitting the model, remove the mean
  structure of the observed variables, and standardize the output. Note that \code{standardize.data},
  \code{mean.observed}, and \code{standardize.out} will be overridden by \code{standardize} if \code{standardize} is set to \code{TRUE}.

\strong{NOTE}: It is recommended that you estimate the model normally and then standardize the output using
  \code{\link{standardized_estimates}}.}

\item{mean.observed}{should the mean structure of the observed variables be estimated?
  This will be overridden by \code{standardize}, if \code{standardize} is set to \code{TRUE}.

\strong{NOTE}: Not recommended unless you know what you are doing.}

\item{cov.syntax}{model syntax for implied covariance matrix of exogenous latent variables
(see \code{vignette("interaction_two_etas", "modsem")}).}

\item{double}{try to double the number of dimensions of integration used in LMS,
this will be extremely slow but should be more similar to \code{mplus}.}

\item{calc.se}{should standard errors be computed? \strong{NOTE}: If \code{FALSE}, the information matrix will not be computed either.}

\item{FIM}{should the Fisher information matrix be calculated using the observed or expected values? Must be either \code{"observed"} or \code{"expected"}.}

\item{EFIM.S}{if the expected Fisher information matrix is computed, \code{EFIM.S} selects the number of Monte Carlo samples. Defaults to 100.
\strong{NOTE}: This number should likely be increased for better estimates (e.g., 1000), but it might drasticly increase computation time.}

\item{OFIM.hessian}{Logical. If \code{TRUE} (default), standard errors are
  based on the negative Hessian (observed Fisher information).
  If \code{FALSE}, they come from the outer product
  of individual score vectors (OPG). For correctly specified models,
  these two matrices are asymptotically equivalent; yielding nearly identical
  standard errors in large samples. The Hessian usually shows smaller finite-sample
  variance (i.e., it's more consistent), and is therefore the default.

  Note, that the Hessian is not always positive definite, and is more computationally
  expensive to calculate. The OPG should always be positive definite, and a lot
  faster to compute. If the model is correctly specified, and the sample size is large,
  then the two should yield similar results, and switching to the OPG can save a
  lot of time. Note, that the required sample size depends on the complexity of the model.

  A large difference between Hessian and OPG suggests misspecification, and
  \code{robust.se = TRUE} should be set to obtain sandwich (robust) standard errors.}

\item{EFIM.parametric}{should data for calculating the expected Fisher information matrix be
simulated parametrically (simulated based on the assumptions and implied parameters
from the model), or non-parametrically (stochastically sampled)? If you believe that
normality assumptions are violated, \code{EFIM.parametric = FALSE} might be the better option.}

\item{robust.se}{should robust standard errors be computed, using the sandwich estimator?}

\item{R.max}{Maximum population size (not sample size) used in the calculated of the expected
fischer information matrix.}

\item{max.iter}{maximum number of iterations.}

\item{max.step}{maximum steps for the M-step in the EM algorithm (LMS).}

\item{start}{starting parameters.}

\item{epsilon}{finite difference for numerical derivatives.}

\item{quad.range}{range in z-scores to perform numerical integration in LMS using,
when using quasi-adaptive Gaussian-Hermite Quadratures. By default \code{Inf}, such that \code{f(t)} is integrated from -Inf to Inf,
but this will likely be inefficient and pointless at a large number of nodes. Nodes outside
\code{+/- quad.range} will be ignored.}

\item{adaptive.quad}{should a quasi adaptive quadrature be used? If \code{TRUE}, the quadrature nodes will be adapted to the data.
If \code{FALSE}, the quadrature nodes will be fixed. Default is \code{FALSE}. The adaptive quadrature does not fit an adaptive
quadrature to each participant, but instead tries to place more nodes where posterior distribution is highest. Compared with a
fixed Gauss Hermite quadrature this usually means that less nodes are placed at the tails of the distribution.}

\item{adaptive.frequency}{How often should the quasi-adaptive quadrature be calculated? Defaults to 3, meaning
that it is recalculated every third EM-iteration.}

\item{adaptive.quad.tol}{Relative error tolerance for quasi adaptive quadrature. Defaults to \code{1e-12}.}

\item{n.threads}{number of threads to use for parallel processing. If \code{NULL}, it will use <= 2 threads.
If an integer is specified, it will use that number of threads (e.g., \code{n.threads = 4} will use 4 threads).
If \code{"default"}, it will use the default number of threads (2).
If \code{"max"}, it will use all available threads, \code{"min"} will use 1 thread.}

\item{algorithm}{algorithm to use for the EM algorithm. Can be either \code{"EM"} or \code{"EMA"}.
\code{"EM"} is the standard EM algorithm. \code{"EMA"} is an
accelerated EM procedure that uses Quasi-Newton and Fisher Scoring
optimization steps when needed. Default is \code{"EM"}.}

\item{em.control}{a list of control parameters for the EM algorithm. See \code{\link{default_settings_da}} for defaults.}

\item{ordered}{Variables to be treated as ordered. Ordered indicators are handled
  with a Monte-Carlo correction for the LMS/QML estimator on standardized category
  scores. The fitted model is used to repeatedly simulate continuous indicators,
  ordinalize them to the observed cumulative category proportions, refit the
  standardized LMS/QML working model, and solve the resulting fixed-point problem.
  This follows the same general Monte-Carlo consistency logic as the MC-OrdPLSc
  algorithm described by Slupphaug, Mehmetoglu, and Mittner (2026,
  \doi{10.31234/osf.io/fwzj6_v1}).

  Thresholds are currently treated as fixed calibration quantities derived from the
  observed marginal category proportions. They are reported in the output for
  transparency, but they are not part of the free Monte-Carlo state vector.}

\item{ordered.mc.reps}{Integer. Monte-Carlo sample size used in each ordered MC
correction step. Larger values reduce simulation noise but increase runtime.}

\item{ordered.min.iter}{Integer. Minimum number of Robbins-Monro iterations for the
ordered MC correction.}

\item{ordered.max.iter}{Integer. Maximum number of Robbins-Monro iterations for the
ordered MC correction.}

\item{ordered.tol}{Convergence tolerance for the ordered MC Robbins-Monro updates.}

\item{ordered.rng.seed}{Optional integer random seed used by the ordered MC
correction.}

\item{ordered.fixed.seed}{Logical. If \code{TRUE} and \code{ordered.rng.seed = NULL},
a fixed seed is drawn once and reused throughout the ordered MC correction to
improve numerical stability.}

\item{ordered.polyak.juditsky}{Logical. Should Polyak-Juditsky averaging be used in
the ordered MC Robbins-Monro solver?}

\item{ordered.pj.extrapolate}{Logical. If \code{TRUE}, use extrapolation of the
Polyak-Juditsky path to estimate the convergence point. If \code{FALSE}, the
averaged iterate is used directly.}

\item{ordered.se}{Character string selecting the ordered MC standard-error correction.
\code{"delta"} (default) uses the delta method.
\code{"penalty"} uses a conservative variance inflation
based on the discrepancy between the naive and MC-corrected standardized estimates.
\code{"naive"} uses the fast diagonal rescaling approximation, and}

\item{ordered.se.penalty}{Non-negative numeric multiplier used when
\code{ordered.se = "penalized"}. The penalty adds
\code{ordered.se.penalty * (theta_mc - theta_naive)^2} to the diagonal of the
naive covariance matrix on the variance scale.}

\item{ordered.delta.reps}{Integer. Monte-Carlo sample size used when approximating
the ordered MC delta-method Jacobian. Only relevant if
\code{ordered.se = "delta"}.}

\item{ordered.delta.epsilon}{Finite-difference step size used for the ordered MC
delta-method Jacobian. Only relevant if \code{ordered.se = "delta"}.}

\item{ordered.standardize}{Logical. Should scored ordered indicators be standardized
before the observed-data fit and after ordinalizing simulated indicators? This is
recommended for numerical stability and is enabled by default.}

\item{cluster}{Clusters used to compute standard errors robust to non-indepence of observations. Must be paired with
\code{robust.se = TRUE}.}

\item{cr1s}{Logical; if \code{TRUE}, apply the CR1S small-sample correction factor
to the cluster-robust variance estimator. The CR1S factor is
\eqn{(G / (G - 1)) \cdot ((N - 1) / (N - q))}, where \eqn{G} is the number of
clusters, \eqn{N} is the total number of observations, and \eqn{q} is the number
of free parameters. This adjustment inflates standard errors to reduce the
small-sample downward bias present in the basic cluster-robust (CR0) estimator,
especially when \eqn{G} is small. If \code{FALSE}, the unadjusted CR0 estimator
is used. Defaults to \code{TRUE}. Only relevant if \code{cluster} is specified.}

\item{sampling.weights}{A variable name in the data frame containing sampling weight information.
Depending on the sampling.weights.normalization argument, these weights may be rescaled (or not)
so that their sum equals the number of observations (total or per group)}

\item{sampling.weights.normalization}{If \code{"none"}, the sampling weights (if provided) will not be
transformed. If \code{"total"}, the sampling weights are normalized by dividing by the total sum
of the weights, and multiplying again by the total sample size. If \code{"group"}, the sampling
weights are normalized per group: by dividing by the sum of the weights (in each group), and
multiplying again by the group size. The default is \code{"total"}.}

\item{rcs}{Should latent variable indicators be replaced with reliability-corrected
single item indicators instead? See \code{\link{relcorr_single_item}}.}

\item{rcs.choose}{Which latent variables should get their indicators replaced with
reliability-corrected single items? It is passed to \code{\link{relcorr_single_item}}
as the \code{choose} argument.}

\item{rcs.scale.corrected}{Should reliability-corrected items be scale-corrected? If \code{TRUE}
reliability-corrected single items are corrected for differences in factor loadings between
the items. Default is \code{TRUE}.}

\item{orthogonal.x}{If \code{TRUE}, all covariances among exogenous latent variables only are set to zero.
Default is \code{FALSE}.}

\item{orthogonal.y}{If \code{TRUE}, all covariances among endogenous latent variables only are set to zero.
If \code{FALSE} residual covariances are added between pure endogenous variables;
those that are predicted by no other endogenous variable in the structural model.
Default is \code{FALSE}.}

\item{auto.fix.first}{If \code{TRUE} the factor loading of the first indicator, for
a given latent variable is fixed to \code{1}. If \code{FALSE} no loadings are fixed
(automatically). Note that that this might make it such that the model no longer is
identified. Default is \code{TRUE}. \strong{NOTE} this behaviour is overridden
if the first loading is labelled, where it gets treated as a free parameter instead. This
differs from the default behaviour in \code{lavaan}.}

\item{auto.fix.single}{If \code{TRUE}, the residual variance of
an observed indicator is set to zero if it is the only indicator of a latent variable.
If \code{FALSE} the residual variance is not fixed to zero, and treated as a free parameter
of the model. Default is \code{TRUE}. \strong{NOTE} this behaviour is overridden
if the first loading is labelled, where it gets treated as a free parameter instead.}

\item{auto.split.syntax}{Should the model syntax automatically be split into a
linear and non-linear part? This is done by moving the structural model for
linear endogenous variables (used in interaction terms) into the \code{cov.syntax}
argument. This can potentially allow interactions between two endogenous variables
given that both are linear (i.e., not affected by interaction terms). This is
\code{FALSE} by default for the LMS approach.
When using the QML approach interation effects between exogenous and endogenous
variables can in some cases be biased, if the model is not split beforehand.
The default is therefore \code{TRUE} for the QML approach.}

\item{fix.composite.var}{If \code{TRUE} (default) the block covariance structure
of composite indiactors is fixed.}

\item{...}{additional arguments to be passed to the estimation function.}
}
\value{
\code{modsem_da} object
}
\description{
\code{modsem_da()} is a function for estimating interaction effects between latent variables
in structural equation models (SEMs) using distributional analytic (DA) approaches.
Methods for estimating interaction effects in SEMs can basically be split into
two frameworks:
1. Product Indicator-based approaches (\code{"dblcent"}, \code{"rca"}, \code{"uca"},
\code{"ca"}, \code{"pind"})
2. Distributionally based approaches (\code{"lms"}, \code{"qml"}).

\code{modsem_da()} handles the latter and can estimate models using both QML and LMS,
necessary syntax, and variables for the estimation of models with latent product indicators.

\strong{NOTE}: Run \code{\link{default_settings_da}} to see default arguments.
}
\examples{
library(modsem)
# For more examples, check README and/or GitHub.
# One interaction
m1 <- "
  # Outer Model
  X =~ x1 + x2 +x3
  Y =~ y1 + y2 + y3
  Z =~ z1 + z2 + z3

  # Inner model
  Y ~ X + Z + X:Z
"

\dontrun{
# QML Approach
est_qml <- modsem_da(m1, oneInt, method = "qml")
summary(est_qml)

# Theory Of Planned Behavior
tpb <- "
# Outer Model (Based on Hagger et al., 2007)
  ATT =~ att1 + att2 + att3 + att4 + att5
  SN =~ sn1 + sn2
  PBC =~ pbc1 + pbc2 + pbc3
  INT =~ int1 + int2 + int3
  BEH =~ b1 + b2

# Inner Model (Based on Steinmetz et al., 2011)
  INT ~ ATT + SN + PBC
  BEH ~ INT + PBC
  BEH ~ INT:PBC
"

# LMS Approach
est_lms <- modsem_da(tpb, data = TPB, method = "lms")
summary(est_lms)
}
}
\references{
Slupphaug, K., Mehmetoglu, M., and Mittner, M. (2026, March 21).
\emph{Consistent Estimates from Biased Estimators: Monte-Carlo Consistent Partial
Least Squares for Latent Interaction Models with Ordinal Indicators}. PsyArXiv.
\doi{10.31234/osf.io/fwzj6_v1}
}
