6  Confirmatory Factor Analysis

Confirmatory Factor Analysis (CFA) is a latent-variable modeling approach used to evaluate whether a theoretically specified measurement model is compatible with observed data. In a CFA, the researcher states in advance which indicators are expected to represent which latent factors and then evaluates the consequences of that specification (Bollen, 1989; Kline, 2023).

CFA is therefore especially useful when a measurement structure has already been proposed by theory, previous research, an earlier EFA, or the design of the instrument itself. It can also be used to compare plausible competing measurement models.

NoteChapter map

This chapter develops CFA through six connected questions:

  1. What makes CFA different from EFA?
  2. How is a CFA model specified mathematically?
  3. When is a CFA model identified?
  4. What do common fit indices actually tell us?
  5. Why does good fit not prove the measurement theory?
  6. How can we specify, fit, inspect, and report CFA models in R?

6.1 What Is Confirmatory Factor Analysis?

Suppose we have a questionnaire intended to measure two dimensions: Extraversion and Neuroticism. If theory states that Items 1–4 measure Extraversion and Items 5–8 measure Neuroticism, CFA allows us to encode that structure directly and evaluate how well it reproduces the observed relationships among the items.

This is the central difference from EFA. In EFA, the loading pattern is estimated more freely and rotation is used to search for an interpretable factor structure. In CFA, the researcher specifies a more explicit model before estimation.

EFA CFA
The loading pattern is explored more freely The loading pattern is specified more explicitly
Cross-loadings are generally estimated Some cross-loadings are commonly fixed to zero
Rotation is central to interpretation The hypothesized loading structure defines the orientation of the factors
Factor retention is a major part of the analysis The number of factors is usually specified before fitting the model
Useful for structural exploration Useful for testing a theoretically specified measurement model
ImportantConfirmatory does not mean proven

A CFA can show that observed data are compatible or incompatible with a specified measurement model. It cannot prove that the model is the true psychological explanation of the data. Other models can sometimes reproduce very similar covariance structures (Bork et al., 2017; Kruis & Maris, 2016; Schmittmann et al., 2013).

6.1.1 When is CFA useful?

Common applications include:

  • evaluating a factor structure proposed in previous research;
  • evaluating whether a structure found in one population is also plausible in another;
  • testing theoretically competing factor structures;
  • evaluating higher-order or bifactor models;
  • testing measurement invariance across groups or occasions; and
  • examining specific hypotheses about factor correlations, loadings, or residual relations.

CFA is therefore not restricted to situations in which an earlier study has already conducted an EFA. The important requirement is that the constraints imposed on the CFA have a substantive justification.

6.2 The CFA Measurement Model

A common notation for a measurement model is

\[ \mathbf{x} = \mathbf{\Lambda}\boldsymbol{\eta} + \boldsymbol{\epsilon}, \]

where:

  • \(\mathbf{x}\) is the vector of observed indicators;
  • \(\boldsymbol{\eta}\) is the vector of latent factors;
  • \(\mathbf{\Lambda}\) is the matrix of factor loadings; and
  • \(\boldsymbol{\epsilon}\) is the vector of indicator-specific residuals or measurement disturbances (Bollen, 1989).

For a single indicator,

\[ x_i = \lambda_{i1}\eta_1 + \lambda_{i2}\eta_2 + \cdots + \lambda_{im}\eta_m + \epsilon_i. \]

The factor loading \(\lambda_{im}\) describes how strongly indicator \(i\) is related to factor \(m\) under the specified model.

6.2.1 A two-factor example

Imagine eight indicators. The first four are specified as indicators of Extraversion and the last four as indicators of Neuroticism. A simple CFA model can be written as

\[ \begin{bmatrix} x_1\\ x_2\\ x_3\\ x_4\\ x_5\\ x_6\\ x_7\\ x_8 \end{bmatrix} = \begin{bmatrix} \lambda_{11} & 0\\ \lambda_{21} & 0\\ \lambda_{31} & 0\\ \lambda_{41} & 0\\ 0 & \lambda_{52}\\ 0 & \lambda_{62}\\ 0 & \lambda_{72}\\ 0 & \lambda_{82} \end{bmatrix} \begin{bmatrix} \eta_1\\ \eta_2 \end{bmatrix} + \begin{bmatrix} \epsilon_1\\ \epsilon_2\\ \epsilon_3\\ \epsilon_4\\ \epsilon_5\\ \epsilon_6\\ \epsilon_7\\ \epsilon_8 \end{bmatrix}. \]

