Skip to contents

Find the likelihood-based confidence intervals (LBCIs) for selected free parameters in an SEM output.


  pars = NULL,
  include_user_pars = TRUE,
  remove_variances = TRUE,
  remove_intercepts = TRUE,
  ciperc = 0.95,
  standardized = FALSE,
  method = "wn",
  robust = c("none", "satorra.2000"),
  try_k_more_times = 2,
  semlbci_out = NULL,
  check_fit = TRUE,
  parallel = FALSE,
  ncpus = 2,
  use_pbapply = TRUE



The SEM output. Currently supports lavaan::lavaan outputs only.


The positions of the parameters for which the LBCIs are to be searched. Use the position as appeared on the parameter tables of the sem_out. If NULL, the default, then LBCIs for all free parameters will be searched. Can also be a vector of strings to indicate the parameters on the parameter table. The parameters should be specified in lavaan::lavaan() syntax. The vector of strings will be converted by syntax_to_i() to parameter positions. See syntax_to_i() on how to specify the parameters.


Logical. Whether all user-defined parameters are automatically included when pars is not set. Default is TRUE. If pars is explicitly set, this argument will be ignored.


Logical. Whether variances and error variances will be removed. Default is TRUE, removing all variances and error variances even if specified in pars.


Logical. Whether intercepts will be removed. Default is TRUE, removing all intercepts (parameters with operator ~1). Intercepts are not yet supported in standardized solution and so will always be removed if standardized = TRUE.


The proportion of coverage for the confidence interval. Default is .95, requesting a 95 percent confidence interval.


If TRUE, the LBCI is for the standardized estimates.


The method to be used to search for the confidence bounds. Currently only "wn" (Wu-Neale-2012), the default, is supported.


Whether the LBCI based on robust likelihood ratio test is to be found. Only "satorra.2000" in lavaan::lavTestLRT() is supported for now, implemented by the method proposed by Falk (2018). If "none", the default, then likelihood ratio test based on maximum likelihood estimation will be used.


How many more times to try if failed. Default is 2.


An semlbci-class object. If provided, parameters already with LBCIs formed will be excluded from pars.


If TRUE (default), the input (sem_out) will be checked by check_sem_out(). If not supported, an error will be raised. If FALSE, the check will be skipped and the LBCIs will be searched even for a model or parameter not supported. Set to TRUE only for testing.


Arguments to be passed to ci_bound_wn_i().


If TRUE, will use parallel processing to do the search.


The number of workers, if parallel is TRUE. Default is 2. This number should not be larger than the number CPU cores.


If TRUE and pbapply is installed, pbapply::pbapply() will be used to display a progress bar when finding the intervals. Default is TRUE. Ignored if pbapply is not installed.


A semlbci-class object similar to the parameter table generated by lavaan::parameterEstimates(), with the LBCIs for selected parameters added. Diagnostic information, if requested, will be included in the attributes. See print.semlbci() for options available.


semlbci() finds the positions of the selected parameters in the parameter table and then calls ci_i_one() once for each of them. For the technical details, please see ci_i_one() and the functions it calls to find a confidence bound, currently ci_bound_wn_i(). ci_bound_wn_i() uses the approach proposed by Wu and Neale (2012) and illustrated by Pek and Wu (2015).

It supports updating an output of semlbci() by setting semlbci_out. This allows forming LBCIs for some parameters after those for some others have been formed.

If possible, parallel processing should be used (see parallel and ncpus), especially for a model with many parameters.

If the search for some of the confidence bounds failed, with NA for the bounds, try increasing try_k_more_times.

The SEM output will first be checked by check_sem_out() to see whether the model and the estimation method are supported. To skip this test (e.g., for testing or experimenting with some models and estimators), set check_fit to FALSE.

Examples and technical details can be found at Cheung and Pesigan (2023), the website of the semlbci package (, and the technical appendices at (

It currently supports lavaan::lavaan outputs only.


Cheung, S. F., & Pesigan, I. J. A. (2023). semlbci: An R package for forming likelihood-based confidence intervals for parameter estimates, correlations, indirect effects, and other derived parameters. Structural Equation Modeling: A Multidisciplinary Journal. Advance online publication. doi:10.1080/10705511.2023.2183860

Falk, C. F. (2018). Are robust standard errors the best approach for interval estimation with nonnormal data in structural equation modeling? Structural Equation Modeling: A Multidisciplinary Journal, 25(2), 244-266. doi:10.1080/10705511.2017.1367254

Pek, J., & Wu, H. (2015). Profile likelihood-based confidence intervals and regions for structural equation models. Psychometrika, 80(4), 1123-1145. doi:10.1007/s11336-015-9461-1

Wu, H., & Neale, M. C. (2012). Adjusted confidence intervals for a bounded parameter. Behavior Genetics, 42(6), 886-898. doi:10.1007/s10519-012-9560-z

Pritikin, J. N., Rappaport, L. M., & Neale, M. C. (2017). Likelihood-based confidence intervals for a parameter with an upper or lower bound. Structural Equation Modeling: A Multidisciplinary Journal, 24(3), 395-401. doi:10.1080/10705511.2016.1275969


mod <-
m ~ a*x
y ~ b*m
ab := a * b
fit_med <- sem(mod, simple_med, fixed.x = FALSE)
p_table <- parameterTable(fit_med)
#>   id lhs op rhs user block group free ustart exo label plabel  start    est
#> 1  1   m  ~   x    1     1     1    1     NA   0     a   .p1.  1.676  1.676
#> 2  2   y  ~   m    1     1     1    2     NA   0     b   .p2.  0.535  0.535
#> 3  3   m ~~   m    0     1     1    3     NA   0         .p3. 34.710 34.710
#> 4  4   y ~~   y    0     1     1    4     NA   0         .p4. 40.119 40.119
#> 5  5   x ~~   x    0     1     1    5     NA   0         .p5.  0.935  0.935
#> 6  6  ab := a*b    1     0     0    0     NA   0    ab         0.000  0.897
#>      se
#> 1 0.431
#> 2 0.073
#> 3 3.471
#> 4 4.012
#> 5 0.094
#> 6 0.261
lbci_med <- semlbci(fit_med,
                    pars = c("m ~ x",
                             "y ~ m",
                             "ab :="))
#> Results:
#>   id lhs op rhs label   est lbci_lb lbci_ub    lb    ub cl_lb cl_ub
#> 1  1   m  ~   x     a 1.676   0.828   2.525 0.832 2.520 0.950 0.950
#> 2  2   y  ~   m     b 0.535   0.391   0.679 0.391 0.679 0.950 0.950
#> 6  6  ab := a*b    ab 0.897   0.427   1.464 0.385 1.409 0.950 0.950
#> Annotation:
#> * lbci_lb, lbci_ub: The lower and upper likelihood-based bounds.
#> * est: The point estimates from the original lavaan output.
#> * lb, ub: The original lower and upper bounds, extracted from the
#>     original lavaan output. Usually Wald CIs for free parameters and
#>     delta method CIs for user-defined parameters
#> * cl_lb, cl_ub: One minus the p-values of chi-square difference tests
#>     at the bounds. Should be close to the requested level of
#>     confidence, e.g., .95 for 95% confidence intervals.
#> Call:
#> semlbci(sem_out = fit_med, pars = c("m ~ x", "y ~ m", "ab :="))