| Title: | Stepwise Elimination and Term Reordering for Mixed-Effects Regression |
|---|---|
| Description: | Finds the largest possible regression model that will still converge for various types of regression analyses (including mixed models and generalized additive models) and then optionally performs stepwise elimination similar to the forward and backward effect-selection methods in SAS, based on the change in log-likelihood or its significance, Akaike's Information Criterion, the Bayesian Information Criterion, the explained deviance, or the F-test of the change in R². |
| Authors: | Cesko C. Voeten [aut, cre] (ORCID: <https://orcid.org/0000-0003-4687-9973>) |
| Maintainer: | Cesko C. Voeten <[email protected]> |
| License: | FreeBSD |
| Version: | 2.12 |
| Built: | 2026-06-08 08:13:23 UTC |
| Source: | https://gitlab.com/cvoeten/buildmer |
The buildmer package consists of a number of functions, each designed to fit specific types of models (e.g. buildmer for mixed-effects regression, buildgam for generalized additive models, buildmertree for mixed-effects-regression trees, and so forth). The common parameters shared by all (or most of) these functions are documented in buildmerControl. For function-specific details, see the documentation for each individual function.
Maintainer: Cesko C. Voeten [email protected] (ORCID)
Useful links:
Report bugs at https://gitlab.com/cvoeten/buildmer/-/issues
Adds terms to a formula
add.terms(formula, add)add.terms(formula, add)
formula |
The formula to add terms to. |
add |
A vector of terms to add. To add terms nested in random-effect groups, use ‘(term|group)’ syntax if you want to add an independent random effect (e.g. ‘(olderterm|group) + (term|group)’), or use ‘term|group’ syntax if you want to add a dependent random effect to a pre-existing term group (if no such group exists, it will be created at the end of the formula). |
The updated formula.
library(buildmer) form <- Reaction ~ Days + (1|Subject) add.terms(form,'Days|Subject') add.terms(form,'(0+Days|Subject)') add.terms(form,c('many','more|terms','to|terms','(be|added)','to|test'))library(buildmer) form <- Reaction ~ Days + (1|Subject) add.terms(form,'Days|Subject') add.terms(form,'(0+Days|Subject)') add.terms(form,c('many','more|terms','to|terms','(be|added)','to|test'))
Converts a buildmer term list into a proper model formula
build.formula(dep, terms, env = parent.frame())build.formula(dep, terms, env = parent.frame())
dep |
The dependent variable. |
terms |
The term list. |
env |
The environment of the formula to return. |
A formula.
library(buildmer) form1 <- Reaction ~ Days + (Days|Subject) terms <- tabulate.formula(form1) form2 <- build.formula(dep='Reaction',terms) # check that the two formulas give the same results library(lme4) check <- function(f) resid(lmer(f,sleepstudy)) all.equal(check(form1),check(form2)) # can also do double bars now form1 <- Reaction ~ Days + (Days||Subject) terms <- tabulate.formula(form1) form2 <- build.formula(dep='Reaction',terms) all.equal(check(form1),check(form2))library(buildmer) form1 <- Reaction ~ Days + (Days|Subject) terms <- tabulate.formula(form1) form2 <- build.formula(dep='Reaction',terms) # check that the two formulas give the same results library(lme4) check <- function(f) resid(lmer(f,sleepstudy)) all.equal(check(form1),check(form2)) # can also do double bars now form1 <- Reaction ~ Days + (Days||Subject) terms <- tabulate.formula(form1) form2 <- build.formula(dep='Reaction',terms) all.equal(check(form1),check(form2))
buildmer to fit big generalized additive models using bam from package mgcv
Uses buildmer to fit big generalized additive models using bam from package mgcv
buildbam( formula, data = NULL, family = gaussian(), buildmerControl = buildmerControl() )buildbam( formula, data = NULL, family = gaussian(), buildmerControl = buildmerControl() )
formula |
See the general documentation under |
data |
See the general documentation under |
family |
See the general documentation under |
buildmerControl |
Control arguments for buildmer — see the general documentation under |
To work around an issue in bam, you must make sure that your data do not contain a variable named 'intercept'.
lme4 random effects are supported: they will be automatically converted using re2mgcv.
In the generalized case, bam only returns the correct ML/REML values as of mgcv 1.9-4.
library(buildmer) model <- buildbam(f1 ~ s(timepoint,by=following) + s(participant,by=following,bs='re') + s(participant,timepoint,by=following,bs='fs'),data=vowels)library(buildmer) model <- buildbam(f1 ~ s(timepoint,by=following) + s(participant,by=following,bs='re') + s(participant,timepoint,by=following,bs='fs'),data=vowels)
buildmer to fit cumulative link mixed models using clmm from package ordinal
Uses buildmer to fit cumulative link mixed models using clmm from package ordinal
buildclmm(formula, data = NULL, buildmerControl = buildmerControl())buildclmm(formula, data = NULL, buildmerControl = buildmerControl())
formula |
A formula specifying both fixed and random effects using |
data |
See the general documentation under |
buildmerControl |
Control arguments for buildmer — see the general documentation under |
if (requireNamespace('ordinal')) { model <- buildclmm(SURENESS ~ PROD + (1|RESP),data=ordinal::soup, buildmerControl=list(args=list(link='probit',threshold='equidistant'))) }if (requireNamespace('ordinal')) { model <- buildclmm(SURENESS ~ PROD + (1|RESP),data=ordinal::soup, buildmerControl=list(args=list(link='probit',threshold='equidistant'))) }
buildmer to perform stepwise elimination using a custom fitting functionUses buildmer to perform stepwise elimination using a custom fitting function
buildcustom( formula, data = NULL, fit = function(p, formula) stop("'fit' not specified"), crit = function(p, ref, alt) stop("'crit' not specified"), elim = function(x) stop("'elim' not specified"), REML = FALSE, buildmerControl = buildmerControl() )buildcustom( formula, data = NULL, fit = function(p, formula) stop("'fit' not specified"), crit = function(p, ref, alt) stop("'crit' not specified"), elim = function(x) stop("'elim' not specified"), REML = FALSE, buildmerControl = buildmerControl() )
formula |
See the general documentation under |
data |
See the general documentation under |
fit |
A function taking two arguments, of which the first is the |
crit |
A function taking one argument and returning a single value. The argument is the return value of the function passed in |
elim |
A function taking one argument and returning a single value. The argument is the return value of the function passed in |
REML |
A logical indicating if the fitting function wishes to distinguish between fits differing in fixed effects (for which |
buildmerControl |
Control arguments for buildmer — see the general documentation under |
## Use \code{buildmer} to do stepwise linear discriminant analysis library(buildmer) migrant[,-1] <- scale(migrant[,-1]) flipfit <- function(p,formula) { # The predictors must be entered as dependent variables in a MANOVA # (i.e. the predictors must be flipped with the dependent variable) Y <- model.matrix(formula,migrant) m <- lm(Y ~ 0+migrant$changed) # the model may error out when asking for the MANOVA test <- try(anova(m)) if (inherits(test,'try-error')) test else m } crit.F <- function(p,a,b) { # use whole-model F pvals <- anova(b)$'Pr(>F)' # not valid for backward! pvals[length(pvals)-1] } crit.Wilks <- function(p,a,b) { if (is.null(a)) return(crit.F(p,a,b)) #not completely correct, but close as F approximates X2 Lambda <- anova(b,test='Wilks')$Wilks[1] p <- length(coef(b)) n <- 1 m <- nrow(migrant) Bartlett <- ((p-n+1)/2-m)*log(Lambda) pchisq(Bartlett,n*p,lower.tail=FALSE) } # First, order the terms based on Wilks' Lambda model <- buildcustom(changed ~ friends.nl+friends.be+multilingual+standard+hearing+reading+ attention+sleep+gender+handedness+diglossic+age+years,buildmerControl=list( fit=flipfit,crit=crit.Wilks,direction='order')) # Now, use the six most important terms (arbitrary choice) in the LDA if (require('MASS')) { model <- lda(changed ~ diglossic + age + reading + friends.be + years + multilingual,data=migrant) }## Use \code{buildmer} to do stepwise linear discriminant analysis library(buildmer) migrant[,-1] <- scale(migrant[,-1]) flipfit <- function(p,formula) { # The predictors must be entered as dependent variables in a MANOVA # (i.e. the predictors must be flipped with the dependent variable) Y <- model.matrix(formula,migrant) m <- lm(Y ~ 0+migrant$changed) # the model may error out when asking for the MANOVA test <- try(anova(m)) if (inherits(test,'try-error')) test else m } crit.F <- function(p,a,b) { # use whole-model F pvals <- anova(b)$'Pr(>F)' # not valid for backward! pvals[length(pvals)-1] } crit.Wilks <- function(p,a,b) { if (is.null(a)) return(crit.F(p,a,b)) #not completely correct, but close as F approximates X2 Lambda <- anova(b,test='Wilks')$Wilks[1] p <- length(coef(b)) n <- 1 m <- nrow(migrant) Bartlett <- ((p-n+1)/2-m)*log(Lambda) pchisq(Bartlett,n*p,lower.tail=FALSE) } # First, order the terms based on Wilks' Lambda model <- buildcustom(changed ~ friends.nl+friends.be+multilingual+standard+hearing+reading+ attention+sleep+gender+handedness+diglossic+age+years,buildmerControl=list( fit=flipfit,crit=crit.Wilks,direction='order')) # Now, use the six most important terms (arbitrary choice) in the LDA if (require('MASS')) { model <- lda(changed ~ diglossic + age + reading + friends.be + years + multilingual,data=migrant) }
buildmer to fit generalized additive models using gam from package mgcv
Uses buildmer to fit generalized additive models using gam from package mgcv
buildgam( formula, data = NULL, family = gaussian(), quickstart = 0, buildmerControl = buildmerControl() )buildgam( formula, data = NULL, family = gaussian(), quickstart = 0, buildmerControl = buildmerControl() )
formula |
See the general documentation under |
data |
See the general documentation under |
family |
See the general documentation under |
quickstart |
A numeric with values from 0 to 5. If set to 1, will use |
buildmerControl |
Control arguments for buildmer — see the general documentation under |
To work around an issue in gam, you must make sure that your data do not contain a variable named 'intercept'.
lme4 random effects are supported: they will be automatically converted using re2mgcv.
If gam's optimizer argument is not set to use outer iteration, gam fits using PQL. In this scenario, only crit='F' and crit='deviance' (note that the latter is not a formal test) are legitimate in the generalized case.
General families implemented in mgcv are not supported, as they are only defined in terms of a mean-variance relationship and hence always use a linearized (PQL) approximation of the model. They do not have a real likelihood.
buildmerControl's quickstart function may be used here. If you desire more control (e.g.\ discrete=FALSE but use.chol=TRUE), additional options can be provided as extra arguments and will be passed on to bam as they are applicable. Note that quickstart needs to be larger than 0 to trigger the quickstart path at all.
If scaled-t errors are used (family=scat), the quickstart path will also provide initial values for the two theta parameters (corresponding to the degrees of freedom and the scale parameter), but only if your installation of package mgcv is at least at version 1.8-32.
library(buildmer) model <- buildgam(f1 ~ s(timepoint,by=following) + s(participant,by=following,bs='re') + s(participant,timepoint,by=following,bs='fs'),data=vowels)library(buildmer) model <- buildgam(f1 ~ s(timepoint,by=following) + s(participant,by=following,bs='re') + s(participant,timepoint,by=following,bs='fs'),data=vowels)
buildmer to fit big generalized additive models using gamm from package mgcv
Uses buildmer to fit big generalized additive models using gamm from package mgcv
buildgamm( formula, data = NULL, family = gaussian(), buildmerControl = buildmerControl() )buildgamm( formula, data = NULL, family = gaussian(), buildmerControl = buildmerControl() )
formula |
See the general documentation under |
data |
See the general documentation under |
family |
See the general documentation under |
buildmerControl |
Control arguments for buildmer — see the general documentation under |
The fixed and random effects are to be passed as a single formula in lme4 format. This is internally split up into the appropriate fixed and random parts.
Only a single grouping factor is allowed. The random-effect covariance matrix is always unstructured. If you want to use pdMat covariance structures, you must (a) not specify any lme4 random-effects term in the formula, and (b) specify your own custom random argument in the args list in buildmerControl. Note that buildgamm will merely pass this through; no term reordering or stepwise elimination is done on a user-provided random argument.
library(buildmer) model <- buildgamm(f1 ~ s(timepoint,by=following) + (following|participant) + s(participant,timepoint,by=following,bs='fs'),data=vowels)library(buildmer) model <- buildgamm(f1 ~ s(timepoint,by=following) + (following|participant) + s(participant,timepoint,by=following,bs='fs'),data=vowels)
buildmer to fit generalized additive models using package gamm4
Uses buildmer to fit generalized additive models using package gamm4
buildgamm4( formula, data = NULL, family = gaussian(), buildmerControl = buildmerControl() )buildgamm4( formula, data = NULL, family = gaussian(), buildmerControl = buildmerControl() )
formula |
See the general documentation under |
data |
See the general documentation under |
family |
See the general documentation under |
buildmerControl |
Control arguments for buildmer — see the general documentation under |
The fixed and random effects are to be passed as a single formula in lme4 format. This is internally split up into the appropriate fixed and random parts.
library(buildmer) if (requireNamespace('gamm4')) model <- buildgamm4(f1 ~ s(timepoint,by=following) + s(participant,timepoint,by=following,bs='fs'),data=vowels)library(buildmer) if (requireNamespace('gamm4')) model <- buildgamm4(f1 ~ s(timepoint,by=following) + s(participant,timepoint,by=following,bs='fs'),data=vowels)
buildmer to fit generalized linear mixed models using mixed_model from package GLMMadaptive
Uses buildmer to fit generalized linear mixed models using mixed_model from package GLMMadaptive
buildGLMMadaptive( formula, data = NULL, family, buildmerControl = buildmerControl() )buildGLMMadaptive( formula, data = NULL, family, buildmerControl = buildmerControl() )
formula |
A formula specifying both fixed and random effects using |
data |
See the general documentation under |
family |
See the general documentation under |
buildmerControl |
Control arguments for buildmer — see the general documentation under |
The fixed and random effects are to be passed as a single formula in lme4 format. This is internally split up into the appropriate fixed and random parts.
As GLMMadaptive can only fit models with a single random-effect grouping factor, having multiple different grouping factors will raise an error.
If multiple identical random-effect grouping factors are provided, they will be concatenated into a single grouping factor using the double-bar syntax, causing GLMMadaptive to assume a diagonal random-effects covariance matrix. In other words, (1|g) + (0+x|g) will correctly be treated as diagonal, but note the caveat: (a|g) + (b|g) will also be treated as fully diagonal, even if a and b are factors which might still have had correlations between their individual levels! This is a limitation of both GLMMadaptive and buildmer's approach to handling double bars.
if (requireNamespace('GLMMadaptive')) { # nonsensical model given these data model <- buildGLMMadaptive(stress ~ vowel + (vowel|participant), family=binomial,data=vowels,buildmerControl=list(args=list(nAGQ=1))) # or with double-bar syntax for a diagonal r.e. cov. matrix model <- buildGLMMadaptive(stress ~ vowel + (vowel||participant), family=binomial,data=vowels,buildmerControl=list(args=list(nAGQ=1))) }if (requireNamespace('GLMMadaptive')) { # nonsensical model given these data model <- buildGLMMadaptive(stress ~ vowel + (vowel|participant), family=binomial,data=vowels,buildmerControl=list(args=list(nAGQ=1))) # or with double-bar syntax for a diagonal r.e. cov. matrix model <- buildGLMMadaptive(stress ~ vowel + (vowel||participant), family=binomial,data=vowels,buildmerControl=list(args=list(nAGQ=1))) }
buildmer to perform stepwise elimination on glmmTMB modelsUses buildmer to perform stepwise elimination on glmmTMB models
buildglmmTMB( formula, data = NULL, family = gaussian(), buildmerControl = buildmerControl() )buildglmmTMB( formula, data = NULL, family = gaussian(), buildmerControl = buildmerControl() )
formula |
See the general documentation under |
data |
See the general documentation under |
family |
See the general documentation under |
buildmerControl |
Control arguments for buildmer — see the general documentation under |
library(buildmer) if (requireNamespace('glmmTMB')) { model <- buildglmmTMB(Reaction ~ Days + (Days|Subject),data=lme4::sleepstudy) }library(buildmer) if (requireNamespace('glmmTMB')) { model <- buildglmmTMB(Reaction ~ Days + (Days|Subject),data=lme4::sleepstudy) }
buildmer to fit generalized-least-squares models using gls from nlme
Uses buildmer to fit generalized-least-squares models using gls from nlme
buildgls(formula, data = NULL, buildmerControl = buildmerControl())buildgls(formula, data = NULL, buildmerControl = buildmerControl())
formula |
See the general documentation under |
data |
See the general documentation under |
buildmerControl |
Control arguments for buildmer — see the general documentation under |
A workaround is included to prevent an error when the model matrix is of less than full rank. The summary output of such a model will look a bit strange!
library(buildmer) library(nlme) vowels$event <- with(vowels,interaction(participant,word)) model <- buildgls(f1 ~ timepoint*following,data=vowels, buildmerControl=list(args=list(correlation=corAR1(form=~1|event))))library(buildmer) library(nlme) vowels$event <- with(vowels,interaction(participant,word)) model <- buildgls(f1 ~ timepoint*following,data=vowels, buildmerControl=list(args=list(correlation=corAR1(form=~1|event))))
buildmer to perform stepwise elimination of mixed-effects models fit via lme from nlme
Uses buildmer to perform stepwise elimination of mixed-effects models fit via lme from nlme
buildlme(formula, data = NULL, buildmerControl = buildmerControl())buildlme(formula, data = NULL, buildmerControl = buildmerControl())
formula |
A formula specifying both fixed and random effects using |
data |
See the general documentation under |
buildmerControl |
Control arguments for buildmer — see the general documentation under |
The fixed and random effects are to be passed as a single formula in lme4 format. This is internally split up into the appropriate fixed and random parts.
Only a single grouping factor is allowed. The random-effect covariance matrix is always unstructured. If you want to use pdMat covariance structures, you must (a) not specify any lme4 random-effects term in the formula, and (b) specify your own custom random argument in the args list in buildmerControl. Note that buildlme will merely pass this through; no term reordering or stepwise elimination is done on a user-provided random argument.
library(buildmer) model <- buildlme(Reaction ~ Days + (Days|Subject),data=lme4::sleepstudy)library(buildmer) model <- buildlme(Reaction ~ Days + (Days|Subject),data=lme4::sleepstudy)
buildmer to fit mixed-effects models using lmer/glmer from lme4
Uses buildmer to fit mixed-effects models using lmer/glmer from lme4
buildmer( formula, data = NULL, family = gaussian(), buildmerControl = buildmerControl() )buildmer( formula, data = NULL, family = gaussian(), buildmerControl = buildmerControl() )
formula |
See the general documentation under |
data |
See the general documentation under |
family |
See the general documentation under |
buildmerControl |
Control arguments for buildmer — see the general documentation under |
library(buildmer) model <- buildmer(Reaction ~ Days + (Days|Subject),lme4::sleepstudy) # Tests from github issue #2, that also show the use of the 'direction' and 'crit' parameters: bm.test <- buildmer(cbind(incidence,size - incidence) ~ period + (1 | herd), family=binomial,data=lme4::cbpp) bm.test <- buildmer(cbind(incidence,size - incidence) ~ period + (1 | herd), family=binomial,data=lme4::cbpp,buildmerControl=buildmerControl(direction='forward')) bm.test <- buildmer(cbind(incidence,size - incidence) ~ period + (1 | herd), family=binomial,data=lme4::cbpp,buildmerControl=buildmerControl(crit='AIC')) bm.test <- buildmer(cbind(incidence,size - incidence) ~ period + (1 | herd), family=binomial,data=lme4::cbpp, buildmerControl=buildmerControl(direction='forward',crit='AIC')) # Example showing use of the 'include' parameter to force a particular term into the model m1 <- buildmer(Reaction ~ Days,data=lme4::sleepstudy,buildmerControl=list(include=~(1|Subject))) # the below are equivalent m2 <- buildmer(Reaction ~ Days,data=lme4::sleepstudy,buildmerControl=list(include='(1|Subject)')) m3 <- buildmer(Reaction ~ Days + (1|Subject),data=lme4::sleepstudy,buildmerControl=list( include=~(1|Subject))) m4 <- buildmer(Reaction ~ Days + (1|Subject),data=lme4::sleepstudy,buildmerControl=list( include='(1|Subject)'))library(buildmer) model <- buildmer(Reaction ~ Days + (Days|Subject),lme4::sleepstudy) # Tests from github issue #2, that also show the use of the 'direction' and 'crit' parameters: bm.test <- buildmer(cbind(incidence,size - incidence) ~ period + (1 | herd), family=binomial,data=lme4::cbpp) bm.test <- buildmer(cbind(incidence,size - incidence) ~ period + (1 | herd), family=binomial,data=lme4::cbpp,buildmerControl=buildmerControl(direction='forward')) bm.test <- buildmer(cbind(incidence,size - incidence) ~ period + (1 | herd), family=binomial,data=lme4::cbpp,buildmerControl=buildmerControl(crit='AIC')) bm.test <- buildmer(cbind(incidence,size - incidence) ~ period + (1 | herd), family=binomial,data=lme4::cbpp, buildmerControl=buildmerControl(direction='forward',crit='AIC')) # Example showing use of the 'include' parameter to force a particular term into the model m1 <- buildmer(Reaction ~ Days,data=lme4::sleepstudy,buildmerControl=list(include=~(1|Subject))) # the below are equivalent m2 <- buildmer(Reaction ~ Days,data=lme4::sleepstudy,buildmerControl=list(include='(1|Subject)')) m3 <- buildmer(Reaction ~ Days + (1|Subject),data=lme4::sleepstudy,buildmerControl=list( include=~(1|Subject))) m4 <- buildmer(Reaction ~ Days + (1|Subject),data=lme4::sleepstudy,buildmerControl=list( include='(1|Subject)'))
This is a simple convenience class that allows ‘anova’ and ‘summary’ calls to fall through to the underlying model object, while retaining buildmer's iteration history. If you need to use the final model for other things, such as prediction, access it through the ‘model’ slot of the buildmer class object.
modelThe final model containing only the terms that survived elimination
pParameters used during the fitting process
anovaThe model's ANOVA, if the model was built with ‘anova=TRUE’
summaryThe model's summary, if the model was built with ‘summary=TRUE’
# Manually create a bare-bones buildmer object: model <- lm(Sepal.Length ~ Petal.Length,iris) p <- list(in.buildmer=FALSE) library(buildmer) bm <- mkBuildmer(model=model,p=p,anova=NULL,summary=NULL) summary(bm)# Manually create a bare-bones buildmer object: model <- lm(Sepal.Length ~ Petal.Length,iris) p <- list(in.buildmer=FALSE) library(buildmer) bm <- mkBuildmer(model=model,p=p,anova=NULL,summary=NULL) summary(bm)
buildmer to fit negative-binomial models using glm.nb and glmer.nb
Uses buildmer to fit negative-binomial models using glm.nb and glmer.nb
buildmer.nb(formula, data = NULL, buildmerControl = buildmerControl())buildmer.nb(formula, data = NULL, buildmerControl = buildmerControl())
formula |
See the general documentation under |
data |
See the general documentation under |
buildmerControl |
Control arguments for buildmer — see the general documentation under |
library(buildmer) if (requireNamespace('MASS')) { model <- buildmer.nb(Days ~ Sex*Age*Eth*Lrn,MASS::quine) }library(buildmer) if (requireNamespace('MASS')) { model <- buildmer.nb(Days ~ Sex*Age*Eth*Lrn,MASS::quine) }
buildmerControl provides all the knobs and levers that can be manipulated during the buildmer fitting and summary/anova process. Some of these are part of buildmer's core functionality—for instance, crit allows to specify different elimination criteria, a core buildmer feature—whereas some are only meant for internal usage, e.g. I_KNOW_WHAT_I_AM_DOING is used to turn off the PQL safeguards in buildbam/buildgam, which you really should only do if you have a very good reason to believe that the PQL check is being triggered erroneously for your problem.
buildmerControl( formula = quote(stop("No formula specified")), data = NULL, family = gaussian(), args = list(), direction = c("order", "backward"), cl = NULL, crit = NULL, elim = NULL, fit = function(...) stop("No fitting function specified"), include = NULL, quiet = FALSE, calc.anova = FALSE, calc.summary = TRUE, ddf = "Wald", quickstart = 0, singular.ok = FALSE, grad.tol = quote(formals(buildmer::converged)$grad.tol), hess.tol = quote(formals(buildmer::converged)$hess.tol), dep = NULL, REML = NA, can.use.reml = TRUE, force.reml = FALSE, scale.est = NA, I_KNOW_WHAT_I_AM_DOING = FALSE )buildmerControl( formula = quote(stop("No formula specified")), data = NULL, family = gaussian(), args = list(), direction = c("order", "backward"), cl = NULL, crit = NULL, elim = NULL, fit = function(...) stop("No fitting function specified"), include = NULL, quiet = FALSE, calc.anova = FALSE, calc.summary = TRUE, ddf = "Wald", quickstart = 0, singular.ok = FALSE, grad.tol = quote(formals(buildmer::converged)$grad.tol), hess.tol = quote(formals(buildmer::converged)$hess.tol), dep = NULL, REML = NA, can.use.reml = TRUE, force.reml = FALSE, scale.est = NA, I_KNOW_WHAT_I_AM_DOING = FALSE )
formula |
The model formula for the maximal model you would like to fit. Alternatively, a buildmer term list as obtained from |
data |
The data to fit the model(s) to. |
family |
The error distribution to use. |
args |
Extra arguments passed to the fitting function. |
direction |
Character string or vector indicating the direction for stepwise elimination; possible options are |
cl |
Specifies a cluster to use for parallelizing the evaluation of terms. This can be an object as returned by function |
crit |
Character string or vector determining the criterion used to test terms for their contribution to the model fit in the ordering step. Possible options are |
elim |
Character string or vector determining the criterion used to test terms for elimination in the elimination step. Possible options are |
fit |
Internal parameter — do not modify. |
include |
A one-sided formula or character vector of terms that will be included in the model at all times and are not subject to testing for elimination. These do not need to be specified separately in the |
quiet |
A logical indicating whether to suppress progress messages. |
calc.anova |
Logical indicating whether to also calculate the ANOVA table for the final model after term elimination. |
calc.summary |
Logical indicating whether to also calculate the summary table for the final model after term elimination. |
ddf |
The method used for calculating p-values for |
quickstart |
For |
singular.ok |
Logical indicating whether singular fits are acceptable. Only for lme4 models. |
grad.tol |
Tolerance for declaring gradient convergence. |
hess.tol |
Tolerance for declaring Hessian convergence. |
dep |
A character string specifying the name of the dependent variable. Only used if |
REML |
In some situations, the user may want to force REML on or off, rather than using buildmer's autodetection. If |
can.use.reml |
Internal option specifying whether the fitting engine should distinguish between fixed-effects and random-effects model comparisons. Do not set this option yourself unless you are programming a new fitting function for |
force.reml |
Internal option specifying whether, if not differentiating between fixed-effects and random-effects model comparisons, these comparisons should be based on ML or on REML (if possible). Do not set this option yourself unless you are programming a new fitting function for |
scale.est |
Internal option specifying whether the model estimates an unknown scale parameter. Used only in |
I_KNOW_WHAT_I_AM_DOING |
An internal option that you should not modify unless you know what you are doing. |
With the default options, all buildmer functions will do two things:
Determine the order of the effects in your model, based on their importance as measured by the likelihood-ratio test statistic. This identifies the ‘maximal model’, which is the model containing either all effects specified by the user, or subset of those effects that still allow the model to converge, ordered such that the most information-rich effects have made it in.
Perform backward stepwise elimination based on the significance of the change in log-likelihood.
The final model is returned in the model slot of the returned buildmer object.
All functions in the buildmer package are aware of the distinction between (f)REML and ML, and know to correct chi-square p-values using the Stram & Lee (1994) correction when comparing nlme/lme4-style models differing only in random effects (see Pinheiro & Bates 2000).
The steps executed above can be changed using the direction argument, allowing for arbitrary chains of, for instance, forward-backward-forward stepwise elimination (although using more than one elimination method on the same data is not recommended). The criterion for determining the importance of terms in the ordering stage and the elimination of terms in the elimination stage can also be changed, using the crit argument.
buildmer to perform stepwise elimination for lmertree and glmertree models from package glmertree
Uses buildmer to perform stepwise elimination for lmertree and glmertree models from package glmertree
buildmertree( formula, data = NULL, family = gaussian(), buildmerControl = buildmerControl(crit = "AIC") )buildmertree( formula, data = NULL, family = gaussian(), buildmerControl = buildmerControl(crit = "AIC") )
formula |
Either a |
data |
See the general documentation under |
family |
See the general documentation under |
buildmerControl |
Control arguments for buildmer — see the general documentation under |
Note that the likelihood-ratio test is not available for glmertree models, as it cannot be assured that the models being compared are nested. The default is thus to use AIC.
In the generalized case or when testing many partitioning variables, it is recommended to pass joint=FALSE, as this results in a dramatic speed gain and reduces the odds of the final glmer model failing to converge or converging singularly.
if (requireNamespace('glmertree')) { model <- buildmertree(Reaction ~ 1 | (Days|Subject) | Days, buildmerControl=buildmerControl(crit='LL',direction='order',args=list(joint=FALSE)), data=lme4::sleepstudy) model <- buildmertree(Reaction ~ 1 | (Days|Subject) | Days, buildmerControl=buildmerControl(crit='LL',direction='order',args=list(joint=FALSE)), data=lme4::sleepstudy,family=Gamma(link=identity)) }if (requireNamespace('glmertree')) { model <- buildmertree(Reaction ~ 1 | (Days|Subject) | Days, buildmerControl=buildmerControl(crit='LL',direction='order',args=list(joint=FALSE)), data=lme4::sleepstudy) model <- buildmertree(Reaction ~ 1 | (Days|Subject) | Days, buildmerControl=buildmerControl(crit='LL',direction='order',args=list(joint=FALSE)), data=lme4::sleepstudy,family=Gamma(link=identity)) }
buildmer to perform stepwise elimination for multinom models from package nnet
Uses buildmer to perform stepwise elimination for multinom models from package nnet
buildmultinom(formula, data = NULL, buildmerControl = buildmerControl())buildmultinom(formula, data = NULL, buildmerControl = buildmerControl())
formula |
See the general documentation under |
data |
See the general documentation under |
buildmerControl |
Control arguments for buildmer — see the general documentation under |
if (requireNamespace('nnet') && require('MASS')) { options(contrasts = c("contr.treatment", "contr.poly")) example(birthwt) bwt.mu <- buildmultinom(low ~ age*lwt*race*smoke,bwt) }if (requireNamespace('nnet') && require('MASS')) { options(contrasts = c("contr.treatment", "contr.poly")) example(birthwt) bwt.mu <- buildmultinom(low ~ age*lwt*race*smoke,bwt) }
Deviation-coding is a contrast-coding scheme that compares each level to the average of the other levels. It is often confused with sum-coding, which compares each level to the average of all levels. In the binary case, deviation coding works out to \( (+0.5,-0.5) \); in the ternary case and beyond, the coding is a little bit more involved.
contr.deviation(n, contrasts = TRUE, sparse = FALSE)contr.deviation(n, contrasts = TRUE, sparse = FALSE)
n |
See |
contrasts |
See |
sparse |
See |
contr.deviation starts by calling contr.sum and hence accepts the same arguments as it does.
A matrix of deviation-coded contrasts.
iris$Species <- contr.deviation(iris$Species)iris$Species <- contr.deviation(iris$Species)
Tests a model for convergence
converged( model, singular.ok = FALSE, grad.tol = if (inherits(model, "bam")) 10 else 0.1, hess.tol = if (inherits(model, "bam")) 10 else 0.01 )converged( model, singular.ok = FALSE, grad.tol = if (inherits(model, "bam")) 10 else 0.1, hess.tol = if (inherits(model, "bam")) 10 else 0.01 )
model |
The model object to test. |
singular.ok |
A logical indicating whether singular fits are accepted as ‘converged’ or not. Relevant only for lme4 models. |
grad.tol |
The tolerance to use for checking the gradient. This is currently only used by mgcv, glmmTMB, and clm(m) models. |
hess.tol |
The tolerance to use for checking the Hessian for negative eigenvalues. This is currently only used by mgcv, glmmTMB, and cl(m)m models. |
Logical indicating whether the model converged.
library(buildmer) library(lme4) good1 <- lm(Reaction ~ Days,sleepstudy) good2 <- lmer(Reaction ~ Days + (Days|Subject),sleepstudy) bad <- lmer(Reaction ~ Days + (Days|Subject),sleepstudy,control=lmerControl( optimizer='bobyqa',optCtrl=list(maxfun=1))) sapply(list(good1,good2,bad),converged)library(buildmer) library(lme4) good1 <- lm(Reaction ~ Days,sleepstudy) good2 <- lmer(Reaction ~ Days + (Days|Subject),sleepstudy) bad <- lmer(Reaction ~ Days + (Days|Subject),sleepstudy,control=lmerControl( optimizer='bobyqa',optCtrl=list(maxfun=1))) sapply(list(good1,good2,bad),converged)
This function is an alias to contr.deviation intended to allow the C command to work for deviation-coding the same way as it does for other, base-R, contrasts.
deviation(n, contrasts = TRUE, sparse = FALSE)deviation(n, contrasts = TRUE, sparse = FALSE)
n |
See |
contrasts |
See |
sparse |
See |
A matrix of deviation-coded contrasts.
iris$Species <- C(iris$Species,deviation)iris$Species <- C(iris$Species,deviation)
Diagonalize the random-effect covariance structure, possibly assisting convergence
## S4 method for signature 'formula' diag(x)## S4 method for signature 'formula' diag(x)
x |
A model formula. |
The formula with all random-effect correlations forced to zero, per Pinheiro & Bates (2000)
# 1. Create explicit columns for factor variables library(buildmer) vowels <- cbind(vowels,model.matrix(~vowel,vowels)) # 2. Create formula with diagonal covariance structure form <- diag(f1 ~ (vowel1+vowel2+vowel3+vowel4)*timepoint*following + ((vowel1+vowel2+vowel3+vowel4)*timepoint*following | participant) + (timepoint | word)) # 3. Convert formula to buildmer term list, grouping terms starting with 'vowel' terms <- tabulate.formula(form,group='vowel[^:]') # 4. Directly pass the terms object to buildmer, using the 'dep' argument to specify the # dependent variable model <- buildmer(terms,data=vowels,buildmerControl=list(dep='f1'))# 1. Create explicit columns for factor variables library(buildmer) vowels <- cbind(vowels,model.matrix(~vowel,vowels)) # 2. Create formula with diagonal covariance structure form <- diag(f1 ~ (vowel1+vowel2+vowel3+vowel4)*timepoint*following + ((vowel1+vowel2+vowel3+vowel4)*timepoint*following | participant) + (timepoint | word)) # 3. Convert formula to buildmer term list, grouping terms starting with 'vowel' terms <- tabulate.formula(form,group='vowel[^:]') # 4. Directly pass the terms object to buildmer, using the 'dep' argument to specify the # dependent variable model <- buildmer(terms,data=vowels,buildmerControl=list(dep='f1'))
The elim argument in buildmerControl can take any user-specified elimination function. LRTalpha generates such a function that uses the likelihood-ratio test, based on a user-specified alpha level. (For the default alpha of .05, one can also simply specify the string 'LRT' or the function buildmer:::elim.LRT).
LRTalpha(alpha)LRTalpha(alpha)
alpha |
The alpha level for the likelihood-ratio test. |
A very small dataset from a pilot study on sound change.
data(migrant)data(migrant)
A standard data frame.
Converts lme4 random-effect terms to mgcv 're' smooths
re2mgcv(formula, data, drop = TRUE)re2mgcv(formula, data, drop = TRUE)
formula |
The lme4 formula. |
data |
The data. |
drop |
Logical indicating whether constant, non-intercept columns should be dropped. Default |
To ensure that the various buildmer functions (e.g. buildgam, buildbam) correctly apply marginality constraints between parametric terms and random-effect terms, the parametric terms are renamed using the same name-mangling scheme that is automatically applied to the random effects. To ensure that the mangled names will be grouped together, instead of passing the returned formula, use the returned termlist with a dep argument. See the description of the dep argument in buildmerControl.
A list containing a new formula (has a dependent variable but loses track of what terms belong together in a single block), a buildmer term list (lacks the dependent variable but represents what terms belong together), and a new data set.
library(buildmer) re <- re2mgcv(temp ~ angle + (1|replicate) + (1|recipe),lme4::cake) model <- buildgam(re$formula,re$data) # note: the below does NOT work, as the dependent variable is looked up in the data by name! re <- re2mgcv(log(Reaction) ~ Days + (Days|Subject),lme4::sleepstudy)library(buildmer) re <- re2mgcv(temp ~ angle + (1|replicate) + (1|recipe),lme4::cake) model <- buildgam(re$formula,re$data) # note: the below does NOT work, as the dependent variable is looked up in the data by name! re <- re2mgcv(log(Reaction) ~ Days + (Days|Subject),lme4::sleepstudy)
lme4 and similar packages (e.g. glmmTMB) have an issue where correlations between factor random slopes are not dropped, even if using the double-bar syntax or diag to diagonalize the random-effects formula. re2uncorr works around this issue by explicitly converting factor random slopes to numerics, which do not suffer from this problem.
re2uncorr(formula, data, drop = TRUE)re2uncorr(formula, data, drop = TRUE)
formula |
The lme4 formula. |
data |
The data. |
drop |
Logical indicating whether constant, non-intercept columns should be dropped. Default |
To ensure that the various buildmer functions (e.g. buildmer, buildglmmTMB) correctly apply marginality constraints between fixed effects and random-effect terms, the fixed effects are renamed using the same name-mangling scheme that is automatically applied to the random effects. To ensure that the mangled names will be grouped together, instead of passing the returned formula, use the returned termlist with a dep argument. See the description of the dep argument in buildmerControl.
A list containing a new formula (has a dependent variable but loses track of what terms belong together in a single block), a buildmer term list (lacks the dependent variable but represents what terms belong together), and a new data set.
library(buildmer) re <- re2uncorr(f1 ~ vowel*timepoint*following + (vowel*timepoint*following|participant) + (timepoint|word),vowels) model <- buildmer(re$formula,re$data)library(buildmer) re <- re2uncorr(f1 ~ vowel*timepoint*following + (vowel*timepoint*following|participant) + (timepoint|word),vowels) model <- buildmer(re$formula,re$data)
Removes terms from a formula
remove.terms(formula, remove, check = TRUE)remove.terms(formula, remove, check = TRUE)
formula |
The formula. |
remove |
A vector of terms to remove. To remove terms nested inside random-effect groups, use ‘(term|group)’ syntax. Note that marginality is respected, i.e. no effects will be removed if they participate in a higher-order interaction, and no fixed effects will be removed if a random slope is included over that fixed effect. |
check |
A logical indicating whether effects should be checked for marginality. If |
library(buildmer) remove.terms(Reaction ~ Days + (Days|Subject),'(Days|Subject)') # illustration of the marginality checking mechanism: # this refuses to remove the term: remove.terms(Reaction ~ Days + (Days|Subject),'(1|Subject)') # so does this, because marginality is checked before removal: remove.terms(Reaction ~ Days + (Days|Subject),c('(Days|Subject)','(1|Subject)')) # but it works with check=FALSE remove.terms(Reaction ~ Days + (Days|Subject),'(1|Subject)',check=FALSE)library(buildmer) remove.terms(Reaction ~ Days + (Days|Subject),'(Days|Subject)') # illustration of the marginality checking mechanism: # this refuses to remove the term: remove.terms(Reaction ~ Days + (Days|Subject),'(1|Subject)') # so does this, because marginality is checked before removal: remove.terms(Reaction ~ Days + (Days|Subject),c('(Days|Subject)','(1|Subject)')) # but it works with check=FALSE remove.terms(Reaction ~ Days + (Days|Subject),'(1|Subject)',check=FALSE)
Parses a formula into a buildmer term list
tabulate.formula(formula, group = NULL)tabulate.formula(formula, group = NULL)
formula |
A formula. |
group |
A character vector of regular expressions. Terms matching the same regular expression are assigned the same block, and will be evaluated together in buildmer functions. |
A buildmer term list, which is just a normal data frame.
buildmer-package
form <- diag(f1 ~ (vowel1+vowel2+vowel3+vowel4)*timepoint*following + ((vowel1+vowel2+vowel3+vowel4)*timepoint*following|participant) + (timepoint|word)) tabulate.formula(form) tabulate.formula(form,group='vowel[1-4]')form <- diag(f1 ~ (vowel1+vowel2+vowel3+vowel4)*timepoint*following + ((vowel1+vowel2+vowel3+vowel4)*timepoint*following|participant) + (timepoint|word)) tabulate.formula(form) tabulate.formula(form,group='vowel[1-4]')
Vowel data from a pilot study.
data(vowels)data(vowels)
A standard data frame.