sambrilleman / rstanarm

rstanarm R package for Bayesian applied regression modeling
http://mc-stan.org/interfaces/rstanarm.html
GNU General Public License v3.0
0 stars 1 forks source link

Minor error: could not find function "glmer" #28

Open jburos opened 7 years ago

jburos commented 7 years ago

Summary:

Seeing error when using neg_binomial_2() family: could not find function "glmer"

Description:

I see the following when using the family = list(neg_binomial_2()):

> mj5 <- with_filecache(
+   stan_jm(formulaLong = spd ~
+             poly(dtedy, degree = 2) +
+    .... [TRUNCATED]
Error in eval(expr, envir, enclos) : could not find function "glmer"

If I precede the call with library(lme4) then the error is resolved.

Reproducible Steps:

Try to fit a model using family = list(neg_binomial_2()) without first running library(lme4).

Eg.:

library(rstanarm)
data(pbcSurv_subset)
data(pbcLong_subset)
fit <- stan_jm(formulaLong = platelet ~ year + (1|id),
               dataLong=pbcLong_subset, 
               formulaEvent = Surv(futimeYears, death) ~ sex + trt,
               dataEvent = pbcSurv_subset,
               time_var = 'year', 
               family = list(neg_binomial_2())
)

RStanARM Version:

Recently installed from the master branch of this repo: 6332b9a0839e91fbacfa2f659a17c5bcc2650776

R Version:

3.3.2

Operating System:

Observed on both OSX and ubuntu

jburos commented 7 years ago

This appears to be one of those annoying R scoping bugs.

The fix would need to happen in lme4 package code, since the call to "glmer" is generated by this line of lme4::glmer.nb:

mc <- match.call()
mc[[1]] <- quote(glmer)
mc$family <- quote(stats::poisson)
mc$verbose <- (verbose>=2)
g0 <- eval(mc, parent.frame(1L))

This call should be prefixed with the package name. For example, similar calls in rstanarm prefix the function name so that they can be evaluated without loading the package into the namespace (per stan-dev/rstanarm#97):

mc[[1L]] <- quote(rstanarm::stan_glmer)

This call to glmer.nb was triggered by this line of rstanarm:::handle_glmod, which is itself evaluated in the parent.frame(). Would be sort of fun to map out the various environments at this point ..

While the workaround solution is easy, it would be nice to get this to work without requiring that the user load lme4 into the global scope. I suspect a similar thing would happen for any function using neg_binomial_2(); surprised it hasn't come up elsewhere.

sambrilleman commented 7 years ago

My guess is that this issue isn't encountered by stan_glmer because that function calls lme4::glFormula rather than lme4::glmer, as here, and glFormula seems to work ok.

The only clean work around I can think of for this, is to evaluate an initial value for theta explicitly in handle_glmod using theta.ml (rather than relying on glmer.nb to do it), and then just use lme4::glmer directly with family = negative.binomial(theta). This would avoid the bug, but would require a little bit more code in stan_jm (but not much). I'm not going to bother with this yet, but will keep the issue open.

The alternative would be to see if quote(glmer) can be changed to quote(lme4::glmer) but perhaps they've done it for some specific reason?