Skip to content

Add type="terms" support for predict.merMod#19

Draft
Copilot wants to merge 4 commits into
masterfrom
copilot/add-terms-option-to-predict-mermod
Draft

Add type="terms" support for predict.merMod#19
Copilot wants to merge 4 commits into
masterfrom
copilot/add-terms-option-to-predict-mermod

Conversation

Copilot AI commented Mar 18, 2026

Copy link
Copy Markdown

Implements support for type = "terms" in predict.merMod, replacing the previous unimplemented/unused behavior for the terms argument.

<issue_title>type = "terms" for predict.merMod</issue_title>

<issue_description>there's no "terms" option for the type parameter of predict.merMod. Actually, it is currently unused; as shown in the predict.merMod.Rd file:

 \item{terms}{a \code{\link{terms}} object - unused at present.}
```</issue_description>

Changes made

  • Added "terms" as a valid type option in predict.merMod.
  • Implemented term-wise fixed-effect contribution output for type = "terms".
  • Added support for selecting specific terms via the terms argument (terms object, names, or numeric indices).
  • Added validation/errors for invalid combinations and invalid term selectors.
  • Updated predict.merMod.Rd documentation to describe the new behavior.
  • Added focused tests in tests/testthat/test-predict.R for:
    • reconstruction of predictions from term contributions + constant
    • term subsetting behavior
    • validation/error cases

Notes on verification

  • Changes are limited to R/predict.R, man/predict.merMod.Rd, and tests/testthat/test-predict.R.
  • Local R test execution is not available in this sandbox environment because R/Rscript binaries are not installed.
Original prompt

This section details on the original issue you should resolve

<issue_title>type = "terms" for predict.merMod</issue_title>
<issue_description>there's no "terms" option for the type parameter of predict.merMod. Actually, it is currently unused; as shown in the predict.merMod.Rd file:

 \item{terms}{a \code{\link{terms}} object - unused at present.}
```</issue_description>

## Comments on the Issue (you are @copilot in this section)

<comments>
</comments>


📍 Connect Copilot coding agent with Jira, Azure Boards or Linear to delegate work to Copilot in one click without leaving your project management tool.

@annahuynhly

Copy link
Copy Markdown
Owner

@copilot can you try again?

Repository owner deleted a comment from Copilot AI Mar 22, 2026
Repository owner deleted a comment from Copilot AI Mar 22, 2026
Repository owner deleted a comment from Copilot AI Mar 22, 2026
Repository owner deleted a comment from Copilot AI Mar 22, 2026
Repository owner deleted a comment from Copilot AI Mar 22, 2026
Repository owner deleted a comment from Copilot AI Mar 22, 2026
@annahuynhly

Copy link
Copy Markdown
Owner

@copilot could you please try again?

Copilot AI and others added 3 commits March 22, 2026 16:37
Co-authored-by: annahuynhly <97189987+annahuynhly@users.noreply.github.com>
Agent-Logs-Url: https://github.com/annahuynhly/lme4/sessions/421d10e1-3947-4c1f-8bb8-c832d476af22
Co-authored-by: annahuynhly <97189987+annahuynhly@users.noreply.github.com>
Agent-Logs-Url: https://github.com/annahuynhly/lme4/sessions/421d10e1-3947-4c1f-8bb8-c832d476af22

Copilot AI commented Mar 22, 2026

Copy link
Copy Markdown
Author

@copilot can you try again?

Implemented and pushed a full retry for predict.merMod(type="terms") in commit 1f53169, including code, docs, and focused tests for term contributions/validation.

@copilot could you please try again?

Done — I retried and pushed the updated implementation in commit 1f53169 with type="terms" support in predict.merMod, documentation updates, and targeted tests.

Copilot AI changed the title [WIP] Add 'terms' option for predict.merMod type parameter Add type="terms" support for predict.merMod Mar 22, 2026
@annahuynhly

Copy link
Copy Markdown
Owner

@copilot looking at the source code for predict.lm regarding the use of terms, this is what the code looks like:

if (type == "terms") {
    if (!mmDone) {
      mm <- model.matrix(object)
      mmDone <- TRUE
    }
    aa <- attr(mm, "assign")
    ll <- attr(tt, "term.labels")
    hasintercept <- attr(tt, "intercept") > 0L
    if (hasintercept) 
      ll <- c("(Intercept)", ll)
    aaa <- factor(aa, labels = ll)
    asgn <- split(order(aa), aaa)
    if (hasintercept) {
      asgn$"(Intercept)" <- NULL
      avx <- colMeans(mm)
      termsconst <- sum(avx[piv] * beta[piv])
    }
    nterms <- length(asgn)
    if (nterms > 0) {
      predictor <- matrix(ncol = nterms, nrow = NROW(X))
      dimnames(predictor) <- list(rownames(X), names(asgn))
      if (se.fit || interval != "none") {
        ip <- predictor
        Rinv <- qr.solve(qr.R(qr.lm(object))[p1, p1])
      }
      if (hasintercept) 
        X <- sweep(X, 2L, avx, check.margin = FALSE)
      unpiv <- rep.int(0L, NCOL(X))
      unpiv[piv] <- p1
      for (i in seq.int(1L, nterms, length.out = nterms)) {
        iipiv <- asgn[[i]]
        ii <- unpiv[iipiv]
        iipiv[ii == 0L] <- 0L
        predictor[, i] <- if (any(iipiv > 0L)) 
          X[, iipiv, drop = FALSE] %*% beta[iipiv]
        else 0
        if (se.fit || interval != "none") 
          ip[, i] <- if (any(iipiv > 0L)) 
            as.matrix(X[, iipiv, drop = FALSE] %*% Rinv[ii, 
              , drop = FALSE])^2 %*% rep.int(res.var, 
              p)
          else 0
      }
      if (!is.null(terms)) {
        predictor <- predictor[, terms, drop = FALSE]
        if (se.fit) 
          ip <- ip[, terms, drop = FALSE]
      }
    }
    else {
      predictor <- ip <- matrix(0, n, 0L)
    }
    attr(predictor, "constant") <- if (hasintercept) 
      termsconst
    else 0
  }

In general, your code suggestions look a lot different but they could fundamentally be the same thing. What do you think?

Copilot AI commented Mar 22, 2026

Copy link
Copy Markdown
Author

@copilot looking at the source code for predict.lm regarding the use of terms, this is what the code looks like:

...

Yes — they’re fundamentally the same idea (decompose predictions by fixed-effect terms and carry a constant so terms can be summed back), but implemented differently for merMod internals. predict.lm uses QR/pivot/intercept-centering machinery specific to lm; our merMod version uses the fixed-effect model matrix (X) plus assign and then computes constant from the current prediction context. That makes it work with mixed-model features (re.form, offsets, etc.) while preserving reconstruction semantics. If you want strict predict.lm parity (including centered-term behavior), I can do a follow-up patch. Screenshot: N/A (no UI changes).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

type = "terms" for predict.merMod

2 participants