[R] low-variance warning in lmer
Ben Bolker
bolker at zoo.ufl.edu
Fri Nov 24 20:26:13 CET 2006
For block effects with small variance, lmer will sometimes
estimate the variance as being very close to zero and issue
a warning. I don't have a problem with this -- I've explored
things a bit with some simulations (see below) and conclude that
this is probably inevitable when trying to incorporate
random effects with not very much data (the means and medians
of estimates are plausibly close to the nominal values:
the fraction of runs with warnings/near-zero estimates drops
from about 50% when the between-block variance is 1% of
the total (with 2 treatments, 12 blocks nested within treatment,
3 replicates per block), to 15% when between=30% of total,
to near zero when between=50% of total.
My question is: what should I suggest to students when this
situation comes up? Can anyone point me to appropriate references?
(I haven't found anything relevant in Pinheiro and Bates, but
I may not have looked in the right place ...)
thanks
Ben Bolker
self-contained but unnecessarily complicated simulation
code/demonstration:
---------------
library(lme4)
library(lattice)
simfun <- function(reefeff,ntreat=2,nreef=12,
nreefpertreat=3,
t.eff=10,
totvar=25,seed=NA) {
if (!is.na(seed)) set.seed(seed)
ntot = nreef*nreefpertreat
npertreat=ntot/ntreat
reef = gl(nreef,nreefpertreat)
treat = gl(ntreat,npertreat)
r.sd = sqrt(totvar*reefeff)
e.sd = sqrt(totvar*(1-reefeff))
y.det = ifelse(treat==1,0,t.eff)
r.vals = rnorm(nreef,sd=r.sd)
e.vals = rnorm(ntot,sd=e.sd)
y <- y.det+r.vals[as.numeric(reef)]+e.vals
data.frame(y,treat,reef)
}
getranvar <- function(x) {
vc <- VarCorr(x)
c(diag(vc[[1]]),attr(vc,"sc")^2)
}
estfun <- function(reefeff,...) {
x <- simfun(reefeff=reefeff,...)
ow <- options(warn=2)
f1 <- try(lmer(y~treat+(1|reef),data=x))
w <- (class(f1)=="try-error" && length(grep("effectively zero",f1))>0)
options(ow)
f2 <- lmer(y~treat+(1|reef),data=x)
c(getranvar(f2),as.numeric(w))
}
rvec <- rep(c(0.01,0.05,0.1,0.15,0.2,0.3,0.5),each=100)
X <- t(sapply(rvec,estfun))
colnames(X) <- c("reefvar","resvar","warn")
rfrac <- X[,"reefvar"]/(X[,"reefvar"]+X[,"resvar"])
fracwarn <- tapply(X[,"warn"],rvec,mean)
est.mean <- tapply(rfrac,rvec,mean)
op <- par(mfrow=c(1,2))
plot(rvec,rfrac,type="n",xlim=c(-0.02,0.55),axes=FALSE)
axis(side=2)
box()
boxplot(rfrac~rvec,at=unique(rvec),add=TRUE,pars=list(boxwex=0.03),
col="gray")
points(jitter(rvec),rfrac,col=X[,"warn"]+1)
lines(unique(rvec),fracwarn,col="blue",type="b",lwd=2)
text(0.4,0.1,"fraction\nzero",col="blue")
abline(a=0,b=1,lwd=2)
points(unique(rvec),est.mean,cex=1.5,col=5)
##
plot(rvec,rfrac,type="n",xlim=c(-0.02,0.55),axes=FALSE,log="y")
axis(side=2)
axis(side=1,at=unique(rvec))
box()
points(jitter(rvec),rfrac,col=X[,"warn"]+1)
curve(1*x,add=TRUE,lwd=2)
print(densityplot(~rfrac,groups=rvec,from=0,to=0.9,
panel=function(...) {
panel.densityplot(...)
cols <- trellis.par.get("superpose.line")$col
lpoints(unique(rvec),rep(8,length(rvec)),type="h",
col=cols[1:length(rvec)])
}))
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 254 bytes
Desc: OpenPGP digital signature
Url : https://stat.ethz.ch/pipermail/r-help/attachments/20061124/5dbf7a26/attachment.bin
More information about the R-help
mailing list