| three_step | R Documentation |
Fits a three-step latent class model through the following steps:
Measurement model: estimates latent class parameters
(\pi, \phi) using multilevLCA
(Lyrvall et al., 2025).
Classification-error matrix: computes posterior class
probabilities and the T x T misclassification probability matrix
P(W = s \mid X = t), with standard errors corrected for
classification-error propagation (Bakk, Oberski & Vermunt, 2014).
Structural model: estimates covariate effects using
two-step starting values (Bakk & Kuha, 2018) and/or distal outcome
means following Bakk, Tekle & Vermunt (2013), with the ML correction (Vermunt, 2010) or BCH correction
(Bolck, Croon & Hagenaars, 2004). See
vignette("tseLCA", package = "tseLCA") for a worked example.
three_step(
data,
Y.names,
n_classes,
Zp.names = NULL,
Zo.name = NULL,
step1 = NULL,
startval = NULL,
n_init = NULL,
use.two.step = TRUE,
use.modal.assignment = TRUE,
include.intercept = TRUE,
use.simple.cov = FALSE,
incomplete = FALSE,
boundary.tol = 0.01,
maxIter.measurement = 5000,
measurement.tol = 1e-08,
covariate.tol = 1e-06,
iter.measurement = 10L,
R2.threshold = 0.7,
use.bch = FALSE,
em.maxIter = 200L,
get.twostep.vcov = FALSE,
rebase = "C1",
family = "gaussian",
correct.spec = FALSE,
verbose = FALSE
)
data |
A data.frame containing all columns referenced by |
Y.names |
Character vector of indicator column names. Indicators
may be factors, logicals, character, or numeric codes (see |
n_classes |
Integer. Number of latent classes. |
Zp.names |
Character vector of covariate column names, or |
Zo.name |
Single character name of the distal outcome column, or
|
step1 |
Pre-fitted Step-1 object (output of |
startval |
Optional starting classification for the Step-1
measurement model, either an integer vector of length |
n_init |
Optional positive integer. If supplied, fits the Step-1
measurement model |
use.two.step |
Logical. Initialize Step-3 from two-step estimates.
Default |
use.modal.assignment |
Logical. Use modal (hard) class assignments in
Step 2 and 3. |
include.intercept |
Logical. Prepend an intercept column to the
covariate design matrix. Default |
use.simple.cov |
Logical. Skip the Step-1 measurement-uncertainty
correction and return only the robust sandwich variance. Faster but
underestimates standard errors when class separation is low. Default
|
incomplete |
Logical. FIML for partially missing indicators. See the
|
boundary.tol |
Scalar. Parameters within this tolerance of 0 or 1 are
treated as fixed when computing the Step-1 variance matrix for numerical stability. Default
|
maxIter.measurement |
Integer. Maximum EM iterations for Step 1.
Default |
measurement.tol |
Scalar. Convergence tolerance for the Step-1 EM
algorithm. Default |
covariate.tol |
Scalar. Convergence tolerance for the Step-3
Newton-Raphson or EM algorithm. Default |
iter.measurement |
Integer. Number of random restarts triggered when
the Step-1 entropy R |
R2.threshold |
Scalar. Entropy R |
use.bch |
Logical. Use the BCH estimator in Step 3 (default: the ML
estimator). May error if BCH weights induce a non-positive semi-definite Hessian in the third step (common in cases of low separation). Default |
em.maxIter |
Integer. Maximum EM iterations for the Step-3 covariate
or distal outcome model. Default |
get.twostep.vcov |
Logical. If |
rebase |
Character (e.g. |
family |
Character. Distal outcome family: one of |
correct.spec |
Logical. Estimate the Step-3 information matrix by the
outer product of the case-wise scores, not the observed-data Hessian.
Valid only when the Step-3 model is correctly specified; the default
observed-Hessian sandwich is robust to misspecification. Default
|
verbose |
Logical. Print convergence messages. Default |
An S3 object of class tseLCA. The subclass depends on which
models were estimated:
tseLCA_measurementReturned when neither Zp.names nor
Zo.name is supplied. Contains the following elements:
measurement_modelStep-1 output list from lca_step1().
llikFinal Step-1 log-likelihood.
AIC, BICInformation criteria from the measurement model.
R2entrEntropy R^2 of the measurement model.
n_classesNumber of latent classes.
posteriorsn x T matrix of soft posterior class probabilities.
classificationsLength-n integer vector of modal class assignments.
tseLCA_covariateReturned when Zp.names is supplied and
Zo.name is NULL. Contains all elements of
tseLCA_measurement plus:
three_step(Q+1) x (T-1) matrix of Step-3 gamma coefficients.
three_step_vcov(Q+1)(T-1) x (Q+1)(T-1) variance-covariance matrix
for three_step, with measurement-uncertainty correction
unless use.simple.cov = TRUE.
two_step(Q+1) x (T-1) matrix of two-step starting values, or
NULL if use.two.step = FALSE.
two_step_vcovmultilevLCA bias-corrected vcov for the
two-step estimates, or NULL.
estimatorCharacter: "ML" or "BCH".
entropy.R2Covariate-adjusted entropy R^2.
llikProfile log-likelihood
\sum_i \log \sum_t P(X=t|Z_{p,i};\hat{\gamma}) P(Y_i|X=t;\hat{\phi}),
with Step-1 parameters \hat{\phi} held fixed. By construction
smaller than the equivalent one-step MLE likelihood.
tseLCA_distalReturned when Zo.name is supplied and
Zp.names is NULL. Contains:
three_stepNamed length-T vector of Step-3 distal outcome
parameters (means, log-rates, or logits depending on
family) – or, for family = "multinomial", a
T x C matrix of class-conditional category probabilities
(rows sum to 1).
three_step_vcovT x T variance-covariance matrix for
three_step, named mu_C1 through mu_CT –
or, for family = "multinomial", a (T*C) x (T*C)
(necessarily rank-deficient) matrix named "C{t}:{category}".
three_step.llikStep-3 distal log-likelihood
\log P(Z_o|X=t) at converged estimates.
llikProfile log-likelihood
\sum_i \log \sum_t P(X=t|\hat{\pi}) P(Z_{o,i}|X=t;\hat{\mu}) P(Y_i|X=t;\hat{\phi}),
with Step-1 parameters \hat{\pi}, \hat{\phi} held fixed.
By construction smaller than the equivalent one-step MLE likelihood.
AICAkaike information criterion based on llik.
BICBayesian information criterion based on llik,
using the number of distal-complete observations.
familyCharacter. The distal outcome family used.
estimatorCharacter: "ML" or "BCH".
posteriorsn x T soft posterior matrix.
classificationsLength-n modal class assignment vector.
tseLCA_bothReturned when both Zp.names and
Zo.name are supplied. Contains:
covariateA tseLCA_covariate-structured sub-list
(see above), including llik, AIC, BIC,
entropy.R2.
distalA tseLCA_distal-structured sub-list
(see above), including llik, AIC, BIC,
three_step.llik.
family, n_classes, estimatorShared top-level fields.
posteriors, classificationsShared n x T posterior matrix and length-n modal class vector.
Deprecated as of tseLCA 2.0.0. It keeps working (and gives the same
estimates) but warns once per session; set
options(tseLCA.warn.deprecated = FALSE) to silence the warning. Use
tseLCA() or the step-wise functions:
three_step() | tseLCA 2.0 |
Y.names, n_classes | tse_lca(cbind(...) ~ 1, nclass = ) |
Zp.names | tse_covariate(, ~ ...) or tseLCA(... ~ covariates) |
Zo.name, family | tse_distal(, outcome ~ 1, family = ), or tseLCA() with the outcome after the bar |
step1 (measurement model from another sample) | tse_classify(, newdata = ) |
startval | tse_lca(start = ) |
use.modal.assignment | tse_classify(assignment = ) |
use.bch | method = "BCH" |
use.simple.cov | se = "robust" |
rebase | ref argument, or relevel() |
incomplete | tse_lca(missing = "fiml") |
n_init, maxIter.measurement, measurement.tol, iter.measurement, R2.threshold, em.maxIter, covariate.tol, boundary.tol, correct.spec | tse_control() |
get.twostep.vcov | tse_twostep(se = TRUE) |
Bakk, Z., Tekle, F. B., & Vermunt, J. K. (2013). Estimating the association between latent class membership and external variables using bias-adjusted three-step approaches. Sociological Methodology, 43(1), 272–311. \Sexpr[results=rd]{tools:::Rd_expr_doi("10.1177/0081175012470644")}
Bakk, Z., & Kuha, J. (2018). Two-step estimation of models between latent classes and external variables. Psychometrika, 83(4), 871–892. \Sexpr[results=rd]{tools:::Rd_expr_doi("10.1007/s11336-017-9592-7")}
Bakk, Z., Pohle, M. J., & Kuha, J. (2025). Bias-adjusted three-step estimation of structural models for latent classes. Multivariate Behavioral Research. \Sexpr[results=rd]{tools:::Rd_expr_doi("10.1080/00273171.2025.2473935")}
vignette("tseLCA", package = "tseLCA") for a full worked
example; lca_step1() for standalone Step-1 estimation
(including from an externally supplied starting classification, with its
own startval argument); fitZ_from_fit0() and fitZ_from_multiLCA()
for two-step covariate estimation.
d <- generate_data(n = 200, separation = "high",
scenario = "covariate", seed = 1)
# Measurement model only
fit_m <- three_step(d, Y.names = paste0("Y", 1:6), n_classes = 3)
summary(fit_m)
# ML three-step with simple SEs (fast)
fit <- three_step(d, Y.names = paste0("Y", 1:6), n_classes = 3,
Zp.names = "Zp", use.simple.cov = TRUE)
summary(fit)
coef(fit)
vcov(fit)
# Full measurement-uncertainty correction (see vignette for interpretation)
fit_cor <- three_step(d, Y.names = paste0("Y", 1:6), n_classes = 3,
Zp.names = "Zp", use.simple.cov = FALSE,
use.modal.assignment = FALSE)
summary(fit_cor)
# BCH estimator
fit_bch <- three_step(d, Y.names = paste0("Y", 1:6), n_classes = 3,
Zp.names = "Zp", use.bch = TRUE,
use.simple.cov = TRUE)
summary(fit_bch)
# Change reference class
fit_c2 <- three_step(d, Y.names = paste0("Y", 1:6), n_classes = 3,
Zp.names = "Zp", use.simple.cov = TRUE,
rebase = "C2")
summary(fit_c2)
# Gaussian distal outcome
d2 <- generate_data(200, "high", "distal", seed = 2)
fit_dis <- three_step(d2, Y.names = paste0("Y", 1:6), n_classes = 3,
Zo.name = "Zo", family = "gaussian",
use.simple.cov = TRUE)
summary(fit_dis)
# Nominal categorical distal outcome (3+ categories): coef() returns a
# T x C matrix of class-conditional category probabilities; omnibus_test()
# gives a single Wald test of whether the category distribution differs
# across classes at all.
d2$Zcat <- factor(sample(c("low", "mid", "high"), nrow(d2), replace = TRUE))
fit_cat <- three_step(d2, Y.names = paste0("Y", 1:6), n_classes = 3,
Zo.name = "Zcat", family = "multinomial",
use.simple.cov = TRUE)
coef(fit_cat)
omnibus_test(fit_cat)
# Pass a pre-fitted measurement model to skip Step 1
fit_step1 <- three_step(d, Y.names = paste0("Y", 1:6), n_classes = 3)
fit2 <- three_step(d, Y.names = paste0("Y", 1:6), n_classes = 3,
Zp.names = "Zp", step1 = fit_step1,
use.simple.cov = TRUE)
summary(fit2)
# Supply an external starting classification for Step 1 (bypasses
# multilevLCA's k-means-on-PCA initialization; here we use the DGP's own
# true classes as a stand-in for e.g. a StepMix solution with many
# random starts)
fit_ext <- three_step(d, Y.names = paste0("Y", 1:6), n_classes = 3,
startval = d$X, use.simple.cov = TRUE)
summary(fit_ext)
# Many random-classification restarts for Step 1, keeping the best
# (analogous to n_init in StepMix or nrep in poLCA)
fit_ninit <- three_step(d, Y.names = paste0("Y", 1:6), n_classes = 3,
n_init = 20L, use.simple.cov = TRUE)
summary(fit_ninit)
# Plot item-response profiles from the measurement model
plot(fit)
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.