The zeros are substantively important. They express the hypothesis that, for example, an indicator assigned only to Extraversion has no direct loading on Neuroticism in this particular CFA model.

A standard reflective CFA also assumes that the latent variables are uncorrelated with their indicator residuals:

\[ \operatorname{Cov}(\eta_j,\epsilon_i)=0. \]

Residuals are often initially assumed to be mutually uncorrelated as well, unless the model explicitly includes residual covariances.

TipRead a CFA model as a set of claims

A zero loading is not an empty cell. It is a restriction. Likewise, a fixed factor correlation, equality constraint, or residual covariance is a theoretical/statistical statement built into the model. CFA becomes useful because those restrictions have observable consequences.

6.3 CFA Is More Restricted Than EFA

It is common to describe EFA as “unrestricted” and CFA as “restricted,” but this shorthand should be used carefully. EFA is not a saturated model in the usual structural-equation-modeling sense. EFA still imposes a common-factor structure and requires identification constraints. It is simply less restrictive than a conventional independent-clusters CFA because cross-loadings are generally estimated rather than fixed to zero.

A conventional CFA might specify

Indicator Factor 1 Factor 2
V1 estimated 0
V2 estimated 0
V3 estimated 0
V4 0 estimated
V5 0 estimated
V6 0 estimated

In an EFA with two retained factors, each item would generally have a loading estimated on both factors before rotation.

NoteWhy this distinction matters

A poor-fitting CFA does not necessarily mean that the proposed factors do not exist. The model may be too restrictive—for example, because small cross-loadings or residual relationships have been fixed to zero. The question is whether those additional relations are substantively defensible, not merely whether freeing them improves fit.

6.4 Model Identification

Before interpreting a CFA, the model must be identified (Bollen, 1989). Identification asks whether the observed information is sufficient to estimate the unknown model parameters uniquely.

6.4.1 Counting observed information

With \(p\) observed variables and no mean structure, the sample covariance matrix contains

\[ \frac{p(p+1)}{2} \]

unique pieces of information: \(p\) variances and

\[ \frac{p(p-1)}{2} \]

unique covariances.

For four indicators:

\[ \frac{4(4+1)}{2}=10. \]

Those ten sample moments consist of four variances and six covariances.

6.4.2 A one-factor example

Suppose a one-factor CFA has four indicators. If the factor variance is fixed to 1 to define the scale of the latent variable, we estimate

  • 4 factor loadings; and
  • 4 residual variances.

That gives eight free parameters. Because the covariance matrix provides ten unique sample moments,

\[ df = 10 - 8 = 2. \]

The model is therefore overidentified and places testable restrictions on the covariance matrix.

With only three indicators, the covariance matrix provides

\[ \frac{3(3+1)}{2}=6 \]

sample moments. A one-factor model with three freely estimated loadings and three residual variances, after fixing the factor variance to 1, also contains six free parameters. Therefore,

\[ df=0. \]

This is a just-identified model.

Degrees of freedom Identification status Implication
\(df < 0\) Underidentified There is not enough information to estimate all parameters uniquely
\(df = 0\) Just-identified Parameters may be estimable, but the model reproduces the sample moments exactly, so global fit cannot be tested
\(df > 0\) Overidentified The model imposes testable restrictions and global fit can be evaluated
WarningA correction to a common misunderstanding

A model with \(df=0\) is not underidentified. It is just-identified. Also, a model does not need \(df>1\) to be testable; any positive number of degrees of freedom represents an overidentified model. Identification in more complicated models can require additional conditions beyond simple parameter counting (Bollen, 1989).

6.4.3 Setting the scale of the latent variable

Because latent variables are unobserved, their numerical scale must be defined. Two common approaches are:

  1. Marker-variable method: fix one factor loading to 1.
  2. Fixed-factor method: fix the factor variance to 1 and estimate all loadings.

lavaan uses the marker-variable approach by default. Alternatively, std.lv = TRUE fixes latent variances to 1 (Rosseel, 2012).

6.5 Model Fit: What Are We Comparing?

Once a model is identified and estimated, we ask how well the model-implied covariance matrix reproduces the observed covariance matrix.

Let

\[ \mathbf{S} \]

be the observed covariance matrix and

\[ \mathbf{\Sigma}(\theta) \]

