stan-dev / stan-dev/rstanarm

`stan_glmer()` and argument `offset`

Open
#541 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
R
Stars
401
Forks
136
PR merge metrics
No merged PRs in 30d

Description

Summary:

A stan_glmer() fit with offset seems to be handled incorrectly when posterior_linpred() (for example) is called with newdata but without offset.

Description:

First, unlike a stan_glm() fit, a stan_glmer() fit with offsets specified via argument offset doesn't produce an appropriate warning when posterior_linpred() (for example) is called with newdata but without offset. Secondly (and more importantly), in that posterior_linpred() call, the stan_glm() and the stan_glmer() fit differ in what is added to the linear predictor: For stan_glm(), a vector of zeros (and of appropriate length) is added, while for stan_glmer(), the original offsets are recycled so that they match the number of observations in newdata. The underlying issue might be that .pp_data_mer() lacks a call to .pp_data_offset(), unlike .pp_data() and .pp_data_nlmer().

Reproducible Steps:
library(rstanarm)
options(mc.cores = parallel::detectCores(logical = FALSE))
data("kidiq")
kidiq_gr <- within(kidiq, {
  agegr <- cut(mom_age,
               breaks = unique(quantile(mom_age)),
               include.lowest = TRUE)
  levels(agegr) <- paste0("lvl", seq_len(nlevels(agegr)))
})
set.seed(3492)
offs_vec <- rnorm(nrow(kidiq))
glmm_fit <- stan_glmer(kid_score ~ mom_iq + (1 | agegr),
                       data = kidiq_gr,
                       offset = offs_vec,
                       seed = 734572)
kidiq_gr_new <- head(kidiq_gr, 3)
glmm_pl <- posterior_linpred(glmm_fit, newdata = kidiq_gr_new)

The last line throws the warning

Warning in sweep(eta, 2L, offset, `+`) :
  STATS is longer than the extent of 'dim(x)[MARGIN]'

In contrast, with stan_glm(), an appropriate warning is thrown:

glm_fit <- stan_glm(kid_score ~ mom_iq + agegr,
                    data = kidiq_gr,
                    offset = offs_vec,
                    seed = 734572)
glm_pl <- posterior_linpred(glm_fit, newdata = kidiq_gr_new)

namely

Warning: 'offset' argument is NULL but it looks like you estimated the model using an offset term.

Calling debug(rstanarm:::linear_predictor) before those posterior_linpred() calls reveals that for the stan_glm() fit, offset is a vector of 3 zeros, while for the stan_glmer() fit, offset is the original offs_vec vector (of length nrow(kidiq) = 434).

RStanARM Version:

2.21.2 (from https://mc-stan.org/r-packages/)

R Version:

4.1.0

Operating System:

Windows 10

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with posterior_linpred() and linear_predictor(), then compare .pp_data_mer() with .pp_data() and .pp_data_nlmer(), especially the missing .pp_data_offset() call. Reproduce the supplied stan_glmer() example and compare it with stan_glm(). Done means newdata without offset gives the appropriate warning and does not recycle the original offsets.

Written by the indexing model from the issue text.

Assessment

Tech stack
r
Domain
data
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.