| Title: | Troubles Solver for 'lme4' |
|---|---|
| Description: | The main function of the package aims to update 'lmer()'/'glmer()' models depending on their warnings, so trying to avoid convergence and singularity problems. |
| Authors: | Iago Giné-Vázquez [aut, cre] (ORCID: <https://orcid.org/0000-0002-6725-2638>) |
| Maintainer: | Iago Giné-Vázquez <[email protected]> |
| License: | GPL-3 |
| Version: | 0.1.4 |
| Built: | 2026-06-01 12:10:47 UTC |
| Source: | https://gitlab.com/iagogv/troubblme4solver |
Updates a (possibly generalized) linear mixed model computed with the
library lme4 functions lmer or glmer, in order to
elude some singularity or convergence problems informed by distinct
warnings or messages.
dwmw(lmmodel, boundary_check = TRUE, scale = FALSE, scale_info = TRUE, tol = 1e-4, max_message_iter = 7, pri_nAGQ = FALSE, max_nAGQ = 6, next_optimizer = "bobyqa", next_optCtrl = list(maxfun = 2e5), when_next = max_message_iter - 1, verbose = FALSE)dwmw(lmmodel, boundary_check = TRUE, scale = FALSE, scale_info = TRUE, tol = 1e-4, max_message_iter = 7, pri_nAGQ = FALSE, max_nAGQ = 6, next_optimizer = "bobyqa", next_optCtrl = list(maxfun = 2e5), when_next = max_message_iter - 1, verbose = FALSE)
lmmodel |
The model of interest, output of either
|
boundary_check |
A length 1 boolean object ( |
scale |
A length 1 boolean object ( |
scale_info |
A length 1 boolean object ( |
tol |
A numeric value (default is |
max_message_iter |
A numeric value (default is |
pri_nAGQ |
A length 1 boolean object ( |
max_nAGQ |
A numeric value (default is |
next_optimizer |
An optimizer (default is |
next_optCtrl |
A |
when_next |
A numeric value not greater than
|
verbose |
A length 1 boolean object ( |
specifying if function iterations and model updating should be verbose.
If the model does not generate any warning or message, dwmw
returns itself. The function rescales numeric predictors if some
warning or message suggests it and the scale argument is
TRUE. If the model fails to converge, it only updates the starting
values for the parameters in the model through the first
when_next - 1 iterations, while it also updates the optimizer
and their arguments through the next iterations.
If the model is singular (there is a
"boundary (singular)"-alike message) and boundary_check
is TRUE, the formula is updated removing the random effects
which cause the model to be singular. If all the random effects are
removed, a linear or generalized linear model is computed according to
the lmmodel object.
If the model has subclass glmerMod, a single scalar random
effect and converges but it is nearly unidentifiable with a very large
eigenvalue, then nAGQ is increased one unity while nAGQ
<= max_nAGQ (and only in this case, allowing the iterations to exceed
max_message_iter until nAGQ == max_nAGQ).
Generally, an object of class
merMod, being either an object of
subclass glmerMod or an object of subclass
lmerMod, corresponding to the input lmmodel
argument. When all random effects are removed, an object of
class glm or lm depending also on the input
lmmodel.
Iago Giné-Vázquez, [email protected]
lmer, glmer,
merMod lmerControl,
convergence, troubleshooting,
isSingular, lm and
glm.
if(requireNamespace("nlme")){ library(lme4) data(Orthodont, package = "nlme") Orthodont$nsex <- as.numeric(Orthodont$Sex == "Male") Orthodont$nsexage <- with(Orthodont, nsex*age) ## Without using dwmw, the next model is singular fmo <- lmer(distance ~ age + (age|Subject) + (0+nsex|Subject) + (0 + nsexage|Subject), data = Orthodont) summary(fmo) ## Using dwmw, we remove the singularity of the model fmo1 <- dwmw(lmer(distance ~ age + (age|Subject) + (0+nsex|Subject) + (0 + nsexage|Subject), data = Orthodont)) summary(fmo1) ## It also can be used on the output object fmo2 <- dwmw(fmo) summary(fmo2) }if(requireNamespace("nlme")){ library(lme4) data(Orthodont, package = "nlme") Orthodont$nsex <- as.numeric(Orthodont$Sex == "Male") Orthodont$nsexage <- with(Orthodont, nsex*age) ## Without using dwmw, the next model is singular fmo <- lmer(distance ~ age + (age|Subject) + (0+nsex|Subject) + (0 + nsexage|Subject), data = Orthodont) summary(fmo) ## Using dwmw, we remove the singularity of the model fmo1 <- dwmw(lmer(distance ~ age + (age|Subject) + (0+nsex|Subject) + (0 + nsexage|Subject), data = Orthodont)) summary(fmo1) ## It also can be used on the output object fmo2 <- dwmw(fmo) summary(fmo2) }
Two integer variables (ValidDetections and
FalseDetections) to build an outcome, two factor
variables to be used as clusters for the random effects
(SUR.ID and Day), three factor variables to be
used as fixed effects (tm, Area and
replicate), five numeric variables to be used as fixed
effects (c.distance, c.tm.depth,
c.receiver.depth, c.temp and c.wind) and a
pair of variables extra, allowing to build a model which fails
to converge.
data("fly_parameters")data("fly_parameters")
A data frame with 220 observations on the following 14 variables.
SUR.IDa factor with levels 10185 10186 10250
tma factor with levels CT PT-04
ValidDetectionsa numeric vector
CountDetectionsa numeric vector
FalseDetectionsa numeric vector
replicatea factor with levels 1 2
Areaa factor with levels Drug Channel Finger
Daya factor with levels 03/06/13 2/22/13 2/26/13 2/27/13 3/14/13
R.deta numeric vector
c.receiver.deptha numeric vector
c.tm.deptha numeric vector
c.tempa numeric vector
c.winda numeric vector
c.distancea numeric vector
warning messages when trying to run glmer in r
data(fly_parameters) str(fly_parameters) df <- fly_parameters df$SUR.ID <- factor(df$SUR.ID) df$replicate <- factor(df$replicate) Rdet <- cbind(df$ValidDetections,df$FalseDetections) Unit <- factor(1:length(df$ValidDetections)) library(lme4) m1 <- glmer(Rdet ~ tm:Area + tm:c.distance + c.distance:Area + c.tm.depth:Area + c.receiver.depth:Area + c.temp:Area + c.wind:Area + c.tm.depth + c.receiver.depth + c.temp +c.wind + tm + c.distance + Area + replicate + (1|SUR.ID) + (1|Day) + (1|Unit) , data = df, family = binomial(link="logit")) summary(m1) m1_new <- dwmw(m1, scale = TRUE, max_message_iter = 3) summary(m1_new)data(fly_parameters) str(fly_parameters) df <- fly_parameters df$SUR.ID <- factor(df$SUR.ID) df$replicate <- factor(df$replicate) Rdet <- cbind(df$ValidDetections,df$FalseDetections) Unit <- factor(1:length(df$ValidDetections)) library(lme4) m1 <- glmer(Rdet ~ tm:Area + tm:c.distance + c.distance:Area + c.tm.depth:Area + c.receiver.depth:Area + c.temp:Area + c.wind:Area + c.tm.depth + c.receiver.depth + c.temp +c.wind + tm + c.distance + Area + replicate + (1|SUR.ID) + (1|Day) + (1|Unit) , data = df, family = binomial(link="logit")) summary(m1) m1_new <- dwmw(m1, scale = TRUE, max_message_iter = 3) summary(m1_new)
Removes those random effects from a model formula making the model to be singular.
fstruction(model, tol = 1e-4)fstruction(model, tol = 1e-4)
model |
The model of interest, output of either
|
tol |
A numeric value (default is |
A list with a string component dstring which is the formula as
character updated (to be used by update) after removing the
singular random effects and, when no all the random effects are
removed two other string components:
betchar: a character vector with the random effect
terms removed from the formula.
inchar: a character vector having the same length as
betchar with the corresponding groups (aggregate levels) for
which the random effects are removed.
Iago Giné-Vázquez, [email protected]
if(requireNamespace("nlme")){ library(lme4) data(Orthodont, package = "nlme") Orthodont$nsex <- as.numeric(Orthodont$Sex == "Male") Orthodont$nsexage <- with(Orthodont, nsex*age) ## The next model is singular fmo <- lmer(distance ~ age + (age|Subject) + (0+nsex|Subject) + (0 + nsexage|Subject), data = Orthodont) summary(fmo) ## Let's see the formula updated (as a string) fstruction(fmo) }if(requireNamespace("nlme")){ library(lme4) data(Orthodont, package = "nlme") Orthodont$nsex <- as.numeric(Orthodont$Sex == "Male") Orthodont$nsexage <- with(Orthodont, nsex*age) ## The next model is singular fmo <- lmer(distance ~ age + (age|Subject) + (0+nsex|Subject) + (0 + nsexage|Subject), data = Orthodont) summary(fmo) ## Let's see the formula updated (as a string) fstruction(fmo) }
Three variables, being one dichotomous, other continuous and the last,
categorical. Data for the first reproducible example for issue 618 on
the lme4 Github-repository, making glmer to produce a
Model is nearly unidentifiable: very large eigenvalue - Rescale variables?
warning for the model outcome_dead ~ AGE +
(1|ZIP).
data("issue618")data("issue618")
A data frame with 1000 observations on the following 3 variables.
outcome_deadan integer vector
AGEan integer vector
ZIPan integer vector
convergence issues with continuous variables in model
data(issue618) str(issue618) library(lme4) m1<- glmer(outcome_dead ~ AGE + (1|ZIP), family = binomial, data = issue618) summary(m1) m2 <- dwmw(m1, scale = TRUE) summary(m2)data(issue618) str(issue618) library(lme4) m1<- glmer(outcome_dead ~ AGE + (1|ZIP), family = binomial, data = issue618) summary(m1) m2 <- dwmw(m1, scale = TRUE) summary(m2)
Three variables, being one dichotomous, other continuous and the last,
categorical. Data for the first reproducible example for issue 618 on
the lme4 Github-repository, making glmer to produce a
Model is nearly unidentifiable: very large eigenvalue - Rescale variables?
warning for the model outcome_dead ~ AGE +
(1|ZIP).
data("issue618")data("issue618")
A data frame with 1000 observations on the following 3 variables.
outcome_deadan integer vector
AGEan integer vector
ZIPan integer vector
convergence issues with continuous variables in model
data(issue618large) str(issue618large) library(lme4) m1<- glmer(outcome_dead ~ AGE + (1|ZIP), family = binomial, data = issue618large) summary(m1) m2 <- dwmw(m1, scale = TRUE) summary(m2) m3 <- glmer(outcome_dead ~ scale(AGE) + (1|ZIP), family = binomial, data = issue618large, nAGQ=20) aa <- allFit(m3) ss <- summary(aa) ss$msgs ## all NULLdata(issue618large) str(issue618large) library(lme4) m1<- glmer(outcome_dead ~ AGE + (1|ZIP), family = binomial, data = issue618large) summary(m1) m2 <- dwmw(m1, scale = TRUE) summary(m2) m3 <- glmer(outcome_dead ~ scale(AGE) + (1|ZIP), family = binomial, data = issue618large, nAGQ=20) aa <- allFit(m3) ss <- summary(aa) ss$msgs ## all NULL
Five variables, being one continuous to use as outcome
(Weight), and four factors, of which two (Rep and
PLANT) are used as clusters for the random effects of a
singular linear mixed model (Weight ~ 1 + (1|Rep:PLANT)).
data("plants")data("plants")
A data frame with 536 observations on the following 5 variables.
Linea factor with levels Line1 Line10 Line11 Line12 Line13 Line14 Line15 Line16 Line17 Line18 Line19 Line2 Line20 Line21 Line22 Line23 Line24 Line25 Line26 Line27 Line28 Line29 Line3 Line30 Line31 Line32 Line33 Line34 Line35 Line36 Line37 Line38 Line39 Line4 Line40 Line41 Line42 Line43 Line44 Line45 Line46 Line47 Line48 Line49 Line5 Line50 Line51 Line52 Line53 Line54 Line55 Line56 Line57 Line58 Line59 Line6 Line60 Line61 Line62 Line63 Line64 Line65 Line66 Line67 Line7 Line8 Line9
Repa factor with levels 1 2
Weighta numeric vector
PLANTa factor with levels 1 2 3 4
Xa factor with levels 24 12 21 11 13 14 22 23
lme4 error: boundary (singular) fit: see ?isSingular
data(plants) str(plants) library(lme4) fit <- lmer(Weight ~ 1 + (1|PLANT:Rep), data = plants) summary(fit) fit2 <- dwmw(fit) summary(fit2)data(plants) str(plants) library(lme4) fit <- lmer(Weight ~ 1 + (1|PLANT:Rep), data = plants) summary(fit) fit2 <- dwmw(fit) summary(fit2)
A continuous variable to be used as outcome (total_no), another
to be used as predictor (week), two factor variables to be used
as predictors (treatment and fzone) and another factor
to be used as cluster for the random effects (plot) of a
Poisson model failing to converge, and an extra variable.
data("treatments")data("treatments")
A data frame with 142 observations on the following 7 variables.
plota numeric vector
datea character vector
total_noa numeric vector
zonea character vector
treatmenta character vector
weeka numeric vector
fzonea character vector
lme4: glmer() warning messages with count data mixed-effects model and how to proceed with model fit
data(treatments) str(treatments) library(lme4) glmm.1 <- glmer(total_no ~ week*treatment*fzone + (1|plot), data = treatments, family = poisson) summary(glmm.1) glmm.11 <- dwmw(glmm.1, verbose = TRUE) summary(glmm.11)data(treatments) str(treatments) library(lme4) glmm.1 <- glmer(total_no ~ week*treatment*fzone + (1|plot), data = treatments, family = poisson) summary(glmm.1) glmm.11 <- dwmw(glmm.1, verbose = TRUE) summary(glmm.11)