the covariance matrix implied by the model parameters \(\theta\). CFA estimation attempts to find parameter values that make \(\mathbf{\Sigma}(\theta)\) sufficiently close to \(\mathbf{S}\) according to the estimator’s fitting function (Bollen, 1989; Kline, 2023).

ImportantFit is about consequences of the model

Fit indices evaluate discrepancies between observed and model-implied relationships. They do not directly inspect whether the psychological causal story attached to the latent variable is true.

6.6 Common Fit Statistics and Indices

Rather than treating fit as one number, it is useful to consider several types of evidence.

Statistic / index Main question
\(\chi^2\) test Is exact model fit rejected?
RMSEA How much approximate misfit is present relative to model complexity?
SRMR How large are the standardized residual discrepancies?
CFI How much better is the target model than a baseline independence model?
TLI Similar to CFI, with a stronger penalty for model complexity

6.6.1 Chi-square test

The model chi-square evaluates an exact-fit null hypothesis. In broad terms,

\[ H_0:\mathbf{\Sigma}(\theta)=\mathbf{\Sigma}. \]

A statistically significant result indicates evidence against exact fit. Because the chi-square statistic is sensitive to sample size and model misspecification, it is normally interpreted together with other diagnostics rather than as the sole criterion for deciding whether a model is acceptable (Kline, 2023).

6.6.2 RMSEA

The Root Mean Square Error of Approximation (RMSEA) is an approximate-fit index derived from the model chi-square and degrees of freedom. Lower values indicate less approximate discrepancy per degree of freedom (Steiger & Lind, 1980).

RMSEA should preferably be reported with its confidence interval rather than as a single number.

6.6.3 CFI and TLI

The Comparative Fit Index (CFI) compares the fitted model with a baseline model in which the observed variables are treated as mutually independent (Bentler, 1990).

The Tucker–Lewis Index (TLI) is another incremental index that also incorporates model complexity (Tucker & Lewis, 1973).

Higher values indicate greater improvement over the baseline model.

6.6.4 SRMR

The Standardized Root Mean Square Residual (SRMR) summarizes the standardized discrepancy between observed and model-implied relationships. Lower values indicate smaller residual discrepancies.

6.7 Should We Use Universal Cutoffs?

One of the most influential simulation studies suggested combinations such as approximately CFI/TLI \(\ge .95\) and RMSEA \(\le .06\) under particular continuous-data conditions (Hu & Bentler, 1999). These values are widely repeated as if they were universal laws.

They are not.

Cutoff behavior depends on features such as estimator, sample size, number of indicators, factor loadings, model complexity, distributional characteristics, and whether indicators are continuous or categorical. For ordered categorical data, for example, the behavior of RMSEA, CFI, and TLI depends strongly on the estimation method (Xia & Yang, 2019).

WarningAvoid the traffic-light approach to fit

Do not reduce CFA to:

CFI > .95 = good; RMSEA < .06 = good; therefore the model is true.

Fit indices are diagnostic summaries. Interpret them together with the model’s purpose, residuals, parameter estimates, theoretical plausibility, data type, estimator, and plausible alternative models.

6.8 Flexible Models Can Fit Well for the Wrong Reason

A model can obtain better fit simply because it is more flexible. Bonifay & Cai (2017) demonstrated that highly parameterized latent variable models can possess substantial fit propensity. This is especially relevant for bifactor and other flexible models: superior fit does not automatically mean that the more complex representation is psychologically preferable.

This is one reason why comparing models only by the largest CFI or smallest RMSEA can be misleading. Model interpretation should consider parsimony, parameter behavior, theoretical meaning, and whether the additional flexibility represents plausible measurement relations.

6.9 Fit Does Not Test the Entire Causal Interpretation

Reflective factor models are often interpreted as if variation in a latent attribute explains variation in its indicators. For example, higher self-esteem is assumed to produce systematic changes in responses to self-esteem items (Bork et al., 2017).

However, a covariance structure alone may be compatible with different substantive explanations. Network models, for instance, allow observed variables to be connected directly rather than attributing all of their shared variation to a common latent cause (Epskamp et al., 2018; Schmittmann et al., 2013).

Simulation and theoretical work has also shown that factor and network models can sometimes imply equivalent or very similar observable covariance structures (Kan et al., 2020; Kruis & Maris, 2016; McFarland, 2020).

NoteConnection with the latent-variable chapter

