ANALYSIS CLINIC · CASE 002

CASE STATUS: DIAGNOSED

My model won't run · Mixed models · R/lme4

Why Am I Getting a Singular Fit in My Mixed Model?

A singular fit means your model estimated fewer distinguishable random-effect dimensions than you asked it to estimate. It may reflect a genuine near-zero variance, a structure the sample cannot support, or a design or coding problem. Diagnose which explanation fits before changing the model.

01

Symptoms

You fit a linear or generalized linear mixed model with lmer() or glmer(), and lme4 prints:

boundary (singular) fit: see help('isSingular')

The model may still print coefficients, standard errors, and optimizer convergence code 0. That is not a contradiction. Optimization and singularity answer different questions: the optimizer can finish at a solution whose estimated random-effects covariance matrix lies on or near the boundary.

In a simple intercept–slope model, look for a variance near zero, a correlation near −1 or 1, or isSingular(fit) returning TRUE. With three or more random effects, the deficient dimension may not be obvious in the printed components.

02

What This Usually Means

The model requested more independent random-effect variation than the fitted data could distinguish. At least one estimated random-effects covariance matrix is not full rank, or is close enough to rank deficient to trigger lme4's diagnostic tolerance.

This does not prove that the software failed, that the entire mixed model is invalid, or that a population variance is exactly zero. A maximum-likelihood estimate can legitimately fall on the boundary. The message still matters because it can reveal an overextended specification, weak information about a variance component, or a design limitation that affects inference.

03

Common Causes

1. Too much covariance structure

The model requests several variances and correlations from too few independent groups or too little repeated information.

2. A genuinely small variance

The outcome may vary across groups in baseline level but show little detectable between-group variation in a particular slope.

3. Too little within-group variation

A random slope cannot be learned from groups in which its predictor does not change and is weakly learned from narrow or sparse ranges.

4. Redundant components

Two requested dimensions may describe nearly the same pattern, producing a boundary correlation or a near-zero orthogonal dimension.

5. Coding problems

Incorrect IDs, duplicated cluster labels across higher levels, unused levels, or an unintended variable type can change the fitted structure.

6. A weakly informative design

Sparse groups, severe imbalance, or few measurements at the relevant level may leave sensible variance components poorly determined.

04

Run These Checks

  1. Preserve the message, formula, version, and optimizer result.

    formula(fit)
    packageVersion("lme4")
    fit@optinfo$conv

    What it suggests: Code 0 with a singular-fit message means optimization completed but the covariance structure is rank deficient. A separate gradient, Hessian, or evaluation-limit message needs its own convergence investigation.

  2. Confirm and localize the singularity.

    isSingular(fit)
    VarCorr(fit)
    rePCA(fit)

    What it suggests: In simple structures, a near-zero variance or boundary correlation may locate the problem. In larger structures, a near-zero rePCA() standard deviation reveals an unsupported orthogonal dimension.

  3. Audit the grouping structure.

    nlevels(dat$group)
    summary(table(dat$group))
    group_by_site <- xtabs(~ group + site, data = dat)
    table(rowSums(group_by_site > 0))

    What it suggests: Sparse groups point to limited information. If a supposedly site-specific ID appears under multiple sites, correct or uniquely nest it before refitting. No universal group-count cutoff diagnoses singularity.

  4. Check within-group information for every random slope.

    within_group_sd <- aggregate(x ~ group, dat, sd)
    summary(within_group_sd$x)
    table(within_group_sd$x == 0, useNA = "ifany")

    What it suggests: Groups with no variation cannot inform that slope; limited variation across many groups can make its variance and correlations difficult to distinguish.

  5. Check coding, scaling, and the fixed-effect matrix.

    str(dat[c("y", "x", "group")])
    colSums(is.na(dat[c("y", "x", "group")]))
    qr(model.matrix(~ x, data = dat))$rank

    What it suggests: Correct genuine coding or processing problems before reconsidering the scientific random-effects structure. Centering can help interpretation or numerics, but it cannot manufacture missing information.

  6. Compare only defensible candidate structures.

    Identify which random effects follow from the sampling design and which protect the focal inference. Compare a small set of theory- and design-supported alternatives—not arbitrary formulas chosen until the message disappears.

    What it suggests: A persistently near-zero dimension indicates weak support for that component. Strong changes across reasonable specifications are themselves evidence of instability that should be reported.

05

What Not to Do

Do not automatically delete a random slope. If it follows from the design or protects the focal test from unmodeled dependence, removing it changes the model and potentially its uncertainty.

