| Title: | Three-Step Estimation for Latent Class Analysis |
|---|---|
| Description: | Bias-adjusted three-step estimation of latent class models with covariates and distal outcomes. The latent class measurement model is estimated first, with 'multilevLCA' (Lyrvall et al., 2025) <doi:10.1080/00273171.2025.2473935>, and held fixed; observations are then classified; and the classes are related to covariates and distal outcomes with the maximum likelihood correction of Vermunt (2010) <doi:10.1093/pan/mpq025> and Bakk, Tekle and Vermunt (2013) <doi:10.1177/0081175012470644>, or the correction of Bolck, Croon and Hagenaars (2004) <doi:10.1093/pan/mph001>. Standard errors account for the uncertainty of the measurement model (Bakk, Oberski and Vermunt, 2014) <doi:10.1093/pan/mpu003>. Includes class enumeration, modal and proportional class assignment, covariate formulas, Gaussian, Poisson, binomial, and multinomial distal outcomes, the two-step estimator of Bakk and Kuha (2018) <doi:10.1007/s11336-017-9592-7>, measurement models applied to new samples, and full-information maximum likelihood for missing indicators, standard methods for fitted models, and a data-generating process replicating the simulation design of Bakk and Kuha (2018). |
| Authors: | Sam Lee [aut, cre, cph] (ORCID: <https://orcid.org/0009-0007-2977-6661>), Jay Goodliffe [aut, cph] (ORCID: <https://orcid.org/0000-0001-8272-7235>) |
| Maintainer: | Sam Lee <[email protected]> |
| License: | GPL (>= 3) |
| Version: | 2.1.1 |
| Built: | 2026-11-01 03:42:35 UTC |
| Source: | https://github.com/cran/tseLCA |
Tests, term by term, that all multinomial-logit coefficients of a covariate term are zero (for all non-reference classes), using the model's variance matrix.
## S3 method for class 'tseLCA_covariate' anova(object, ...)## S3 method for class 'tseLCA_covariate' anova(object, ...)
object |
A |
... |
Unused. |
An anova table with the Wald statistic, degrees of freedom, and
p-value of each term.
d <- generate_data(500, "high", "covariate", seed = 1) m <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 3) anova(tse_covariate(tse_classify(m), ~ Zp))d <- generate_data(500, "high", "covariate", seed = 1) m <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 3) anova(tse_covariate(tse_classify(m), ~ Zp))
Creates a measurement model from given class sizes and item-response
probabilities, evaluated on data, without estimating it. This allows
Steps 2 and 3 to be based on a measurement model estimated elsewhere: in
another program, reported in a publication, or saved from an earlier
analysis.
as_tse_lca( formula, data, class_sizes, item_probs, vcov = NULL, missing = c("listwise", "fiml"), control = tse_control() )as_tse_lca( formula, data, class_sizes, item_probs, vcov = NULL, missing = c("listwise", "fiml"), control = tse_control() )
formula |
|
data |
A data frame. |
class_sizes |
Class proportions, one per class (they are normalized to sum to one). |
item_probs |
Item-response probabilities in the layout of
|
vcov |
Optional variance matrix of the Step-1 parameters, for
corrected standard errors in Step 3. It refers to the unconstrained
log-ratio parameters, in the layout of |
missing, control
|
As in |
Corrected standard errors in Step 3 (se = "corrected") need the
variance matrix of the Step-1 parameters, which can only come from the
sample they were estimated on. A model from as_tse_lca() receives only the
parameter values, so it uses the variance matrix given in vcov. Without
vcov, Step 3 warns and reports robust standard errors (se = "robust"),
which do not include the Step-1 uncertainty. vcov() of the model returns
vcov, or an error if none was given.
If the parameters are the maximum likelihood estimates for data (a model
estimated on these data and saved), vcov(m) of the original tse_lca()
model is the matching vcov. For parameters estimated on another sample,
take the variance matrix from that estimation (e.g. Latent GOLD or Mplus
output), or use tse_classify() with newdata on the original model.
A tseLCA_measurement object, usable like one from tse_lca().
d <- generate_data(500, "high", "covariate", seed = 1) m <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 3) # the same measurement model from its parameters and their variance m2 <- as_tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, class_sizes = class_sizes(m), item_probs = item_probs(m), vcov = vcov(m)) all.equal(logLik(m2), logLik(m), tolerance = 1e-6) coef(tse_covariate(tse_classify(m2), ~ Zp)) # without `vcov`, Step 3 warns and reports robust standard errors m3 <- as_tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, class_sizes = class_sizes(m), item_probs = item_probs(m)) fit3 <- tse_covariate(tse_classify(m3), ~ Zp)d <- generate_data(500, "high", "covariate", seed = 1) m <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 3) # the same measurement model from its parameters and their variance m2 <- as_tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, class_sizes = class_sizes(m), item_probs = item_probs(m), vcov = vcov(m)) all.equal(logLik(m2), logLik(m), tolerance = 1e-6) coef(tse_covariate(tse_classify(m2), ~ Zp)) # without `vcov`, Step 3 warns and reports robust standard errors m3 <- as_tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, class_sizes = class_sizes(m), item_probs = item_probs(m)) fit3 <- tse_covariate(tse_classify(m3), ~ Zp)
Methods for the tseLCA_select object returned by tse_lca() with
several numbers of classes. best_model() returns the fitted model that
minimizes an information criterion; x[[k]] returns the k-class model.
best_model(object, ...) ## S3 method for class 'tseLCA_select' best_model(object, criterion = c("BIC", "AIC", "SABIC"), ...) ## S3 method for class 'tseLCA_select' x[[i, ...]] ## S3 method for class 'tseLCA_select' as.data.frame(x, ...) ## S3 method for class 'tseLCA_select' print(x, digits = max(3L, getOption("digits") - 3L), ...) ## S3 method for class 'tseLCA_select' plot(x, which = c("AIC", "BIC", "SABIC"), ...)best_model(object, ...) ## S3 method for class 'tseLCA_select' best_model(object, criterion = c("BIC", "AIC", "SABIC"), ...) ## S3 method for class 'tseLCA_select' x[[i, ...]] ## S3 method for class 'tseLCA_select' as.data.frame(x, ...) ## S3 method for class 'tseLCA_select' print(x, digits = max(3L, getOption("digits") - 3L), ...) ## S3 method for class 'tseLCA_select' plot(x, which = c("AIC", "BIC", "SABIC"), ...)
... |
Further arguments passed to |
criterion |
Information criterion to minimize: |
x, object
|
A |
i |
Number of classes of the model to extract. |
digits |
Number of significant digits to print. |
which |
Criteria to plot. |
best_model() and [[: a tseLCA_measurement object.
as.data.frame(): the enumeration table. print(), plot(): x,
invisibly.
d <- generate_data(500, "high", "covariate", seed = 1) sel <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 1:4) as.data.frame(sel) best_model(sel) sel[[2]]d <- generate_data(500, "high", "covariate", seed = 1) sel <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 1:4) as.data.frame(sel) best_model(sel) sel[[2]]
A list of pre-specified parameters used by generate_data() and related
functions. All elements correspond to the values stated in the paper
(Section 3, p. 879).
bk2018_paramsbk2018_params
class_propsLength-3 vector of equal class proportions (1/3 each).
separation_levelsNamed vector mapping "low", "mid", "high"
to the probability of a "likely" response (0.70, 0.80, 0.90).
covariate_paramsList with $b0 (intercepts) and $b (slopes)
for the multinomial logit P(X=t | Zp). Intercepts b02 and b03 are
set so that marginal class sizes average to 1/3 when Zp ~ Uniform{1..5}.
distal_paramsList with $mu (class means, c(-1, 1, 0)) and
$sigma (residual SD = 1) for the distal outcome model.
A named list with four elements:
class_propsLength-3 numeric vector of equal class proportions (1/3 each).
separation_levelsNamed numeric vector mapping
"low", "mid", "high" to 0.70, 0.80, 0.90.
covariate_paramsList with $b0 (intercepts) and
$b (slopes) for the multinomial logit P(X=t|Zp).
distal_paramsList with $mu (class means) and
$sigma (residual SD).
# True item-response probabilities for high separation bk2018_params$rho_high # Covariate model parameters (intercepts and slopes) bk2018_params$covariate_params # Distal outcome parameters bk2018_params$distal_params# True item-response probabilities for high separation bk2018_params$rho_high # Covariate model parameters (intercepts and slopes) bk2018_params$covariate_params # Distal outcome parameters bk2018_params$distal_params
class_sizes() returns the estimated class proportions and
item_probs() the class-conditional item-response probabilities of the
Step-1 measurement model underlying any fitted tseLCA object.
class_sizes(object, ...) ## S3 method for class 'tseLCA' class_sizes(object, se = FALSE, ...) item_probs(object, ...) ## S3 method for class 'tseLCA' item_probs(object, se = FALSE, ...)class_sizes(object, ...) ## S3 method for class 'tseLCA' class_sizes(object, se = FALSE, ...) item_probs(object, ...) ## S3 method for class 'tseLCA' item_probs(object, se = FALSE, ...)
object |
A fitted |
... |
Further arguments (currently unused). |
se |
Logical. If |
With se = TRUE, their standard errors are returned as well. They are
obtained by the delta method from the variance of the measurement model's
log-ratio parameters (vcov() of the measurement model): class sizes are
the softmax of , and the response probabilities of
an item in class the softmax of . Parameters on the boundary of the parameter space
are treated as fixed and get a standard error of zero.
class_sizes(): a named numeric vector of length T summing to one.
item_probs(): a matrix with one row per item (binary items:
) or per item category (polytomous items:
) and one column per class. With se = TRUE,
a list with elements estimate and se of that form.
d <- generate_data(200, "high", "covariate", seed = 1) m <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 3) class_sizes(m) item_probs(m) item_probs(m, se = TRUE)$sed <- generate_data(200, "high", "covariate", seed = 1) m <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 3) class_sizes(m) item_probs(m) item_probs(m, se = TRUE)$se
Returns a named coefficient vector whose names match the rows and columns
of vcov(), so that stats::confint() and other generic tools work.
## S3 method for class 'tseLCA_structural' coef( object, component = c("all", "covariate", "distal"), step = c("three_step", "two_step"), matrix = FALSE, ... ) ## S3 method for class 'tseLCA_measurement' coef(object, ...)## S3 method for class 'tseLCA_structural' coef( object, component = c("all", "covariate", "distal"), step = c("three_step", "two_step"), matrix = FALSE, ... ) ## S3 method for class 'tseLCA_measurement' coef(object, ...)
object |
A fitted |
component |
For |
step |
|
matrix |
Logical. If |
... |
Further arguments (currently unused). |
Measurement models: class-size log-ratios and
item-response log-ratios . Use
class_sizes() and item_probs() for the probability scale.
Covariate models: multinomial-logit coefficients named
"<covariate>:<class>", e.g. "Zp:C2".
Distal-outcome models: class-specific means (gaussian), log means
(poisson), logits (binomial), or category probabilities
(multinomial, named "<class>:<category>").
A named numeric vector (or matrix / list if matrix = TRUE).
d <- generate_data(200, "high", "covariate", seed = 1) fit <- three_step(d, paste0("Y", 1:6), n_classes = 3, Zp.names = "Zp", use.simple.cov = TRUE) coef(fit) coef(fit, matrix = TRUE) confint(fit)d <- generate_data(200, "high", "covariate", seed = 1) fit <- three_step(d, paste0("Y", 1:6), n_classes = 3, Zp.names = "Zp", use.simple.cov = TRUE) coef(fit) coef(fit, matrix = TRUE) confint(fit)
Draw latent class memberships from their marginal distribution
draw_classes(n, pi_)draw_classes(n, pi_)
n |
Integer. Sample size. |
pi_ |
Numeric vector of length T. Class proportions (must sum to 1). |
Integer vector of length n with values in 1:T.
# Draw 100 class labels from equal prevalences draw_classes(100, c(1/3, 1/3, 1/3))# Draw 100 class labels from equal prevalences draw_classes(100, c(1/3, 1/3, 1/3))
Draw latent classes conditional on the covariate (scenario "covariate")
draw_classes_given_Zp(Zp, params)draw_classes_given_Zp(Zp, params)
Zp |
Numeric vector of length n. Covariate values. |
params |
Multinomial logistic parameter list (see |
Integer vector of length n with class labels in 1:T.
Zp <- draw_Zp(1000) X <- draw_classes_given_Zp(Zp, bk2018_params$covariate_params) table(X) # Should be roughly uniformZp <- draw_Zp(1000) X <- draw_classes_given_Zp(Zp, bk2018_params$covariate_params) table(X) # Should be roughly uniform
Draw binary indicators given true class memberships
draw_indicators(X, rho)draw_indicators(X, rho)
X |
Integer vector of length n. True latent class (1-indexed). |
rho |
T x K matrix. |
An n x K integer matrix of 0/1 values.
rho <- make_rho(0.9) X <- draw_classes(50, c(1/3, 1/3, 1/3)) draw_indicators(X, rho)rho <- make_rho(0.9) X <- draw_classes(50, c(1/3, 1/3, 1/3)) draw_indicators(X, rho)
Draw a continuous distal outcome given true class memberships (scenario "distal")
draw_Zo(X, params)draw_Zo(X, params)
X |
Integer vector of length n. Latent class (1-indexed). |
params |
List with |
Numeric vector of length n.
X <- draw_classes(100, c(1/3, 1/3, 1/3)) Zo <- draw_Zo(X, bk2018_params$distal_params) tapply(Zo, X, mean) # should be close to true muX <- draw_classes(100, c(1/3, 1/3, 1/3)) Zo <- draw_Zo(X, bk2018_params$distal_params) tapply(Zo, X, mean) # should be close to true mu
Draw the covariate Zp ~ Uniform{1, 2, 3, 4, 5}
draw_Zp(n)draw_Zp(n)
n |
Integer. Sample size. |
Integer vector of length n.
Zp <- draw_Zp(100) table(Zp)Zp <- draw_Zp(100) table(Zp)
Fixes mPhi at fit0$mPhi and estimates multinomial logit coefficients
mGamma (Q x (T-1)) with an EM algorithm using a BFGS M-step.
fitZ_from_fit0( fit0, data, Y.names, Zp.names, tol = 1e-06, maxIter = 200L, incomplete = FALSE, include.intercept = TRUE, rebase = "C1", starting_val = NULL, verbose = FALSE, Y.levels = NULL, Zp.formula = NULL )fitZ_from_fit0( fit0, data, Y.names, Zp.names, tol = 1e-06, maxIter = 200L, incomplete = FALSE, include.intercept = TRUE, rebase = "C1", starting_val = NULL, verbose = FALSE, Y.levels = NULL, Zp.formula = NULL )
fit0 |
Output of |
data |
A data.frame. |
Y.names |
Character vector of item column names. |
Zp.names |
Character vector of covariate column names. |
tol |
Convergence tolerance. Default |
maxIter |
Maximum EM iterations. Default |
incomplete |
Logical. FIML for partially missing indicators. See the
|
include.intercept |
Logical. Prepend intercept to covariate design matrix. Default |
rebase |
Character or integer. Reference class for the multinomial logit
parameterization (e.g. |
starting_val |
Optional (Q+1) x (T-1) starting value matrix for |
verbose |
Logical. Print convergence messages. Default |
Y.levels |
Optional named list of indicator categories when |
Zp.formula |
Optional one-sided formula for the covariate design; it
replaces |
A list with the following elements:
mGamma(Q+1) x (T-1) numeric matrix of multinomial logit
coefficients, where Q + 1 is the number of columns in the covariate design
matrix (including intercept if include.intercept = TRUE). Rows are
named by covariate, columns by non-reference class (e.g. "C2",
"C3").
mPhiExpanded item parameter matrix (items x classes), fixed at
fit0$mPhi throughout estimation.
vOmegaLength-T vector of marginal class proportions implied by
the final mGamma, computed as column means of the fitted class
probability matrix.
LLKSeriesSingle-column matrix of observed-data log-likelihoods, one row per EM iteration. Useful for diagnosing convergence.
convergedLogical. TRUE if the EM loop exited before
maxIter iterations or if the final log-likelihood change was below
tol.
n_obsInteger. Number of observations used in estimation after listwise deletion on covariates.
Deprecated as of tseLCA 2.0.0: use tse_twostep(). It keeps
working and warns once per session when called directly.
d <- generate_data(200, "high", "covariate", seed = 1) s1 <- lca_step1(d, Y.names = paste0("Y", 1:6), n_classes = 3) # Estimate two-step gamma with mPhi fixed at Step-1 values fZ <- fitZ_from_fit0( fit0 = s1$fit0, data = d, Y.names = paste0("Y", 1:6), Zp.names = "Zp", verbose = TRUE ) fZ$mGamma # (Q+1) x (T-1) coefficient matrix fZ$convergedd <- generate_data(200, "high", "covariate", seed = 1) s1 <- lca_step1(d, Y.names = paste0("Y", 1:6), n_classes = 3) # Estimate two-step gamma with mPhi fixed at Step-1 values fZ <- fitZ_from_fit0( fit0 = s1$fit0, data = d, Y.names = paste0("Y", 1:6), Zp.names = "Zp", verbose = TRUE ) fZ$mGamma # (Q+1) x (T-1) coefficient matrix fZ$converged
Calls multilevLCA::multiLCA with fixedpars = 1 and Z = Zp.names to
fit the two-step covariate model. This is the original multilevLCA approach
and is used when get.twostep.vcov = TRUE in three_step() to obtain
multilevLCA's corrected standard errors for the two-step gamma estimates.
fitZ_from_multiLCA( data, Y.names, n_classes, Zp.names, maxIter.measurement, measurement.tol, covariate.tol, iter.measurement, R2.threshold, incomplete = FALSE, rebase = "C1", startval = NULL, n_init = NULL, verbose = FALSE )fitZ_from_multiLCA( data, Y.names, n_classes, Zp.names, maxIter.measurement, measurement.tol, covariate.tol, iter.measurement, R2.threshold, incomplete = FALSE, rebase = "C1", startval = NULL, n_init = NULL, verbose = FALSE )
data |
A data.frame. |
Y.names |
Character vector of item column names. |
n_classes |
Integer. Number of latent classes. |
Zp.names |
Character vector of covariate column names. |
maxIter.measurement |
Maximum EM iterations. |
measurement.tol |
Convergence tolerance. |
covariate.tol |
NR tolerance for the covariate model. |
iter.measurement |
Number of random restarts. |
R2.threshold |
Entropy R |
incomplete |
Logical. FIML for partially missing indicators. See the
|
rebase |
Character or integer. Reference class for column naming of
|
startval |
Optional starting classification for the measurement
portion of this |
n_init |
Optional positive integer. If supplied, fits this
|
verbose |
Logical. |
A list with the following elements:
mGamma(Q+1) x (T-1) numeric matrix of multinomial logit
coefficients. Rows are named by covariate (including "Intercept"),
columns by non-reference class (e.g. "C2", "C3").
mPhiItem parameter matrix (items x classes) from the fixed-parameter multilevLCA fit.
vOmegaLength-T vector of marginal class proportions, computed
as the average of the fitted class probability matrix (vPi_avg in
multilevLCA output).
LLKSeriesMatrix of observed-data log-likelihoods across EM iterations, passed through directly from the multilevLCA fit.
raw_fitThe full multilevLCA::multiLCA() output object,
including $Varmat_cor (corrected variance matrix) and
$SEs_cor_gamma (corrected standard errors for mGamma) if
available.
Deprecated as of tseLCA 2.0.0: use tse_twostep(). It keeps
working and warns once per session when called directly.
d <- generate_data(200, "high", "covariate", seed = 1) # Two-step estimation with multiLCA (fixedpars = 1) fZ_ml <- fitZ_from_multiLCA( data = d, Y.names = paste0("Y", 1:6), n_classes = 3, Zp.names = "Zp", maxIter.measurement = 5000L, measurement.tol = 1e-8, covariate.tol = 1e-6, iter.measurement = 10L, R2.threshold = 0.70 ) fZ_ml$mGamma # two-step estimates fZ_ml$raw_fit$Varmat_cor # multilevLCA corrected vcovd <- generate_data(200, "high", "covariate", seed = 1) # Two-step estimation with multiLCA (fixedpars = 1) fZ_ml <- fitZ_from_multiLCA( data = d, Y.names = paste0("Y", 1:6), n_classes = 3, Zp.names = "Zp", maxIter.measurement = 5000L, measurement.tol = 1e-8, covariate.tol = 1e-6, iter.measurement = 10L, R2.threshold = 0.70 ) fZ_ml$mGamma # two-step estimates fZ_ml$raw_fit$Varmat_cor # multilevLCA corrected vcov
Iterates over the 2 scenarios x 3 separation levels x 3 sample sizes,
generating n_rep independent replications per condition. Seeds are
derived deterministically from base_seed so the entire experiment is
reproducible from a single integer.
generate_all_conditions( n_rep = 500L, base_seed = 5262026L, params = bk2018_params, scenarios = c("covariate", "distal"), sep_levels = c("low", "mid", "high"), sample_sizes = c(500L, 1000L, 2000L), verbose = TRUE )generate_all_conditions( n_rep = 500L, base_seed = 5262026L, params = bk2018_params, scenarios = c("covariate", "distal"), sep_levels = c("low", "mid", "high"), sample_sizes = c(500L, 1000L, 2000L), verbose = TRUE )
n_rep |
Integer. Replications per condition (paper uses 500). |
base_seed |
Integer. Base seed for reproducibility. |
params |
Population parameters list. Defaults to bk2018_params. |
scenarios |
Character. Lists the scenario(s) ("covariate" and/or "distal")
wanting to be simulated. Passed into |
sep_levels |
Character. Lists the separation level(s) ("low", "mid", "high")
wanting to be simulated. Passed into |
sample_sizes |
Integer. Lists the sample size(s) wanting to be generated
for each replication condition. Passed into |
verbose |
Logical. If |
Nested list indexed as
datasets[[scenario]][[separation]][[as.character(n)]],
each element a list of n_rep data frames.
# Generate 5 replicates for mid and high separation only datasets <- generate_all_conditions(n_rep = 5L, base_seed = 1L, sep_levels = c("mid", "high")) # Access a single replicate head(datasets[["covariate"]][["high"]][["500"]][[1]])# Generate 5 replicates for mid and high separation only datasets <- generate_all_conditions(n_rep = 5L, base_seed = 1L, sep_levels = c("mid", "high")) # Access a single replicate head(datasets[["covariate"]][["high"]][["500"]][[1]])
Generate one dataset following the Bakk & Kuha (2018) simulation design
generate_data( n, separation = c("low", "mid", "high"), scenario = c("covariate", "distal"), params = bk2018_params, seed = NULL )generate_data( n, separation = c("low", "mid", "high"), scenario = c("covariate", "distal"), params = bk2018_params, seed = NULL )
n |
Integer. Sample size (paper uses 500, 1000, or 2000). |
separation |
Character. One of |
scenario |
Character. One of:
|
params |
List of population parameters. Defaults to bk2018_params. |
seed |
Integer or |
A data.frame with columns:
Y1 .. Y6
Binary indicators (always present).
XTrue latent class, integer 1-3 (not observed in practice).
ZpInteger covariate 1-5 (scenario "covariate" only).
ZoContinuous distal outcome (scenario "distal" only).
# Covariate scenario with high separation d <- generate_data(n = 200, separation = "high", scenario = "covariate", seed = 1) head(d) colMeans(d) # Distal outcome scenario d2 <- generate_data(n = 200, separation = "high", scenario = "distal", seed = 2) head(d2)# Covariate scenario with high separation d <- generate_data(n = 200, separation = "high", scenario = "covariate", seed = 1) head(d) colMeans(d) # Distal outcome scenario d2 <- generate_data(n = 200, separation = "high", scenario = "distal", seed = 2) head(d2)
Estimates the latent class measurement model with multilevLCA and
optionally, fixes mPhi and estimates covariate effects (two-step
initialization) with fitZ_from_fit0().
lca_step1( data, Y.names, n_classes, Zp.names = NULL, maxIter.measurement = 5000L, measurement.tol = 1e-08, covariate.tol = 1e-06, iter.measurement = 10L, R2.threshold = 0.7, use.two.step = TRUE, estimate.one.step = TRUE, incomplete = FALSE, maxIter.fitZ = 200L, include.intercept = TRUE, rebase = "C1", startval = NULL, n_init = NULL, verbose = FALSE )lca_step1( data, Y.names, n_classes, Zp.names = NULL, maxIter.measurement = 5000L, measurement.tol = 1e-08, covariate.tol = 1e-06, iter.measurement = 10L, R2.threshold = 0.7, use.two.step = TRUE, estimate.one.step = TRUE, incomplete = FALSE, maxIter.fitZ = 200L, include.intercept = TRUE, rebase = "C1", startval = NULL, n_init = NULL, verbose = FALSE )
data |
A data.frame containing at minimum the indicator columns. |
Y.names |
Character vector of item column names. |
n_classes |
Integer. Number of latent classes. |
Zp.names |
Character vector of covariate column names, or |
maxIter.measurement |
Maximum EM iterations before giving up on convergence. Default |
measurement.tol |
Convergence tolerance. Default |
covariate.tol |
Convergence tolerance for the |
iter.measurement |
Number of random restarts when entropy R |
R2.threshold |
Entropy R |
use.two.step |
Logical. If |
estimate.one.step |
Logical. If |
incomplete |
Logical. FIML for partially missing indicators. See the
|
maxIter.fitZ |
Maximum EM iterations for |
include.intercept |
Logical. Prepend intercept to covariate design matrix. Default |
rebase |
Character or integer specifying the reference latent class.
Use |
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
measurement model |
verbose |
Logical. Print progress messages. Default |
A list with $fit0 (multilevLCA::multiLCA() measurement model) and $fitZ
(two-step covariate model from fitZ_from_fit0(), or NULL).
Deprecated as of tseLCA 2.0.0: use tse_lca(). It keeps
working and warns once per session when called directly.
d <- generate_data(200, "high", "covariate", seed = 1) # Measurement model only s1 <- lca_step1(d, Y.names = paste0("Y", 1:6), n_classes = 3) s1$fit0$vPi # estimated class prevalences s1$fit0$mPhi # item-response probabilities # With two-step covariate initialization s1z <- lca_step1(d, Y.names = paste0("Y", 1:6), n_classes = 3, Zp.names = "Zp", use.two.step = TRUE, verbose = TRUE) s1z$fitZ$mGamma # two-step gamma estimates # Many random-classification restarts, keeping the best (analogous to # n_init in StepMix or nrep in poLCA) s1r <- lca_step1(d, Y.names = paste0("Y", 1:6), n_classes = 3, n_init = 20L, verbose = TRUE)d <- generate_data(200, "high", "covariate", seed = 1) # Measurement model only s1 <- lca_step1(d, Y.names = paste0("Y", 1:6), n_classes = 3) s1$fit0$vPi # estimated class prevalences s1$fit0$mPhi # item-response probabilities # With two-step covariate initialization s1z <- lca_step1(d, Y.names = paste0("Y", 1:6), n_classes = 3, Zp.names = "Zp", use.two.step = TRUE, verbose = TRUE) s1z$fitZ$mGamma # two-step gamma estimates # Many random-classification restarts, keeping the best (analogous to # n_init in StepMix or nrep in poLCA) s1r <- lca_step1(d, Y.names = paste0("Y", 1:6), n_classes = 3, n_init = 20L, verbose = TRUE)
logLik() returns the log-likelihood of a fitted model with its number of
free parameters (df) and observations (nobs), so that stats::AIC()
and stats::BIC() work directly. For a measurement model this is the
Step-1 log-likelihood. For structural models it is the log-likelihood of
the joint model for the indicators and the structural variables evaluated
with the Step-1 parameters held fixed; for a tseLCA_both object it is the
distal-outcome component, which conditions on the covariates.
## S3 method for class 'tseLCA' logLik(object, ...) ## S3 method for class 'tseLCA' nobs(object, ...)## S3 method for class 'tseLCA' logLik(object, ...) ## S3 method for class 'tseLCA' nobs(object, ...)
object |
A fitted |
... |
Further arguments (currently unused). |
logLik(): an object of class "logLik". nobs(): an integer.
d <- generate_data(200, "high", "covariate", seed = 1) fit <- three_step(d, paste0("Y", 1:6), n_classes = 3, Zp.names = "Zp", use.simple.cov = TRUE) logLik(fit) AIC(fit) BIC(fit) nobs(fit)d <- generate_data(200, "high", "covariate", seed = 1) fit <- three_step(d, paste0("Y", 1:6), n_classes = 3, Zp.names = "Zp", use.simple.cov = TRUE) logLik(fit) AIC(fit) BIC(fit) nobs(fit)
Returns a T x K matrix rho where rho[t, k] = P(Y_k = 1 | X = t).
make_rho(pi_)make_rho(pi_)
pi_ |
Numeric scalar in (0.5, 1). Probability of the "likely" response.
Use |
The three-class structure is:
Class 1: pi_ on all 6 items (high responders).
Class 2: pi_ on items 1-3, 1 - pi_ on items 4-6 (mixed).
Class 3: 1 - pi_ on all 6 items (low responders).
A 3 x 6 numeric matrix.
# High separation: P(Y=1|class) = 0.9 for the "high" class make_rho(0.9) # Low separation make_rho(0.7)# High separation: P(Y=1|class) = 0.9 for the "high" class make_rho(0.9) # Low separation make_rho(0.7)
Extract the step-wise components of a model fitted with tseLCA() or the
step-wise functions: the Step-1 measurement model, the Step-2
classification, and the Step-3 covariate and distal outcome models.
measurement(x, ...) ## S3 method for class 'tseLCA' measurement(x, ...) classification(x, ...) ## S3 method for class 'tseLCA' classification(x, ...) covariate(x, ...) ## S3 method for class 'tseLCA' covariate(x, ...) distal(x, ...) ## S3 method for class 'tseLCA' distal(x, ...)measurement(x, ...) ## S3 method for class 'tseLCA' measurement(x, ...) classification(x, ...) ## S3 method for class 'tseLCA' classification(x, ...) covariate(x, ...) ## S3 method for class 'tseLCA' covariate(x, ...) distal(x, ...) ## S3 method for class 'tseLCA' distal(x, ...)
x |
A fitted tseLCA object. |
... |
Unused. |
measurement(): a tseLCA_measurement object.
classification(): a tseLCA_classify object. covariate(): a
tseLCA_covariate object. distal(): a tseLCA_distal object.
d <- generate_data(500, "high", "covariate", seed = 1) d$Zo <- draw_Zo(d$X, bk2018_params$distal_params) fit <- tseLCA(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ Zp | Zo, data = d, nclass = 3) class_sizes(measurement(fit)) classification(fit)$D coef(covariate(fit)) omnibus_test(distal(fit))d <- generate_data(500, "high", "covariate", seed = 1) d$Zo <- draw_Zo(d$X, bk2018_params$distal_params) fit <- tseLCA(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ Zp | Zo, data = d, nclass = 3) class_sizes(measurement(fit)) classification(fit)$D coef(covariate(fit)) omnibus_test(distal(fit))
Evaluates P(X = t | Zp) for each observation using a multinomial logit with one or more covariates and class-specific intercepts and slopes.
mnl_probs(Zp, params)mnl_probs(Zp, params)
Zp |
Numeric vector of length n, or numeric matrix of dimension n x P, where P is the number of covariates. A vector is treated as a single covariate (P = 1). |
params |
List with elements |
An n x T matrix of class probabilities (rows sum to 1).
# Single covariate: class membership probabilities for Zp = 1..5 mnl_probs(1:5, bk2018_params$covariate_params) # Multiple covariates (n = 5, P = 2) Zp_mat <- matrix(rnorm(10), nrow = 5, ncol = 2) params2 <- list(b0 = c(0, 0.5, -0.5), b = matrix(rnorm(6), nrow = 2, ncol = 3)) mnl_probs(Zp_mat, params2)# Single covariate: class membership probabilities for Zp = 1..5 mnl_probs(1:5, bk2018_params$covariate_params) # Multiple covariates (n = 5, P = 2) Zp_mat <- matrix(rnorm(10), nrow = 5, ncol = 2) params2 <- list(b0 = c(0, 0.5, -0.5), b = matrix(rnorm(6), nrow = 2, ncol = 3)) mnl_probs(Zp_mat, params2)
Tests whether the distal outcome distribution differs across latent
classes at all – for
the class-specific distal parameters (class means for
family = "gaussian", log-rates for "poisson", logits for
"binomial", or the full length-C category-probability vector for
"multinomial") – using a generalized Wald test with
vcov(). This answers whether the outcome's distribution is
associated with class membership at all, before drilling into which
classes differ. The degrees of freedom equal the rank of the contrast
covariance (T - 1 for scalar outcomes; (T - 1) * (C - 1) for
multinomial, i.e. the textbook chi-squared test of homogeneity in a
table), computed with a Moore-Penrose pseudo-inverse so
the test remains valid despite multinomial's inherently singular
covariance (each class's category probabilities sum to 1).
omnibus_test(object, ...) ## S3 method for class 'tseLCA_distal' omnibus_test(object, ...) ## S3 method for class 'tseLCA_both' omnibus_test(object, ...)omnibus_test(object, ...) ## S3 method for class 'tseLCA_distal' omnibus_test(object, ...) ## S3 method for class 'tseLCA_both' omnibus_test(object, ...)
object |
A |
... |
Unused; present for S3 method consistency. |
A standard "htest" object: the Wald chi-squared
$statistic, its degrees of freedom $parameter (also
$df), and the $p.value.
d <- generate_data(300, "high", "distal", seed = 1) fit <- three_step(d, paste0("Y", 1:6), n_classes = 3, Zo.name = "Zo", use.simple.cov = TRUE) omnibus_test(fit)d <- generate_data(300, "high", "distal", seed = 1) fit <- three_step(d, paste0("Y", 1:6), n_classes = 3, Zo.name = "Zo", use.simple.cov = TRUE) omnibus_test(fit)
Delegates to plot.multiLCA from multilevLCA, which draws the
class-specific item-response probability profiles of the Step-1
measurement model.
## S3 method for class 'tseLCA' plot(x, horiz = FALSE, clab = NULL, ...)## S3 method for class 'tseLCA' plot(x, horiz = FALSE, clab = NULL, ...)
x |
A fitted |
horiz |
Logical. If |
clab |
Optional character vector of length T giving class labels. |
... |
Further arguments passed to |
Called for its side effect (a base-graphics plot). Invisibly
returns NULL.
d <- generate_data(100, "high", "covariate", seed = 1) fit_m <- three_step(d, paste0("Y", 1:6), n_classes = 3) plot(fit_m) plot(fit_m, clab = c("Low", "Mixed", "High"))d <- generate_data(100, "high", "covariate", seed = 1) fit_m <- three_step(d, paste0("Y", 1:6), n_classes = 3) plot(fit_m) plot(fit_m, clab = c("Low", "Mixed", "High"))
posterior() returns the n x T matrix of posterior class-membership
probabilities used by a fitted model; classes() returns the modal
(most likely) class of each observation.
posterior(object, ...) ## S3 method for class 'tseLCA' posterior(object, ...) classes(object, ...) ## S3 method for class 'tseLCA' classes(object, ...)posterior(object, ...) ## S3 method for class 'tseLCA' posterior(object, ...) classes(object, ...) ## S3 method for class 'tseLCA' classes(object, ...)
object |
A fitted |
... |
Further arguments (currently unused). |
posterior(): a numeric n x T matrix. classes(): an integer
vector of length n with values in 1..T.
d <- generate_data(200, "high", "covariate", seed = 1) fit <- three_step(d, paste0("Y", 1:6), n_classes = 3, Zp.names = "Zp", use.simple.cov = TRUE) head(posterior(fit)) table(classes(fit))d <- generate_data(200, "high", "covariate", seed = 1) fit <- three_step(d, paste0("Y", 1:6), n_classes = 3, Zp.names = "Zp", use.simple.cov = TRUE) head(posterior(fit)) table(classes(fit))
The fitted class prior for the rows of newdata, or
of the estimation data.
## S3 method for class 'tseLCA_covariate' predict(object, newdata = NULL, type = c("prob", "class"), ...)## S3 method for class 'tseLCA_covariate' predict(object, newdata = NULL, type = c("prob", "class"), ...)
object |
A |
newdata |
Optional data frame with the covariates. |
type |
|
... |
Unused. |
A matrix (rows with missing covariates are NA) or integer vector.
d <- generate_data(500, "high", "covariate", seed = 1) m <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 3) fit <- tse_covariate(tse_classify(m), ~ Zp) predict(fit, newdata = data.frame(Zp = 1:5))d <- generate_data(500, "high", "covariate", seed = 1) m <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 3) fit <- tse_covariate(tse_classify(m), ~ Zp) predict(fit, newdata = data.frame(Zp = 1:5))
Posterior class-membership probabilities P(X = t | Y) for the rows of
newdata (or the estimation sample), or their modal class. Indicators in
newdata are coded with the categories stored in the model; missing
indicator values are skipped (the posterior uses the observed ones), and
rows with no observed indicator get NA.
## S3 method for class 'tseLCA_measurement' predict(object, newdata = NULL, type = c("posterior", "class"), ...) ## S3 method for class 'tseLCA_measurement' fitted(object, ...)## S3 method for class 'tseLCA_measurement' predict(object, newdata = NULL, type = c("posterior", "class"), ...) ## S3 method for class 'tseLCA_measurement' fitted(object, ...)
object |
A |
newdata |
Optional data frame with the indicator columns. Omitted: the estimation sample. |
type |
|
... |
Unused. |
A matrix (type = "posterior") or integer vector ("class").
d <- generate_data(300, "high", "covariate", seed = 1) m <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 3) predict(m, newdata = d[1:5, ]) predict(m, newdata = d[1:5, ], type = "class")d <- generate_data(300, "high", "covariate", seed = 1) m <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 3) predict(m, newdata = d[1:5, ]) predict(m, newdata = d[1:5, ], type = "class")
Refits the model with another reference class of the multinomial logit.
## S3 method for class 'tseLCA_covariate' relevel(x, ref, ...)## S3 method for class 'tseLCA_covariate' relevel(x, ref, ...)
x |
A |
ref |
The new reference class (number or label such as |
... |
Unused. |
The refitted tseLCA_covariate object.
d <- generate_data(500, "high", "covariate", seed = 1) m <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 3) fit <- tse_covariate(tse_classify(m), ~ Zp) coef(stats::relevel(fit, ref = "C3"))d <- generate_data(500, "high", "covariate", seed = 1) m <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 3) fit <- tse_covariate(tse_classify(m), ~ Zp) coef(stats::relevel(fit, ref = "C3"))
summary() collects fit statistics and coefficient tables; printing the
result formats the tables with stats::printCoefmat(). The coefficient
table (columns Estimate, Std. Error, z value, Pr(>|z|)) can be
extracted with coef(summary(fit)).
## S3 method for class 'tseLCA_structural' summary(object, ...) ## S3 method for class 'summary.tseLCA_structural' coef(object, ...) ## S3 method for class 'summary.tseLCA_structural' print( x, digits = max(3L, getOption("digits") - 3L), signif.stars = getOption("show.signif.stars"), ... ) ## S3 method for class 'tseLCA_structural' print( x, digits = max(3L, getOption("digits") - 3L), signif.stars = getOption("show.signif.stars"), ... ) ## S3 method for class 'tseLCA_measurement' summary(object, ...) ## S3 method for class 'summary.tseLCA_measurement' print(x, digits = max(3L, getOption("digits") - 3L), ...) ## S3 method for class 'tseLCA_measurement' print(x, ...)## S3 method for class 'tseLCA_structural' summary(object, ...) ## S3 method for class 'summary.tseLCA_structural' coef(object, ...) ## S3 method for class 'summary.tseLCA_structural' print( x, digits = max(3L, getOption("digits") - 3L), signif.stars = getOption("show.signif.stars"), ... ) ## S3 method for class 'tseLCA_structural' print( x, digits = max(3L, getOption("digits") - 3L), signif.stars = getOption("show.signif.stars"), ... ) ## S3 method for class 'tseLCA_measurement' summary(object, ...) ## S3 method for class 'summary.tseLCA_measurement' print(x, digits = max(3L, getOption("digits") - 3L), ...) ## S3 method for class 'tseLCA_measurement' print(x, ...)
object |
A fitted |
... |
Further arguments passed to |
x |
A |
digits |
Number of significant digits to print. |
signif.stars |
Logical; print significance stars? |
summary() returns an object of class "summary.tseLCA_structural"
or "summary.tseLCA_measurement". Print methods return their argument
invisibly.
d <- generate_data(200, "high", "covariate", seed = 1) fit <- three_step(d, paste0("Y", 1:6), n_classes = 3, Zp.names = "Zp", use.simple.cov = TRUE) summary(fit) printCoefmat(coef(summary(fit)))d <- generate_data(200, "high", "covariate", seed = 1) fit <- three_step(d, paste0("Y", 1:6), n_classes = 3, Zp.names = "Zp", use.simple.cov = TRUE) summary(fit) printCoefmat(coef(summary(fit)))
Fits a three-step latent class model through the following steps:
Measurement model: estimates latent class parameters
(, ) using multilevLCA
(Lyrvall et al., 2025).
Classification-error matrix: computes posterior class
probabilities and the T x T misclassification probability matrix
, 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 )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, BIC
Information criteria from the measurement model.
R2entrEntropy R 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.
llikProfile log-likelihood
,
with Step-1 parameters 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
at converged estimates.
llikProfile log-likelihood
,
with Step-1 parameters 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, estimator
Shared top-level fields.
posteriors, classifications
Shared 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. 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. 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. 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)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)
Computes posterior class-membership probabilities from a fitted
measurement model, assigns observations to classes, and estimates the
classification-error probabilities
between the true class and the assigned class . These error
probabilities are what the bias-adjusted Step-3 estimators (BCH and ML)
correct for.
tse_classify( object, newdata = NULL, assignment = c("modal", "proportional"), control = NULL ) ## S3 method for class 'tseLCA_classify' print(x, digits = max(3L, getOption("digits") - 4L), ...)tse_classify( object, newdata = NULL, assignment = c("modal", "proportional"), control = NULL ) ## S3 method for class 'tseLCA_classify' print(x, digits = max(3L, getOption("digits") - 4L), ...)
object |
A measurement model from |
newdata |
Optional data frame to classify. Omitted: the data the measurement model was estimated on. |
assignment |
|
control |
Estimation settings; default: those of |
x |
A |
digits |
Number of significant digits to print. |
... |
Unused. |
The measurement model is held fixed. With newdata, observations from
another sample are classified with it, e.g. to relate the classes to
covariates observed only in a subsample; the uncertainty of the
measurement model is then still that of the sample it was estimated on.
A tseLCA_classify object with components posteriors (n x T),
classifications (modal classes), weights (the assignment weights
), D (the T x T classification-error matrix),
entropy.R2 (computed from these posteriors, relative to the entropy of
the class proportions), and data. Pass it to
the Step-3 functions.
Vermunt, J. K. (2010). Latent class modeling with covariates: Two improved three-step approaches. Political Analysis, 18(4), 450–469. doi:10.1093/pan/mpq025
d <- generate_data(500, "high", "covariate", seed = 1) m <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 3) cl <- tse_classify(m) cl tse_classify(m, assignment = "proportional") # classify another sample with the same measurement model tse_classify(m, newdata = d[1:200, ])d <- generate_data(500, "high", "covariate", seed = 1) m <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 3) cl <- tse_classify(m) cl tse_classify(m, assignment = "proportional") # classify another sample with the same measurement model tse_classify(m, newdata = d[1:200, ])
Collects the numerical settings of the three estimation steps. Pass the
result as the control argument of the model-fitting functions.
tse_control( step1.maxit = 5000L, step1.tol = 1e-08, step1.restarts = 10L, step1.restart.R2 = 0.7, n_init = NULL, step3.maxit = 200L, step3.tol = 1e-06, boundary.tol = 0.01, hessian = c("observed", "opg"), verbose = FALSE )tse_control( step1.maxit = 5000L, step1.tol = 1e-08, step1.restarts = 10L, step1.restart.R2 = 0.7, n_init = NULL, step3.maxit = 200L, step3.tol = 1e-06, boundary.tol = 0.01, hessian = c("observed", "opg"), verbose = FALSE )
step1.maxit |
Maximum number of EM iterations for the Step-1 measurement model. A fit that reaches it is retried with twice as many. |
step1.tol |
Convergence tolerance of the Step-1 EM algorithm (change in log-likelihood). |
step1.restarts |
Number of additional random starts tried when the
default Step-1 fit has an entropy R |
step1.restart.R2 |
Entropy R |
n_init |
Optional number of Step-1 fits from independent random
classifications, bypassing the default k-means initialization; the fit
with the highest log-likelihood is kept. Unlike |
step3.maxit |
Maximum number of iterations for the Step-3 (structural model) EM or Newton-Raphson algorithm. |
step3.tol |
Convergence tolerance of the Step-3 algorithm. |
boundary.tol |
Step-1 probabilities within this distance of 0 or 1 are treated as fixed when computing the Step-1 variance. |
hessian |
Step-3 information matrix used for standard errors.
|
verbose |
Logical. Print progress and convergence messages. |
A list of class "tse_control".
tse_control() tse_control(step1.maxit = 10000, n_init = 20)tse_control() tse_control(step1.maxit = 10000, n_init = 20)
Estimates a multinomial logistic regression of latent class membership on
covariates, , correcting for
the classification error of the Step-2 class assignments. The measurement
model is held fixed, so the covariates cannot change the classes.
tse_covariate( object, formula, method = c("ML", "BCH", "none"), se = c("corrected", "robust"), ref = 1, start = NULL, control = NULL, data = NULL )tse_covariate( object, formula, method = c("ML", "BCH", "none"), se = c("corrected", "robust"), ref = 1, start = NULL, control = NULL, data = NULL )
object |
A classification from |
formula |
One-sided formula for the covariates, e.g. |
method |
Step-3 estimator: |
se |
Standard errors: |
ref |
Reference class of the multinomial logit: a class number or
label such as |
start |
Optional starting values: a (Q+1) x (T-1) coefficient matrix (Q covariates plus the intercept, T classes). By default, the two-step estimates (Bakk and Kuha 2018) are used. |
control |
Estimation settings; default: those of the measurement
model. See |
data |
Optional data frame with the covariates: the classified data
(the same rows, in the same order) with any additional columns. Omitted:
the data stored in |
Estimators (method):
"ML" (default): the bias-adjusted maximum likelihood estimator of
Vermunt (2010), which treats the assigned class as an indicator of the
true class with known classification-error probabilities.
"BCH": the Bolck-Croon-Hagenaars estimator (Bolck, Croon, and
Hagenaars 2004; Vermunt 2010), which reweights the assignments with the
inverse of the classification-error matrix.
"none": the uncorrected three-step estimator (a weighted multinomial
logit of the assigned classes), which is biased toward zero; provided for
comparison.
Standard errors (se): "corrected" (default) adds the uncertainty of
the Step-1 measurement model (Bakk, Oberski, and Vermunt 2014) to the
robust (sandwich) Step-3 variance; "robust" omits it. For "BCH" the
robust variance is used, which accounts for the Step-1 uncertainty through
the weights (Vermunt 2010); for "none" the robust variance is used.
A tseLCA_covariate object; see coef.tseLCA_structural(),
summary.tseLCA_structural(), predict.tseLCA_covariate(), and
anova.tseLCA_covariate(). Pass it to tse_distal() to also model a
distal outcome.
Bakk, Z., & Kuha, J. (2018). Two-step estimation of models between latent classes and external variables. Psychometrika, 83(4), 871–892. doi:10.1007/s11336-017-9592-7
Bakk, Z., Oberski, D. L., & Vermunt, J. K. (2014). Relating latent class assignments to external variables: Standard errors for correct inference. Political Analysis, 22(4), 520–540. doi:10.1093/pan/mpu003
Bolck, A., Croon, M., & Hagenaars, J. (2004). Estimating latent structure models with categorical variables: One-step versus three-step estimators. Political Analysis, 12(1), 3–27. doi:10.1093/pan/mph001
Vermunt, J. K. (2010). Latent class modeling with covariates: Two improved three-step approaches. Political Analysis, 18(4), 450–469. doi:10.1093/pan/mpq025
d <- generate_data(500, "high", "covariate", seed = 1) m <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 3) cl <- tse_classify(m) fit <- tse_covariate(cl, ~ Zp) summary(fit) confint(fit) predict(fit, newdata = data.frame(Zp = 1:5)) # BCH, and the uncorrected estimator for comparison coef(tse_covariate(cl, ~ Zp, method = "BCH")) coef(tse_covariate(cl, ~ Zp, method = "none"))d <- generate_data(500, "high", "covariate", seed = 1) m <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 3) cl <- tse_classify(m) fit <- tse_covariate(cl, ~ Zp) summary(fit) confint(fit) predict(fit, newdata = data.frame(Zp = 1:5)) # BCH, and the uncorrected estimator for comparison coef(tse_covariate(cl, ~ Zp, method = "BCH")) coef(tse_covariate(cl, ~ Zp, method = "none"))
Estimates the class-specific distribution of a distal outcome, correcting
for the classification error of the Step-2 class assignments (Bakk,
Tekle, and Vermunt 2013). Given a covariate model from tse_covariate(),
the class prior depends on the covariates and the covariate-model
uncertainty is propagated to the distal estimates. The Step-2 assignments
and classification errors are those of the classification (they use the
indicators only); only the class prior is covariate-adjusted.
tse_distal( object, formula, family = "gaussian", method = NULL, se = NULL, control = NULL, data = NULL )tse_distal( object, formula, family = "gaussian", method = NULL, se = NULL, control = NULL, data = NULL )
object |
A classification from |
formula |
|
family |
Distribution of the outcome within classes: |
method, se
|
As for |
control |
Estimation settings; default: those of |
data |
Optional data frame with the distal outcome, as in
|
The class-specific parameters are means (gaussian, with a common
within-class variance, reported as $sigma2), log means (poisson),
logits (binomial), or category probabilities ("multinomial"). The
estimators and standard errors are as for tse_covariate(). Use
omnibus_test() to test whether the outcome differs across classes.
A tseLCA_distal object, or a tseLCA_both object when object
is a covariate model.
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. doi:10.1177/0081175012470644
d <- generate_data(500, "high", "distal", seed = 2) m <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 3) fd <- tse_distal(tse_classify(m, assignment = "proportional"), Zo ~ 1) summary(fd) omnibus_test(fd)d <- generate_data(500, "high", "distal", seed = 2) m <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 3) fd <- tse_distal(tse_classify(m, assignment = "proportional"), Zo ~ 1) summary(fd) omnibus_test(fd)
Estimates the measurement model: the class sizes and the class-conditional
item-response probabilities of the indicators on the left-hand side of
formula. This is the first step of three-step estimation; covariates and
distal outcomes are related to the classes afterwards, holding this model
fixed.
tse_lca( formula, data, nclass, start = NULL, missing = c("listwise", "fiml"), control = tse_control() )tse_lca( formula, data, nclass, start = NULL, missing = c("listwise", "fiml"), control = tse_control() )
formula |
A formula |
data |
A data frame. |
nclass |
Number of latent classes, or a vector of numbers of classes
to compare (e.g. |
start |
Optional fixed starting point for the EM algorithm (single
|
missing |
Handling of missing indicator values: |
control |
Estimation settings, see |
With a vector nclass, a model is fitted for each number of classes and
the result is a class-enumeration table of fit statistics (see Details).
The number of classes is chosen from the measurement model alone, before
any structural variables are considered, typically by the BIC, the
interpretability of the classes, and their separation; see Nylund, Asparouhov, and
Muthén (2007) and Masyn (2013). The enumeration table reports, for each
number of classes, the log-likelihood, number of free parameters, AIC,
BIC, sample-size adjusted BIC (SABIC; Sclove 1987), entropy R, and
the smallest estimated class proportion. The one-class model is the
independence model, fitted in closed form.
Indicators may be factors, logicals, character, or numeric codes; their
categories are stored with the model and reused when the model is applied
to new data (see predict.tseLCA_measurement()) or in later steps.
For a single nclass, a tseLCA_measurement object (see
class_sizes(), item_probs(), posterior(), predict(); it keeps
data for tse_classify()); for several,
a tseLCA_select object: the enumeration table with the fitted models,
see best_model().
Masyn, K. E. (2013). Latent class analysis and finite mixture modeling. In T. D. Little (Ed.), The Oxford Handbook of Quantitative Methods, Vol. 2, 551–611. Oxford University Press.
Nylund, K. L., Asparouhov, T., & Muthén, B. O. (2007). Deciding on the number of classes in latent class analysis and growth mixture modeling: A Monte Carlo simulation study. Structural Equation Modeling, 14(4), 535–569. doi:10.1080/10705510701575396
Sclove, S. L. (1987). Application of model-selection criteria to some problems in multivariate analysis. Psychometrika, 52(3), 333–343. doi:10.1007/BF02294360
d <- generate_data(500, "high", "covariate", seed = 1) # Class enumeration sel <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 1:4) sel plot(sel) # The selected model m <- best_model(sel, criterion = "BIC") m class_sizes(m) item_probs(m) head(predict(m, newdata = d[1:5, ]))d <- generate_data(500, "high", "covariate", seed = 1) # Class enumeration sel <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 1:4) sel plot(sel) # The selected model m <- best_model(sel, criterion = "BIC") m class_sizes(m) item_probs(m) head(predict(m, newdata = d[1:5, ]))
Estimates the multinomial logit of class membership on covariates with the measurement-model parameters held fixed at their Step-1 values (Bakk and Kuha 2018). Unlike the three-step estimators, the indicators enter the Step-2 likelihood directly, so no classification step is needed.
tse_twostep(object, formula, ref = 1, se = FALSE, control = NULL)tse_twostep(object, formula, ref = 1, se = FALSE, control = NULL)
object |
A measurement model from |
formula |
One-sided covariate formula. |
ref |
Reference class of the multinomial logit. |
se |
Logical. If |
control |
Estimation settings; default: those of |
A tseLCA_twostep object (also a tseLCA_covariate).
Bakk, Z., & Kuha, J. (2018). Two-step estimation of models between latent classes and external variables. Psychometrika, 83(4), 871–892. doi:10.1007/s11336-017-9592-7
d <- generate_data(500, "high", "covariate", seed = 1) m <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 3) coef(tse_twostep(m, ~ Zp))d <- generate_data(500, "high", "covariate", seed = 1) m <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 3) coef(tse_twostep(m, ~ Zp))
Fits the measurement model, classifies the observations, and relates the
classes to covariates and/or a distal outcome, all from one formula. This
is a convenience wrapper around the step-wise functions tse_lca(),
tse_classify(), tse_covariate(), and tse_distal(), which remain
available for inspecting each step (see measurement()).
tseLCA( formula, data, nclass, family = "gaussian", method = c("ML", "BCH", "none"), se = c("corrected", "robust"), assignment = c("modal", "proportional"), ref = 1, missing = c("listwise", "fiml"), start = NULL, control = tse_control() )tseLCA( formula, data, nclass, family = "gaussian", method = c("ML", "BCH", "none"), se = c("corrected", "robust"), assignment = c("modal", "proportional"), ref = 1, missing = c("listwise", "fiml"), start = NULL, control = tse_control() )
formula |
|
data |
A data frame. |
nclass |
Number of latent classes. |
family |
Distribution of the distal outcome; see |
method |
Step-3 estimator: |
se |
Standard errors: |
assignment |
Step-2 class assignment: |
ref |
Reference class of the covariate model. |
missing |
Missing indicator values: |
start |
Optional Step-1 starting values; see |
control |
Estimation settings, see |
The formula has up to three parts: indicators ~ covariates | outcome.
Left-hand side: the indicators, cbind(Y1, Y2, ...).
First right-hand side part: the covariates of class membership, with the
usual formula syntax (1 for none).
Optional second part: the name of a distal outcome.
For example, cbind(Y1, Y2, Y3) ~ age + sex | income relates the classes
to the covariates age and sex and to the distal outcome income;
cbind(Y1, Y2, Y3) ~ 1 | income has only the distal outcome; and
cbind(Y1, Y2, Y3) ~ 1 fits the measurement model alone.
The number of classes is chosen beforehand from the measurement model, for
example with tse_lca(..., nclass = 1:6).
A tseLCA_measurement, tseLCA_covariate, tseLCA_distal, or
tseLCA_both object, depending on the formula. Its components are
available with measurement(), classification(), covariate(), and
distal().
d <- generate_data(500, "high", "covariate", seed = 1) d$Zo <- draw_Zo(d$X, bk2018_params$distal_params) fit <- tseLCA(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ Zp | Zo, data = d, nclass = 3) summary(fit) measurement(fit) classification(fit) # the same model, step by step m <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 3) fc <- tse_covariate(tse_classify(m), ~ Zp) fb <- tse_distal(fc, Zo ~ 1)d <- generate_data(500, "high", "covariate", seed = 1) d$Zo <- draw_Zo(d$X, bk2018_params$distal_params) fit <- tseLCA(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ Zp | Zo, data = d, nclass = 3) summary(fit) measurement(fit) classification(fit) # the same model, step by step m <- tse_lca(cbind(Y1, Y2, Y3, Y4, Y5, Y6) ~ 1, data = d, nclass = 3) fc <- tse_covariate(tse_classify(m), ~ Zp) fb <- tse_distal(fc, Zo ~ 1)
Row and column names match coef().
## S3 method for class 'tseLCA_structural' vcov( object, component = c("all", "covariate", "distal"), step = c("three_step", "two_step"), ... ) ## S3 method for class 'tseLCA_measurement' vcov(object, boundary.tol = 0.01, ...)## S3 method for class 'tseLCA_structural' vcov( object, component = c("all", "covariate", "distal"), step = c("three_step", "two_step"), ... ) ## S3 method for class 'tseLCA_measurement' vcov(object, boundary.tol = 0.01, ...)
object |
A fitted |
component |
For |
step |
|
... |
Further arguments (currently unused). |
boundary.tol |
Measurement models only: parameters within this
tolerance of 0 or 1 are treated as fixed. Default |
Measurement models: the BHHH variance matrix of the log-ratio
parameters (attribute "parameterization" records the scale).
Covariate and distal-outcome models: the Step-3 variance matrix, which
includes the correction for Step-1 uncertainty unless the model was
fitted with use.simple.cov = TRUE. For family = "multinomial" it is
on the probability scale and rank-deficient (each class's probabilities
sum to one).
tseLCA_both with component = "all": the covariate and distal blocks
on the diagonal; the cross-covariances between the two sets of
parameters are not computed and are NA.
A named square matrix.
d <- generate_data(200, "high", "covariate", seed = 1) fit <- three_step(d, paste0("Y", 1:6), n_classes = 3, Zp.names = "Zp", use.simple.cov = TRUE) vcov(fit)d <- generate_data(200, "high", "covariate", seed = 1) fit <- three_step(d, paste0("Y", 1:6), n_classes = 3, Zp.names = "Zp", use.simple.cov = TRUE) vcov(fit)