This is the same distinction developed in Chapter 3. A good-fitting factor model provides evidence that its statistical restrictions are compatible with the data. It does not, by itself, establish that the latent variable is the true common cause of the indicators. Tetrad-based approaches attempt to test additional covariance restrictions implied by common-cause structures (Franco et al., 2023).

6.10 Modification Indices and Residual Correlations

A CFA often fails to fit perfectly. Software can suggest parameters that, if freed, are expected to improve fit. These suggestions are commonly reported as modification indices.

Typical candidates include:

  • a cross-loading currently fixed to zero;
  • a residual covariance between two indicators; or
  • another fixed parameter.

Modification indices can be useful diagnostics, but they should not be used as an automatic model-building algorithm.

For example, two items may share residual covariance because they have very similar wording, refer to the same situation, or contain a shared method effect. In that case, allowing their residuals to correlate may have a defensible substantive interpretation. Adding residual correlations solely because they improve CFI or RMSEA risks tailoring the model to sample-specific noise.

TipA better modification question

Instead of asking:

Which parameter should I free to improve fit?

ask:

What substantive feature of these indicators would justify the additional relationship?

6.11 How to Run a CFA in R

The following tutorial uses lavaan (Rosseel, 2012) and the HolzingerSwineford1939 dataset. This classic dataset contains nine mental-ability variables commonly represented by three latent dimensions (Holzinger & Swineford, 1939).

6.11.1 Install and load lavaan

Installation is required only once:

install.packages("lavaan")

Then load the package:

library(lavaan)
This is lavaan 0.7-2
lavaan is FREE software! Please report any bugs.

6.11.2 Specify the model

The three-factor model contains:

  • visual: x1, x2, x3;
  • textual: x4, x5, x6; and
  • speed: x7, x8, x9.
HS.model <- '
  visual  =~ x1 + x2 + x3
  textual =~ x4 + x5 + x6
  speed   =~ x7 + x8 + x9
'

In lavaan, the operator =~ means is measured by. The latent variable is written on the left and its indicators on the right.

6.11.3 Fit the model

For these continuous demonstration variables, we can fit the model using maximum likelihood:

cfa.fit <- lavaan::cfa(
  model = HS.model,
  data = lavaan::HolzingerSwineford1939,
  estimator = "ML"
)

Inspect the main output:

summary(
  cfa.fit,
  fit.measures = TRUE,
  standardized = TRUE
)
lavaan 0.7-2 ended normally after 35 iterations

  Estimator                                         ML
  Optimization method                           NLMINB
  Number of model parameters                        21

  Number of observations                           301

Model Test User Model:
                                                      
  Test statistic                                85.306
  Degrees of freedom                                24
  P-value (Chi-square)                           0.000

Model Test Baseline Model:

  Test statistic                               918.852
  Degrees of freedom                                36
  P-value                                        0.000

User Model versus Baseline Model:

  Comparative Fit Index (CFI)                    0.931
  Tucker-Lewis Index (TLI)                       0.896

Loglikelihood and Information Criteria:

  Loglikelihood user model (H0)              -3737.745
  Loglikelihood unrestricted model (H1)      -3695.092
                                                      
  Akaike (AIC)                                7517.490
  Bayesian (BIC)                              7595.339
  Sample-size adjusted Bayesian (SABIC)       7528.739

Root Mean Square Error of Approximation:

  RMSEA                                          0.092
  90 Percent confidence interval - lower         0.071
  90 Percent confidence interval - upper         0.114
  P-value H_0: RMSEA <= 0.050                    0.001
  P-value H_0: RMSEA >= 0.080                    0.840

Standardized Root Mean Square Residual:

  SRMR                                           0.065

Goodness of Fit Index:

  Goodness of Fit Index (GFI)                    0.959
  90 Percent confidence interval - lower         0.939
  90 Percent confidence interval - upper         0.976

Parameter Estimates:

  Standard errors                             Standard
  Information                                 Expected
  Information saturated (h1) model          Structured

Latent Variables:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  visual =~                                                             
    x1                1.000                               0.900    0.772
    x2                0.554    0.100    5.554    0.000    0.498    0.424
    x3                0.729    0.109    6.685    0.000    0.656    0.581
  textual =~                                                            
    x4                1.000                               0.990    0.852
    x5                1.113    0.065   17.014    0.000    1.102    0.855
    x6                0.926    0.055   16.703    0.000    0.917    0.838
  speed =~                                                              
    x7                1.000                               0.619    0.570
    x8                1.180    0.165    7.152    0.000    0.731    0.723
    x9                1.082    0.151    7.155    0.000    0.670    0.665