Do not call the fit nonconverged solely because it is singular. Check optimizer diagnostics separately.

Do not switch optimizers and call repeated singularity repaired. Another optimizer cannot create missing random-effect information.

Do not change the tolerance merely to obtain FALSE. That changes the diagnostic rule, not the information in the data.

Do not remove correlations mechanically with ||. Zero correlation is a model assumption, and a near-zero variance can remain.

Do not infer that a population variance is exactly zero. A boundary estimate is conditional on the fitted data and model.

06

Treatment Options

Correct coding or structure

Use when: IDs, types, contrasts, levels, or missingness exclusions are wrong.

Tradeoff: genuine errors must be corrected; convenient recoding that changes the question needs stronger justification.

Simplify an unsupported component

Use when: design review and diagnostics consistently locate a component whose removal preserves the focal estimand.

Tradeoff: the simpler model assumes greater homogeneity and may understate uncertainty if the omitted variation is real but weakly estimated.

Remove selected correlations

Use when: variances are meaningful but covariance parameters are weakly supported, and an uncorrelated structure was defensible.

Tradeoff: zero correlation is an assumption and does not cure a near-zero variance.

lmer(y ~ x + (1 + x || group), data = dat)

Use a regularizing model

Use when: a Bayesian or penalized analysis is justified and credible priors can stabilize weak covariance estimation.

Tradeoff: conclusions depend on the prior or penalty and require sensitivity analysis; regularization cannot repair an uninformative design.

Plan more informative data

Use when: the scientific question requires variance the present design cannot estimate.

Tradeoff: this rarely repairs a completed dissertation dataset and may narrow the claims possible now.

Treatment principle: represent the sampling design and support the focal inference—not merely remove the singular-fit message.

07

Worked Example

This controlled example generates 240 observations in 30 groups. It contains genuine random-intercept variation but no random-slope variation, then asks lme4 to estimate both.

library(lme4)
set.seed(1)
n_groups <- 30
n_per_group <- 8
group <- factor(rep(seq_len(n_groups), each = n_per_group))
x <- rep(as.numeric(scale(seq_len(n_per_group), scale = FALSE)), n_groups)
random_intercept <- rnorm(n_groups, 0, 1)
y <- 5 + 0.6 * x + random_intercept[group] + rnorm(n_groups * n_per_group)
dat <- data.frame(y, x, group)

fit_singular <- lmer(y ~ x + (1 + x | group), data = dat)
fit_singular@optinfo$conv$opt
isSingular(fit_singular)
VarCorr(fit_singular)
rePCA(fit_singular)

fit_supported <- lmer(y ~ x + (1 | group), data = dat)
isSingular(fit_supported)

Requested intercept and slope: convergence code = 0; isSingular = TRUE; slope variance = 8.330494e-04; correlation = 1; PCA SDs = 1.032971e+00, 1.904998e-05.

Known generating structure: random-intercept fit has isSingular = FALSE. Both controlled fits estimate the fixed slope as 0.578134.

Interpretation: Optimization completed, but the requested covariance matrix contains a near-zero dimension. The random-intercept model is justified here because the generating process is known. Equal fixed-slope estimates in this example do not show that simplification is harmless in other datasets.

Download the complete verified R script

08

What to Tell Your Committee

Explain the reasoning rather than saying that a term was removed because R printed a message:

  1. Original structure: connect each random effect to the sampling design, repeated measurements, or focal hypothesis.
  2. Diagnosis: report the exact message, optimizer result, isSingular(), and the component or PCA dimension that located the boundary.
  3. Available information: summarize independent groups, group sizes, within-group predictor variation, imbalance, and coding checks.
  4. Response: explain what was corrected, retained, simplified, decorrelated, or regularized and whether that changed the estimand.
  5. Sensitivity: compare the focal estimate and uncertainty across the small set of defensible specifications and disclose instability.

A defensible explanation shows what the model asked the data to estimate, which dimension was unsupported, why the final structure still represents the design, and what the change means for the claim.

09 · ANALYSIS CLINIC

When You Need More Help

Still stuck?

The checks above often locate a near-zero variance, boundary correlation, miscoded group, or lack of within-group information. Crossed, nested, longitudinal, or generalized models may require closer review of the design matrix, sampling levels, focal contrast, and competing structures.

Bring your model to the Analysis Clinic. For education studies, the Multilevel and Hierarchical Models workflow provides cluster audits, centering decisions, random-intercept and random-slope models, cross-level interactions, and reproducible diagnostics.

Use the multilevel workflow