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)
