Skip to content

Keep by variables whose names insight renames (marginaleffects backend) - #677

Merged
strengejacke merged 8 commits into
easystats:mainfrom
jmgirard:focal-names-insight-renames
Oct 13, 2026
Merged

strengejacke merged 8 commits into
easystats:mainfrom
jmgirard:focal-names-insight-renames

Conversation

@jmgirard

Copy link
Copy Markdown
Contributor

With the marginaleffects backend, some by variable names caused trouble. If insight or modelbased also uses the name for a column, the variable was dropped or renamed, or it mislabeled other columns. .standardize_marginaleffects_columns() calls parameters::model_parameters(), which runs insight::standardize_names(), and then removes some columns by name. For example, with lm and a factor by variable:

  • type, p, CI, S, predicted, conf.level, df_residual and df_error were dropped,
  • n became n_Obs, value became Level, response became Response, and so on,
  • a variable named Median was labeled Mean, and the means were labeled Coefficient,
  • F, Chi2, chisq, Chisq and W replaced the t column with the factor levels.

This PR gives these focal columns temporary names before model_parameters() and restores the original names after the renaming and removal steps. A focal column is protected only if all its values occur in the data grid. Columns that marginaleffects writes itself (for example hypothesis in contrasts, or s.value) are handled as before. Bayesian models are not changed, because describe_posterior() drops columns it does not know.

Not fixed here:

  • by variables named like an output column of the same call (Mean in means, p in slopes, Difference and p in contrasts). Following the answer in Keep marginaleffects focal terms named like reserved columns parameters#1274, I plan a separate PR that keeps our column name and renames the variable (for example p.1).
  • s.value, predicted and hypothesis, which marginaleffects overwrites with its own values.
  • Bayesian models and inequality comparisons.

Tests: a new file, test-focal-name-clashes.R, compares each call with the same call where the variable is named safe_var. It covers estimate_means() with one and two focal terms, estimate_slopes(by =), estimate_contrasts(by =) and estimate_contrasts(). It uses 99 candidate names. The test also checks that every name which worked on main still works. The output for the neutral name is identical to main.

Two other test fixes:

  • test-visualisation_recipe.R lost the closing }) of one test in Color plots of emmeans ordinal output by response category or threshold #676, so the file did not parse on main. This adds it back.
  • test-brms.R:26 required every median from a random 200-draw subsample to differ from the full-draw median by more than 0.001, which failed in 6 of 10 local runs. It now checks that the medians differ and that iterations = 200 keeps 200 draws.

devtools::test() and devtools::check() locally: 0 failures, 0 errors, 0 warnings.

The version is bumped to 0.17.0.11.

model_parameters() renames columns such as type, n or value, and the
format step removes columns such as p, CI or S by name. A by variable
with one of these names was dropped, renamed, or mislabeled other
columns. Focal columns that hold the data grid values now get temporary
names until the renaming is done.
The "recipes that do not change" test in test-visualisation_recipe.R
had no closing "})", so the file did not parse and devtools::test()
stopped there.
Another test file assigns a global d, which the formula environment
could find before the local data.
The test asked every median from a random 200-draw subsample to differ
from the full-draw median by more than 0.001, which failed in 6 of 10
local runs. It now tests that the medians differ and that 200 draws
are kept.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟡 Changes recommended

Focal names can still collide with temporary or generated columns, and custom grids can bypass the protection.

3 open findings
What changed in this PR

This PR protects focal variable names while the marginaleffects backend formats means, slopes, and contrasts.

Changes:

  • Temporarily renames focal columns during formatting and adds name-clash tests.
  • Repairs two existing tests, documents the fix, and bumps the development version.
File Description
tests/​testthat/​test-visualisation_recipe.R Restores a missing test closure.
tests/​testthat/​test-focal-name-clashes.R Adds focal-name regression coverage.
tests/​testthat/​test-brms.R Replaces a flaky median assertion.
R/​format.R Protects focal columns during standardization.
NEWS.md Documents the behavior change and limits.
DESCRIPTION Bumps the development version.

🧠 Review effort: Lite


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread R/format.R
Comment thread R/format.R Outdated
Comment thread R/format.R Outdated
With a custom newdata, the datagrid attribute holds the generated grid,
not the one passed to marginaleffects, so focal columns were not
protected. Temporary column names are now also unique against the
existing columns.
@strengejacke

Copy link
Copy Markdown
Member

Thanks, looks good to me!

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