Covariances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
  visual ~~                                                             
    textual           0.408    0.074    5.552    0.000    0.459    0.459
    speed             0.262    0.056    4.660    0.000    0.471    0.471
  textual ~~                                                            
    speed             0.173    0.049    3.518    0.000    0.283    0.283

Variances:
                   Estimate  Std.Err  z-value  P(>|z|)   Std.lv  Std.all
   .x1                0.549    0.114    4.833    0.000    0.549    0.404
   .x2                1.134    0.102   11.146    0.000    1.134    0.821
   .x3                0.844    0.091    9.317    0.000    0.844    0.662
   .x4                0.371    0.048    7.779    0.000    0.371    0.275
   .x5                0.446    0.058    7.642    0.000    0.446    0.269
   .x6                0.356    0.043    8.277    0.000    0.356    0.298
   .x7                0.799    0.081    9.823    0.000    0.799    0.676
   .x8                0.488    0.074    6.573    0.000    0.488    0.477
   .x9                0.566    0.071    8.003    0.000    0.566    0.558
    visual            0.809    0.145    5.564    0.000    1.000    1.000
    textual           0.979    0.112    8.737    0.000    1.000    1.000
    speed             0.384    0.086    4.451    0.000    1.000    1.000

The output contains parameter estimates, factor covariances, the model chi-square test, and several fit indices.

6.11.4 Extract the most common fit measures

Instead of searching manually through the entire printed output, we can request a compact set of statistics:

fitMeasures(
  cfa.fit,
  c(
    "chisq",
    "df",
    "pvalue",
    "cfi",
    "tli",
    "rmsea",
    "rmsea.ci.lower",
    "rmsea.ci.upper",
    "srmr"
  )
)
         chisq             df         pvalue            cfi            tli 
        85.306         24.000          0.000          0.931          0.896 
         rmsea rmsea.ci.lower rmsea.ci.upper           srmr 
         0.092          0.071          0.114          0.065 

This is usually easier to use when preparing tables or a report.

6.11.5 Inspect standardized loadings

standardizedSolution(cfa.fit)
lhs op rhs est.std se z pvalue ci.lower ci.upper
visual =~ x1 0.7718804 0.0549727 14.041152 0.00e+00 0.6641359 0.8796250
visual =~ x2 0.4236010 0.0596191 7.105120 0.00e+00 0.3067497 0.5404523
visual =~ x3 0.5811323 0.0551393 10.539347 0.00e+00 0.4730613 0.6892034
textual =~ x4 0.8515822 0.0225431 37.775746 0.00e+00 0.8073986 0.8957659
textual =~ x5 0.8550654 0.0223412 38.272946 0.00e+00 0.8112774 0.8988535
textual =~ x6 0.8380101 0.0233552 35.881126 0.00e+00 0.7922348 0.8837854
speed =~ x7 0.5695147 0.0531549 10.714253 0.00e+00 0.4653331 0.6736963
speed =~ x8 0.7230444 0.0505306 14.309048 0.00e+00 0.6240063 0.8220825
speed =~ x9 0.6650092 0.0510943 13.015321 0.00e+00 0.5648662 0.7651523
x1 x1 0.4042006 0.0848647 4.762880 1.90e-06 0.2378688 0.5705325
x2 x2 0.8205622 0.0505094 16.245721 0.00e+00 0.7215655 0.9195589
x3 x3 0.6622852 0.0640865 10.334244 0.00e+00 0.5366781 0.7878924
x4 x4 0.2748077 0.0383946 7.157458 0.00e+00 0.1995557 0.3500597
x5 x5 0.2688631 0.0382065 7.037110 0.00e+00 0.1939798 0.3437464
x6 x6 0.2977391 0.0391437 7.606301 0.00e+00 0.2210188 0.3744595
x7 x7 0.6756530 0.0605450 11.159526 0.00e+00 0.5569871 0.7943190
x8 x8 0.4772067 0.0730717 6.530664 0.00e+00 0.3339888 0.6204247
x9 x9 0.5577627 0.0679564 8.207654 0.00e+00 0.4245706 0.6909549
visual visual 1.0000000 0.0000000 NA NA 1.0000000 1.0000000
textual textual 1.0000000 0.0000000 NA NA 1.0000000 1.0000000
speed speed 1.0000000 0.0000000 NA NA 1.0000000 1.0000000
visual textual 0.4585093 0.0637794 7.188993 0.00e+00 0.3335041 0.5835145
visual speed 0.4705345 0.0728267 6.461017 0.00e+00 0.3277968 0.6132722
textual speed 0.2829847 0.0687293 4.117382 3.83e-05 0.1482778 0.4176916

