An lme4 user pointed out <https://github.com/lme4/lme4/issues/491> that passing contrasts as a string or symbol to [g]lmer (which would work if we were using `contrasts<-` to set contrasts on a factor variable) is *silently ignored*. This goes back to model.matrix(), and seems bad (this is a very easy mistake to make, because of the multitude of ways to specify contrasts for factors in R - e.g. options(contrasts=...); setting contrasts on the specific factors; passing contrasts as a list to the model function ... )
The relevant code is here: https://github.com/wch/r-source/blob/trunk/src/library/stats/R/models.R#L578-L603 The following code shows the problem: a plain-vanilla model.matrix() call with no contrasts argument, followed by two wrong contrasts arguments, followed by a correct contrasts argument. data(cbpp, package="lme4") mf1 <- model.matrix(~period, data=cbpp) mf2 <- model.matrix(~period, contrasts.arg="contr.sum", data=cbpp) all.equal(mf1,mf2) ## TRUE mf3 <- model.matrix(~period, contrasts.arg=contr.sum, data=cbpp) all.equal(mf1,mf3) ## TRUE mf4 <- model.matrix(~period, contrasts.arg=list(period=contr.sum), data=cbpp) isTRUE(all.equal(mf1,mf4)) ## FALSE I've attached a potential patch for this, which is IMO the mildest possible case (if contrasts.arg is non-NULL and not a list, it produces a warning). I haven't been able to test it because of some mysterious issues I'm having with re-making R properly ... Thoughts? Should I submit this as a bug report/patch? cheers Ben Bolker
Index: src/library/stats/R/models.R =================================================================== --- src/library/stats/R/models.R (revision 76140) +++ src/library/stats/R/models.R (working copy) @@ -589,20 +589,23 @@ contrasts(data[[nn]]) <- contr.funs[1 + isOF[nn]] ## it might be safer to have numerical contrasts: ## get(contr.funs[1 + isOF[nn]])(nlevels(data[[nn]])) - if (!is.null(contrasts.arg) && is.list(contrasts.arg)) { - if (is.null(namC <- names(contrasts.arg))) - stop("invalid 'contrasts.arg' argument") - for (nn in namC) { - if (is.na(ni <- match(nn, namD))) - warning(gettextf("variable '%s' is absent, its contrast will be ignored", nn), - domain = NA) - else { - ca <- contrasts.arg[[nn]] - if(is.matrix(ca)) contrasts(data[[ni]], ncol(ca)) <- ca - else contrasts(data[[ni]]) <- contrasts.arg[[nn]] - } - } - } + if (!is.null(contrasts.arg)) { + if (!is.list(contrasts.arg)) { + warning("non-list contrasts argument ignored") + } else { ## contrasts.arg is a list + if (is.null(namC <- names(contrasts.arg))) + stop("'contrasts.arg' argument must be named") + for (nn in namC) { + if (is.na(ni <- match(nn, namD))) + warning(gettextf("variable '%s' is absent, its contrast will be ignored", nn), + domain = NA) + else { + ca <- contrasts.arg[[nn]] + if(is.matrix(ca)) contrasts(data[[ni]], ncol(ca)) <- ca + else contrasts(data[[ni]]) <- contrasts.arg[[nn]] + } } + } ## contrasts.arg is a list + } ## non-null contrasts.arg } else { # no rhs terms ('~1', or '~0'): internal model.matrix needs some variable isF <- FALSE data[["x"]] <- raw(nrow(data))
______________________________________________ R-devel@r-project.org mailing list https://stat.ethz.ch/mailman/listinfo/r-devel