2
$\begingroup$

I'm getting the warning boundary (singular) fit: see ?isSingular with this dataset

set.seed(12)
x=rnorm(600,50,9)
error=rnorm(600,0,16)
y=150-(4*x1)+(2.5*x1)+error
ID = rep(c("ID1","ID2","ID3","ID4","ID5","ID6"), each=100)
t = rep(c(1:100), times=6)
df <- data.frame(x=x, ID=ID, y=y, t=t)

m <- lmer(y ~ x + (1|ID), data=df)

I figured out that the problem is with the 100 time points per ID. If I go down to 30 time points:

df2 = df[df$t<30,]
m <- lmer(y ~ x + (1|ID), data=df2)

the warning disappears.

This is also happening with my actual data which have more than 200 time points per ID and over 600 IDs. It seems there is a limit to which lmer can estimate models with many time points per ID.

I will have to work with the data I have, so what is the recommendation to model large data such as these in lmer? There is a strong correlation between ID and the DV and IV in most IDs in my data, so I know they are strongly associated. What are my options?

$\endgroup$

1 Answer 1

3
$\begingroup$

In your example, the warning "boundary (singular) fit" does't have anything to do with the number of points per ID. You use the wrong model for the data you've simulated.

You simulate data with a fixed effect and no random subject effect. The LMM observes no variability within subjects, so $\sigma^2_{\operatorname{subject}} = 0$. Hence a singular fit.

We don't know anything about your actual data. In general, strong correlation between a fixed predictor and the outcome provides no information about the within-subject variability, if any.

It might help to think more about the within-subject correlation structure. The specification (1 | ID) means that, for each subject, the correlation between the first and last observations, $Y_{i,1}$ and $Y_{i,t}$, is the same as the correlation between the next-to-last and last observations, $Y_{i,t-1}$ and $Y_{i,t}$. This might not be a realistic assumption, esp. when data has many observations per subject collected over a long period of time.

Note: If you'd like to explore different within-subject correlation structures, it might be easier to switch from lme4 to glmmTMB. See for example the vignette Covariance structures with glmmTMB.


Here are some in-depth CV discussions on this complex topic. Some of them might not be directly relevant to your study since you have a lot of subjects.

Why do I get zero variance of a random effect in my mixed model, despite some variation in the data?
singular fit in lmer, despite no high correlations of random effects
Random effect equal to 0 in generalized linear mixed model
Singular fit with simplest random structure in glmer (lme4)?

The code below demonstrates that if the data is simulated from the correct mixed-effects model, lmer estimates the true parameters correctly and without warnings.

library("lme4")

set.seed(12)

ntimes <- 100
nsubjects <- 6

x <- rnorm(nsubjects * ntimes, 50, 9)
t <- rep(seq(ntimes), times = nsubjects)
ID <- rep(seq(nsubjects), each = ntimes)

error <- rnorm(nsubjects * ntimes, 0, 16)

In your simulation there is no random subject effect.

y <- 150 - 1.5 * x + error # No extra variability with subjects
m <- lmer(y ~ x + (1 | ID))
#> boundary (singular) fit: see help('isSingular')

# The estimate of sigma_subject is `sd__(Intercept)`.
broomExtra::tidy(m)
#> # A tibble: 4 × 6
#>   effect   group    term            estimate std.error statistic
#>   <chr>    <chr>    <chr>              <dbl>     <dbl>     <dbl>
#> 1 fixed    <NA>     (Intercept)       144.      3.79        38.0
#> 2 fixed    <NA>     x                  -1.38    0.0754     -18.3
#> 3 ran_pars ID       sd__(Intercept)     0      NA           NA  
#> 4 ran_pars Residual sd__Observation    15.7    NA           NA

Now let's simulate a true random effect for each subject.

z <- 3 * rep(rnorm(nsubjects), each = ntimes)

y <- 150 - 1.5 * x + z + error
m <- lmer(y ~ x + (1 | ID)) # No warning about singular fit

broomExtra::tidy(m)
#> # A tibble: 4 × 6
#>   effect   group    term            estimate std.error statistic
#>   <chr>    <chr>    <chr>              <dbl>     <dbl>     <dbl>
#> 1 fixed    <NA>     (Intercept)      143.       3.82        37.5
#> 2 fixed    <NA>     x                 -1.38     0.0756     -18.3
#> 3 ran_pars ID       sd__(Intercept)    0.838   NA           NA  
#> 4 ran_pars Residual sd__Observation   15.7     NA           NA
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.