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))
______________________________________________
[email protected] mailing list
https://stat.ethz.ch/mailman/listinfo/r-devel