To keep only factor loadings:

subset(
  standardizedSolution(cfa.fit),
  op == "=~"
)
lhs op rhs est.std se z pvalue ci.lower ci.upper
visual =~ x1 0.7718804 0.0549727 14.04115 0 0.6641359 0.8796250
visual =~ x2 0.4236010 0.0596191 7.10512 0 0.3067497 0.5404523
visual =~ x3 0.5811323 0.0551393 10.53935 0 0.4730613 0.6892034
textual =~ x4 0.8515822 0.0225431 37.77575 0 0.8073986 0.8957659
textual =~ x5 0.8550654 0.0223412 38.27295 0 0.8112774 0.8988535
textual =~ x6 0.8380101 0.0233552 35.88113 0 0.7922348 0.8837854
speed =~ x7 0.5695147 0.0531549 10.71425 0 0.4653331 0.6736963
speed =~ x8 0.7230444 0.0505306 14.30905 0 0.6240063 0.8220825
speed =~ x9 0.6650092 0.0510943 13.01532 0 0.5648662 0.7651523

The standardized loading expresses the strength of the relation between an indicator and its factor on a standardized metric.

6.12 How Is the Factor Scale Defined?

By default, lavaan fixes the first loading of each factor to 1. This is the marker-variable method and defines the scale of the latent variable (Rosseel, 2012).

For example, the default model behaves conceptually like:

visual =~ 1*x1 + x2 + x3

The loading fixed to 1 is a scaling constraint, not an empirical finding.

If we prefer to fix the latent variance to 1 and estimate all loadings, we can use:

cfa.fit.std.lv <- lavaan::cfa(
  HS.model,
  data = lavaan::HolzingerSwineford1939,
  estimator = "ML",
  std.lv = TRUE
)

Both approaches identify the latent scale, but the unstandardized parameterization differs.

6.13 Constraining Factor Correlations

By default, the exogenous latent factors in this CFA are allowed to correlate. Suppose theory instead proposes that the three factors are orthogonal. We can fix their covariances to zero:

HS.orthogonal <- '
  visual  =~ x1 + x2 + x3
  textual =~ x4 + x5 + x6
  speed   =~ x7 + x8 + x9

  visual  ~~ 0*textual
  visual  ~~ 0*speed
  textual ~~ 0*speed
'

Fit the constrained model:

cfa.fit.orthogonal <- lavaan::cfa(
  HS.orthogonal,
  data = lavaan::HolzingerSwineford1939,
  estimator = "ML"
)

The operator ~~ represents a variance or covariance relation. Thus,

visual ~~ 0*textual

fixes the covariance between the two factors to zero.

WarningConstraints need a reason

Software allows us to fix almost any parameter to almost any value. Statistical possibility is not theoretical justification. Constraints should represent a substantive hypothesis whenever possible.

6.14 Inspect Modification Indices

We can inspect the largest modification indices with:

mi <- modindices(cfa.fit, sort. = TRUE)

head(mi, 10)
lhs op rhs mi epc sepc.lv sepc.all sepc.nox
30 visual =~ x9 36.411031 0.5770215 0.5191001 0.5152491 0.5152491
76 x7 x8 34.145089 0.5364440 0.5364440 0.8591510 0.8591510
28 visual =~ x7 18.630638 -0.4218624 -0.3795158 -0.3489088 -0.3489088
78 x8 x9 14.946392 -0.4230959 -0.4230959 -0.8052026 -0.8052026
33 textual =~ x3 9.150895 -0.2716376 -0.2688377 -0.2380993 -0.2380993
55 x2 x7 8.918022 -0.1827254 -0.1827254 -0.1919302 -0.1919302
31 textual =~ x1 8.902732 0.3503311 0.3467201 0.2974884 0.2974884
51 x2 x3 8.531827 0.2182393 0.2182393 0.2230502 0.2230502
59 x3 x5 7.858085 -0.1300947 -0.1300947 -0.2119402 -0.2119402
26 visual =~ x5 7.440646 -0.2098980 -0.1888284 -0.1465688 -0.1465688

