bcjaeger / r2glmm

An R package for computation of model R squared and semi-partial R squared (with confidence limits) in linear and generalized linear mixed models
16 stars 9 forks source link

r2beta fails for GLMs fit with a text formula or as.formula #8

Closed dschlaep closed 4 years ago

dschlaep commented 4 years ago

I have a situation where I programmatically create model formulae with as.formula and paste (see examples for as.formula) -- unfortunately, the function r2beta (more precisely glmPQL) currently fails for such model fits.

I installed the latest version of r2glmm today from github.

Below is an example where I fit a GLM in three ways that all produce the same model fits, but only one works with the current r2beta.

I suggest to fix this from the function r2glmm:::glmPQL by using

mod.form = formula(fit0)

which returns the evaluated formula (i.e., of class "formula", see ?formula and stats:::formula.glm) to replace the current code

mod.form = mod.call[["formula"]]

which returns the object passed to glm (i.e., fit0[["call"]][["formula"]]) which may be unevaluated and not of class "formula".

Thanks!

# Example from documentation of `r2beta`

dis = data.frame(discoveries)
dis$year = 1:nrow(dis)

glmod1 = glm(
  discoveries ~ year + I(year^2),
  family = 'poisson',
  data = dis
)

glmod2 = glm(
  as.formula("discoveries ~ year + I(year^2)"),
  family = 'poisson',
  data = dis
)

glmod3 = glm(
  "discoveries ~ year + I(year^2)",
  family = 'poisson',
  data = dis
)

summary(glmod1)
summary(glmod2)
summary(glmod3)
# These three produce the same coefficients, tests, etc.

r2glmm::r2beta(glmod1)
# Effect   Rsq upper.CL lower.CL
# 1     Model 0.247    0.397    0.125
# 3 I(year^2) 0.189    0.333    0.073
# 2      year 0.132    0.270    0.035

r2glmm::r2beta(glmod2)
# Error in formula.default(object, env = baseenv()) : invalid formula

r2glmm::r2beta(glmod3)
# Error in mod.form[[2L]] <- quote(zz) :
#   long vectors not supported yet: ../../../../R-3.6.2/src/main/subassign.c:1814

Obviously, I could hack my fit so that glm "has" the evaluated formula for r2glmm:::glmPQL to extract, but it would be nice if r2beta would work with normal calls as well!

glmod4 <- do.call(
  "glm",
  args = list(
    as.formula("discoveries ~ year + I(year^2)"),
    family = 'poisson',
    data = dis
  )
)

r2glmm::r2beta(glmod4)
bcjaeger commented 4 years ago

Thanks for catching this! I updated glmPQL with the modification you suggested and committed the changes just a second ago. Please let me know if you run into any more issues.

dschlaep commented 4 years ago

That works beautifully. Thanks for your ultra-fast response and fix!