Skip to content

Conversation

@DominiqueMakowski
Copy link
Member

Recently I was embroiled in discussions about how to interpret (i.e., the unit) of grouplevel estimates, which can become tricky for complex models. I suggested estimating group-level estimates directly using marginal means rather than raw ranefs. This actually would be a useful addition to estimate_grouplevel.

Currently only works on simple-ish cases, there are edgecases where it probably needs to be tested.
But it works, currently correlates perfectly r=1 with the other methods.

@gemini-code-assist
Copy link

Summary of Changes

Hello @DominiqueMakowski, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a significant enhancement to the estimate_grouplevel() function by adding a new 'marginal' estimation method. This new approach aims to provide more interpretable group-level parameter estimates by computing them based on marginal means and effects, which can be particularly beneficial for understanding complex mixed models. While currently experimental, it offers a novel way to conceptualize and present group-level variations.

Highlights

  • New 'marginal' estimation method: The estimate_grouplevel() function now includes a new type = "marginal" option for estimating group-level parameters. This method recomputes estimates using model predictions, specifically marginal means for intercepts and marginal effects for slopes.
  • Improved Interpretability: The primary benefit of the new 'marginal' method is enhanced interpretability. Random intercepts directly correspond to the 'mean' outcome value for each group, and random slopes represent the direct 'effect' of a predictor for each group.
  • Experimental Status and Correlation: The 'marginal' method is currently experimental. Initial tests show a perfect correlation (r=1) with existing 'random' and 'total' methods in simple cases, suggesting consistency in its estimates.
  • Internal Implementation: A new internal function, .grouplevel_marginal(), has been introduced to handle the logic for this new estimation type, leveraging estimate_means() and estimate_slopes() for its calculations.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

DominiqueMakowski and others added 3 commits October 4, 2025 08:59
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull Request Overview

This PR adds a new "marginal" method to estimate_grouplevel() for estimating group-level parameters using marginal means and effects rather than raw random effects. The feature provides improved interpretability by computing random intercepts as mean outcome values and random slopes as direct predictor effects.

  • Adds "marginal" type option to estimate_grouplevel() function
  • Implements marginal estimation using estimate_means() and estimate_slopes()
  • Updates documentation to describe the new experimental method

Reviewed Changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 6 comments.

File Description
R/estimate_grouplevel.R Implements the new marginal estimation method and updates function logic
man/estimate_grouplevel.Rd Updates documentation to describe the new "marginal" type option

Tip: Customize your code reviews with copilot-instructions.md. Create the file or learn how to get started.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new experimental marginal method to estimate_grouplevel(), which is an interesting approach for interpreting group-level parameters. The implementation looks like a good start. My review focuses on improving the robustness and maintainability of this new feature. The main points are the need for automated tests to ensure correctness, removing commented-out test code from the source, and addressing some of the limitations of the experimental implementation, such as by providing warnings for unsupported cases like factor-based random slopes. Overall, a promising addition.

DominiqueMakowski and others added 9 commits October 4, 2025 09:00
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@DominiqueMakowski
Copy link
Member Author

@copilot could you add tests

@strengejacke
Copy link
Member

I asked Gemini to add a test, not sure if that test is super good or not. But I saw in your "Quick examples" that the first example returns a different value than expected?

library(modelbased)
model <- lme4::lmer(mpg ~ hp + (1 | carb), data = mtcars)
model <- lme4::lmer(mpg ~ hp + (1 + hp | carb), data = mtcars)
#> boundary (singular) fit: see help('isSingular')
model <- lme4::lmer(mpg ~ hp + (1 + hp | carb) + (1 | gear), data = mtcars)
#> boundary (singular) fit: see help('isSingular')

m1 <- estimate_grouplevel(model, type = "random")
m2 <- estimate_grouplevel(model, type = "total")
m3 <- estimate_grouplevel(model, type = "marginal")
cor.test(m1$Coefficient, m3$Coefficient)  # r = 1
#> 
#>  Pearson's product-moment correlation
#> 
#> data:  m1$Coefficient and m3$Coefficient
#> t = 0.39984, df = 13, p-value = 0.6958
#> alternative hypothesis: true correlation is not equal to 0
#> 95 percent confidence interval:
#>  -0.4261020  0.5892142
#> sample estimates:
#>       cor 
#> 0.1102191
cor.test(m2$Coefficient, m3$Coefficient)  # r = 1
#> 
#>  Pearson's product-moment correlation
#> 
#> data:  m2$Coefficient and m3$Coefficient
#> t = 61.877, df = 13, p-value < 2.2e-16
#> alternative hypothesis: true correlation is not equal to 0
#> 95 percent confidence interval:
#>  0.9947589 0.9994535
#> sample estimates:
#>       cor 
#> 0.9983066

Created on 2025-10-04 with reprex v2.1.1

@codecov
Copy link

codecov bot commented Oct 4, 2025

Codecov Report

❌ Patch coverage is 96.36364% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.72%. Comparing base (f79d3bf) to head (4e6acf9).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
R/estimate_grouplevel.R 96.36% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #574      +/-   ##
==========================================
+ Coverage   90.63%   90.72%   +0.09%     
==========================================
  Files          40       40              
  Lines        3364     3397      +33     
==========================================
+ Hits         3049     3082      +33     
  Misses        315      315              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@strengejacke
Copy link
Member

Should we probably also add estimate = "average" if we want marginal estimates?

DominiqueMakowski and others added 3 commits October 4, 2025 14:58
@strengejacke yeah it's because we were correlating apples and potatoes
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@DominiqueMakowski
Copy link
Member Author

hould we probably also add estimate = "average"

Yes I think this makes sense

strengejacke and others added 2 commits October 6, 2025 11:47
Co-authored-by: Dominique Makowski <dom.mak19@gmail.com>
@strengejacke strengejacke merged commit e5246db into main Oct 6, 2025
20 of 21 checks passed
@strengejacke strengejacke deleted the grouplevel_marginal branch October 6, 2025 10:20
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.

3 participants