A large modification index suggests that freeing a currently fixed parameter may improve the fit of the model. Before doing so, inspect the parameter itself and ask whether the additional relation is theoretically plausible.

6.15 CFA with Ordinal Indicators

Many psychological items are ordered categorical rather than continuous. For example, Likert-type responses such as

Strongly disagree → Disagree → Neutral → Agree → Strongly agree

are ordinal indicators.

For ordered endogenous variables, lavaan can fit the CFA using WLSMV. The following template assumes that item1 through item8 are ordinal:

ordinal_items <- paste0("item", 1:8)

ordinal.model <- '
  Factor1 =~ item1 + item2 + item3 + item4
  Factor2 =~ item5 + item6 + item7 + item8
'

ordinal.fit <- lavaan::cfa(
  ordinal.model,
  data = mydata,
  ordered = ordinal_items,
  estimator = "WLSMV"
)

summary(
  ordinal.fit,
  fit.measures = TRUE,
  standardized = TRUE
)

For ordered categorical indicators, the estimator and fit indices should be interpreted in the context of categorical-data methods rather than by automatically importing cutoffs developed for continuous maximum- likelihood CFA (Xia & Yang, 2019).

6.16 Factor Scores

After fitting a CFA, we can estimate factor scores for individual cases:

factor_scores <- lavPredict(cfa.fit)

head(factor_scores)
          visual     textual       speed
[1,] -0.81767524 -0.13754501  0.06150726
[2,]  0.04951940 -1.01272402  0.62549360
[3,] -0.76139670 -1.87228634 -0.84057276
[4,]  0.41934153  0.01848569 -0.27133710
[5,] -0.41590481 -0.12225009  0.19432951
[6,]  0.02325632 -1.32981727  0.70885348

Factor scores can be useful for some downstream purposes, but they are estimated model-dependent quantities, not directly observed trait values. Different factor-score estimators and different measurement models can produce different scores.

WarningDo not confuse a factor score with the factor itself

A latent variable remains unobserved. lavPredict() provides an estimate of a person’s location under the fitted model. That estimate contains uncertainty and inherits the assumptions of the CFA.

6.17 A Practical CFA Checklist

Stage Ask yourself
Theory What factor structure am I testing, and why?
Indicators Are these variables appropriate indicators of the proposed factors?
Identification Is the model identified and is the latent scale defined?
Estimator Does the estimator match the type and distribution of the indicators?
Global fit What do \(\chi^2\), RMSEA, CFI, TLI, and SRMR jointly suggest?
Local fit Are there large residuals, cross-loading signals, or modification indices?
Parameters Are loadings, factor correlations, and residual variances plausible?
Alternatives Could another theoretically plausible model explain the same data?
Interpretation Does the statistical model justify the psychological claims I want to make?

6.18 Reporting a CFA

A useful report should identify the model, estimator, data type, sample size, and the main evidence used to evaluate the model.

For example:

A three-factor confirmatory factor analysis was fitted to the nine Holzinger–Swineford indicators using maximum likelihood estimation. The model specified visual, textual, and speed factors, each measured by three indicators. Model fit was evaluated using the chi-square test, CFI, TLI, RMSEA with its confidence interval, and SRMR. Standardized factor loadings and factor correlations were also inspected. The interpretation of fit considered the pattern of indices and parameter estimates rather than applying any single cutoff as a definitive criterion.

When reporting your own analysis, replace this general description with the actual estimates obtained from your fitted model.

6.19 Concluding Remarks

CFA is powerful because it turns a measurement theory into a set of explicit statistical restrictions. A researcher specifies which indicators represent which factors, how factors are allowed to relate, and which parameters are fixed or estimated. The observed data can then be used to evaluate the consequences of that specification.

The most important lesson, however, is that model fit is not the same as model truth. CFI, TLI, RMSEA, SRMR, and the chi-square test summarize different aspects of correspondence between the model and the observed data, but they do not establish the psychological meaning of the latent variables or prove the causal assumptions that motivated the model. Flexible models can also achieve good fit simply because they have more ways to reproduce the data (Bonifay & Cai, 2017).

CFA is therefore best understood as one part of a broader validation process. Its strongest use is not to obtain a collection of acceptable fit indices, but to confront a theoretically meaningful measurement model with empirical evidence and identify where the theory and data agree—or where they do not.