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] |
Maintainer: | Iago Giné-Vázquez <[email protected]> |
License: | GPL-3 |
Version: | 0.1.2 |
Built: | 2024-10-31 19:47:24 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.ID
a factor with levels 10185
10186
10250
tm
a factor with levels CT
PT-04
ValidDetections
a numeric vector
CountDetections
a numeric vector
FalseDetections
a numeric vector
replicate
a factor with levels 1
2
Area
a factor with levels Drug Channel
Finger
Day
a factor with levels 03/06/13
2/22/13
2/26/13
2/27/13
3/14/13
R.det
a numeric vector
c.receiver.depth
a numeric vector
c.tm.depth
a numeric vector
c.temp
a numeric vector
c.wind
a numeric vector
c.distance
a 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_dead
an integer vector
AGE
an integer vector
ZIP
an 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_dead
an integer vector
AGE
an integer vector
ZIP
an 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 NULL
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 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.
Line
a 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
Rep
a factor with levels 1
2
Weight
a numeric vector
PLANT
a factor with levels 1
2
3
4
X
a 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.
plot
a numeric vector
date
a character vector
total_no
a numeric vector
zone
a character vector
treatment
a character vector
week
a numeric vector
fzone
a 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)