Reputation: 995
I'm trying to run a relatively straightforward glmer model and get warnings that it isSingular and I can't figure out why.
In my dataset, 40 participants did 108 trials. They responded to a question (the response is coded as correct/incorrect - 0/1) and rated confidence in their response on a continuous scale from 0 to 1.
library(lme4)
library(tidybayes)
library(tidyverse)
set.seed(5)
n_trials = 108
n_subjs = 40
data =
tibble(
subject = as.factor(rep(c(1:n_subjs), n_trials)),
correct = sample(c(0,1), replace=TRUE, size=(n_trials*n_subjs)),
confidence = runif(n_trials*n_subjs)
)
I'm trying to run a mixed effects logistic regression, to estimate each participant's ability to associate high confidence to correct responses only. That means, I have good reasons to add the random slope of confidence in my model.
The simplest model that I'm interested in gives me:
model = glmer(correct ~ confidence + (confidence|subject) ,
data = data,
family = binomial)
boundary (singular) fit: see ?isSingular, and
> isSingular(model)
[1] TRUE
So I simplify the model beyond usefulness, and get the same problem:
model = glmer(correct ~ confidence + (1|subject) ,
data = data,
family = binomial)
I tried to bin confidence (I'm sure there are more elegant ways), in case that helped, but it didn't:
#Initialize as vector of 0s
data$confidence_binned <- numeric(dim(data)[1])
nbins = 4
bins=seq(0,1,length.out = (nbins+1))
for (b in 1:(length(bins)-1)) {
data$confidence_binned[data$confidence>=bins[b] & data$confidence<bins[b+1]] = b
}
data$confidence_binned[data$confidence_binned==1]=nbins
model = glmer(correct ~ confidence_binned + (confidence_binned|subject) ,
data = data,
family = binomial)
boundary (singular) fit: see ?isSingular
There are many posts and SO questions about the isSingular
warning, but all the ones I've found say that the model is too complex for the data, and the solution is usually to 'keep it maximal'. However, this model is as simple as it can get, and I am confused that with (what sounds to me like) enough trials it still fails.
I also tried changing the controller, but it didn't help:
ctrl = glmerControl(optimizer = "bobyqa",
boundary.tol = 1e-5,
calc.derivs=TRUE,
use.last.params=FALSE,
sparseX = FALSE,
tolPwrss=1e-7,
compDev=TRUE,
nAGQ0initStep=TRUE,
## optimizer args
optCtrl = list(maxfun = 1e5))
model <- glmer(correct ~ confidence_binned + (confidence_binned|subject),
data=data,
verbose=T,
control=ctrl,
family = binomial)
Any help or pointers on what to look out for in the data are appreciated.
EDIT to respond to a comment:
The result of ggplot(data,aes(x=subject, y=correct)) + stat_summary(fun.data=mean_cl_normal)
Upvotes: 5
Views: 539
Reputation: 3228
GLMMs with random slopes and random intercepts correlated (aka the maximal model) are notoriously difficult to fit even under well-fitting data despite some who advocate for this approach. Unless you see some seriously fluctuating by-subject or by-item variance with their random slope predictors, my best advice is to fit a random intercepts only model and see if it fits better.
For three comprehensive papers that have very different views on this subject, see below. The first is a paper often cited for the maximal approach. The second is written by the guy who created the lme4
package, who makes arguments for parsimonious models. The third is an additional peer-reviewed paper by Bates recommended by Ben Bolker.
Citations:
Upvotes: 1