Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
9f2fbc6
new lmerMod methods
mattansb Oct 13, 2026
4c4f259
docs
mattansb Oct 13, 2026
90d8a87
news and version bump
mattansb Oct 13, 2026
7cb0086
use explicit function def
mattansb Oct 13, 2026
66e06c8
Update methods_lme4.R
mattansb Oct 13, 2026
7671027
don't use Satterthwaite when bootstrapping
mattansb Oct 13, 2026
324cd55
add tests
mattansb Oct 13, 2026
23f2bd0
fix some tests
mattansb Oct 13, 2026
be07cd0
fix vcov being overwritten by satterthwaite
mattansb Oct 14, 2026
06ca11d
correctly name lmerModLmerTest
mattansb Oct 14, 2026
8a08d4c
fix a zillion tests
mattansb Oct 15, 2026
88cb5fa
just the snaps
mattansb Oct 15, 2026
17534e7
update snaps
strengejacke Oct 15, 2026
0614223
fix RD
strengejacke Oct 15, 2026
7dcac78
Merge branch 'main' into default-satterthwaite
strengejacke Oct 15, 2026
6ce41b0
fix more tests
mattansb Oct 15, 2026
b76c21e
double check for lmerMod class
mattansb Oct 15, 2026
520b90e
oops
mattansb Oct 15, 2026
f2b1d0d
double oops
mattansb Oct 15, 2026
d38d3d0
i hate this so much
mattansb Oct 15, 2026
fcba851
fix one last time (haha yeah right)
mattansb Oct 15, 2026
3dbb2f0
snaps
mattansb Oct 15, 2026
e12e4ac
Merge branch 'main' into default-satterthwaite
strengejacke Oct 15, 2026
cd0395c
updates
strengejacke Oct 15, 2026
4a7360f
add snapshot
strengejacke Oct 15, 2026
64ac096
re-add ci_random test for also including the fixef
mattansb Oct 15, 2026
08b89db
Restore the glmgee snapshot deleted by a local test run
jmgirard Oct 15, 2026
463cade
Merge branch 'main' into default-satterthwaite
strengejacke Oct 15, 2026
e759d35
always pass ci_method
mattansb Oct 15, 2026
7c7ec0b
rewrite logic
mattansb Oct 15, 2026
160dabf
Fall back to Wald when Satterthwaite df fail, and keep robust vcov in…
jmgirard Oct 15, 2026
80f4272
setup new default
mattansb Oct 19, 2026
64690f4
fix compare_parameters default ci
mattansb Oct 19, 2026
307e2d2
fix tests
mattansb Oct 19, 2026
d688e87
Merge remote-tracking branch 'origin/main' into default-satterthwaite
jmgirard Oct 19, 2026
fee935f
Fix failing tests for the Satterthwaite default
jmgirard Oct 19, 2026
1251d6d
Update R/compare_parameters.R
mattansb Oct 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Type: Package
Package: parameters
Title: Processing of Model Parameters
Version: 0.30.0.10
Version: 0.30.0.11
Authors@R:
c(person(given = "Daniel",
family = "Lüdecke",
Expand Down Expand Up @@ -241,4 +241,4 @@ Config/testthat/parallel: false
Config/Needs/website: easystats/easystatstemplate
Config/Needs/check: stan-dev/cmdstanr
Config/rcmdcheck/ignore-inconsequential-notes: true
Config/roxygen2/version: 8.1.0
Config/roxygen2/version: 8.1.1
4 changes: 4 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ S3method(ci,list)
S3method(ci,lm)
S3method(ci,lm_robust)
S3method(ci,lme)
S3method(ci,lmerMod)
S3method(ci,lmodel2)
S3method(ci,logistf)
S3method(ci,logitmfx)
Expand Down Expand Up @@ -289,6 +290,7 @@ S3method(model_parameters,lcmm)
S3method(model_parameters,list)
S3method(model_parameters,lm_robust)
S3method(model_parameters,lme)
S3method(model_parameters,lmerMod)
S3method(model_parameters,lmodel2)
S3method(model_parameters,logistf)
S3method(model_parameters,logitmfx)
Expand Down Expand Up @@ -501,6 +503,7 @@ S3method(p_value,list)
S3method(p_value,lm)
S3method(p_value,lm_robust)
S3method(p_value,lme)
S3method(p_value,lmerMod)
S3method(p_value,lmodel2)
S3method(p_value,logistf)
S3method(p_value,logitmfx)
Expand Down Expand Up @@ -852,6 +855,7 @@ S3method(standard_error,lcmm)
S3method(standard_error,list)
S3method(standard_error,lm_robust)
S3method(standard_error,lme)
S3method(standard_error,lmerMod)
S3method(standard_error,lmodel2)
S3method(standard_error,logistf)
S3method(standard_error,logitmfx)
Expand Down
9 changes: 9 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# parameters (devel)

## Breaking Changes

* `compare_parameters()`'s `ci_method` now defaults to `NULL`, so the value is
potentially set by the models' unique methods.

* `model_parameters()`, `ci()`, `standard_error()`, and `p_value()` now default
to the Satterthwaite approximation for `lmerModLmerTest` models and suggest
doing so for `lmerMod` models (#989).

## Changes

* `model_parameters()` for models from *blavaan* with `standardize` no longer
Expand Down
3 changes: 3 additions & 0 deletions R/1_model_parameters.R
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,9 @@
#' - Applies to *linear mixed models*. CIs computed using the
#' Wald method (SE and a *t-distribution with Satterthwaite df*); p-values
#' computed using the Wald method with a *t-distribution with Satterthwaite df*.
#' This is the default for `lmerModLmerTest` models when the corresponding
#' method argument (`ci_method` or `method`) is `NULL` (and
#' `bootstrap = FALSE`).
#'
#' `"kenward"`
#' - Applies to *linear mixed models*. CIs computed using the Wald
Expand Down
2 changes: 1 addition & 1 deletion R/ci_generic.R
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,13 @@
)
)

if (method == "ml1") {

Check warning on line 38 in R/ci_generic.R

View workflow job for this annotation

GitHub Actions / lint-changed-files / lint-changed-files

file=R/ci_generic.R,line=38,col=3,[if_switch_linter] Prefer switch() statements over repeated if/else equality tests, e.g., switch(x, a = 1, b = 2) over if (x == "a") 1 else if (x == "b") 2.

Check warning on line 38 in R/ci_generic.R

View workflow job for this annotation

GitHub Actions / lint / lint

file=R/ci_generic.R,line=38,col=3,[if_switch_linter] Prefer switch() statements over repeated if/else equality tests, e.g., switch(x, a = 1, b = 2) over if (x == "a") 1 else if (x == "b") 2.
# nolint
return(ci_ml1(model, ci = ci))
} else if (method == "betwithin") {
return(ci_betwithin(model, ci = ci))
} else if (method == "satterthwaite") {
return(ci_satterthwaite(model, ci = ci))
return(ci_satterthwaite(model, ci = ci, vcov = vcov, vcov_args = vcov_args, ...))
} else if (method %in% c("kenward", "kr")) {
return(ci_kenward(model, ci = ci))
}
Expand Down
115 changes: 82 additions & 33 deletions R/compare_parameters.R
Original file line number Diff line number Diff line change
Expand Up @@ -69,23 +69,25 @@
#' compare_parameters(list("linear model" = m1, "logistic reg." = m2))
#' }
#' @export
compare_parameters <- function(...,
ci = 0.95,
effects = "fixed",
component = "conditional",
standardize = NULL,
exponentiate = FALSE,
ci_method = "wald",
p_adjust = NULL,
select = NULL,
column_names = NULL,
pretty_names = TRUE,
coefficient_names = NULL,
keep = NULL,
drop = NULL,
include_reference = FALSE,
groups = NULL,
verbose = TRUE) {
compare_parameters <- function(
...,
ci = 0.95,
effects = "fixed",
component = "conditional",
standardize = NULL,
exponentiate = FALSE,
ci_method = NULL,
p_adjust = NULL,
select = NULL,
column_names = NULL,
pretty_names = TRUE,
coefficient_names = NULL,
keep = NULL,
drop = NULL,
include_reference = FALSE,
groups = NULL,
verbose = TRUE
) {
models <- list(...)

if (length(models) == 1) {
Expand Down Expand Up @@ -117,14 +119,23 @@ compare_parameters <- function(...,
}
}

supported_models <- vapply(models, function(i) {
insight::is_model_supported(i) || inherits(i, "lavaan") || inherits(i, "parameters_model")
}, TRUE)
supported_models <- vapply(
models,
function(i) {
insight::is_model_supported(i) ||
inherits(i, "lavaan") ||
inherits(i, "parameters_model")
},
TRUE
)

if (!all(supported_models)) {
if (verbose) {
insight::format_alert(
sprintf("Following objects are not supported: %s", toString(model_names[!supported_models])),
sprintf(
"Following objects are not supported: %s",
toString(model_names[!supported_models])
),
"Dropping unsupported models now."
)
}
Expand Down Expand Up @@ -169,7 +180,15 @@ compare_parameters <- function(...,
dat <- model
} else {
# set default-ci_type for Bayesian models
if (insight::is_bayesian_model(model, exclude = c("bmerMod", "bayesx", "blmerMod", "bglmerMod")) && !ci_method %in% c("hdi", "quantile", "ci", "eti", "si", "bci", "bcai")) { # nolint
if (
insight::is_bayesian_model(
model,
exclude = c("bmerMod", "bayesx", "blmerMod", "bglmerMod")
) &&
(is.null(ci_method) ||
!ci_method %in% c("hdi", "quantile", "ci", "eti", "si", "bci", "bcai"))
) {
# nolint
ci_method_tmp <- "eti"
} else {
ci_method_tmp <- ci_method
Expand Down Expand Up @@ -217,7 +236,10 @@ compare_parameters <- function(...,

# add zi-suffix to parameter names
if (any(dat$Component == "zero_inflated")) {
dat$Parameter[dat$Component == "zero_inflated"] <- paste0(dat$Parameter[dat$Component == "zero_inflated"], " (zi)")
dat$Parameter[dat$Component == "zero_inflated"] <- paste0(
dat$Parameter[dat$Component == "zero_inflated"],
" (zi)"
)
}

# add suffix
Expand All @@ -235,15 +257,28 @@ compare_parameters <- function(...,
names(object_attributes) <- model_names

# merge all data frames
all_models <- suppressWarnings(Reduce(function(x, y) {
merge(x, y, all = TRUE, sort = FALSE, by = c("Parameter", "Component", "Effects", "Group"))
}, m))
all_models <- suppressWarnings(Reduce(
function(x, y) {
merge(
x,
y,
all = TRUE,
sort = FALSE,
by = c("Parameter", "Component", "Effects", "Group")
)
},
m
))

# find columns with model numbers and create new variable "params_order",
# which is pasted together of all model-column indices. Take lowest index of
# all model-column indices, which then indicates order of parameters/rows.
model_cols <- which(startsWith(colnames(all_models), "model"))
params_order <- as.numeric(substr(gsub("NA", "", do.call(paste0, all_models[model_cols]), fixed = TRUE), 0, 1))
params_order <- as.numeric(substr(
gsub("NA", "", do.call(paste0, all_models[model_cols]), fixed = TRUE),
0,
1
))

all_models <- all_models[order(params_order), ]
all_models[model_cols] <- NULL
Expand All @@ -253,11 +288,20 @@ compare_parameters <- function(...,
all_models$Group <- NULL
}

attr(all_models, "model_names") <- gsub("\"", "", unlist(lapply(model_names, insight::safe_deparse)), fixed = TRUE)
attr(all_models, "model_names") <- gsub(
"\"",
"",
unlist(lapply(model_names, insight::safe_deparse)),
fixed = TRUE
)
attr(all_models, "output_style") <- select
attr(all_models, "all_attributes") <- object_attributes
attr(all_models, "parameter_groups") <- groups
class(all_models) <- c("compare_parameters", "see_compare_parameters", unique(class(all_models)))
class(all_models) <- c(
"compare_parameters",
"see_compare_parameters",
unique(class(all_models))
)

all_models
}
Expand All @@ -270,11 +314,12 @@ compare_models <- compare_parameters

# helper ----------------------------


.set_pretty_names <- function(x, pretty_names) {
# check if pretty names should be replaced by value labels
# (if we have labelled data)
if (isTRUE(getOption("parameters_labels", FALSE)) || identical(pretty_names, "labels")) {
if (
isTRUE(getOption("parameters_labels", FALSE)) || identical(pretty_names, "labels")
) {
attr(x, "pretty_names") <- attr(x, "pretty_labels", exact = TRUE)
pretty_names <- TRUE
}
Expand All @@ -288,15 +333,19 @@ compare_models <- compare_parameters
match_pretty_names <- match(names(att$pretty_names), x$Parameter)
match_pretty_names <- match_pretty_names[!is.na(match_pretty_names)]
if (length(match_pretty_names)) {
x$Parameter[match_pretty_names] <- att$pretty_names[x$Parameter[match_pretty_names]]
x$Parameter[match_pretty_names] <- att$pretty_names[x$Parameter[
match_pretty_names
]]
}
} else {
match_pretty_names <- att$pretty_names[x$Parameter]
if (anyNA(match_pretty_names)) {
match_pretty_names <- match(names(att$pretty_names), x$Parameter)
match_pretty_names <- match_pretty_names[!is.na(match_pretty_names)]
if (length(match_pretty_names)) {
x$Parameter[match_pretty_names] <- att$pretty_names[x$Parameter[match_pretty_names]]
x$Parameter[match_pretty_names] <- att$pretty_names[x$Parameter[
match_pretty_names
]]
}
} else {
x$Parameter <- att$pretty_names[x$Parameter]
Expand Down
13 changes: 10 additions & 3 deletions R/extract_parameters.R
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# generic function ------------------------------------------------------

#' @keywords internal
.extract_parameters_generic <- function(

Check warning on line 4 in R/extract_parameters.R

View workflow job for this annotation

GitHub Actions / lint-changed-files / lint-changed-files

file=R/extract_parameters.R,line=4,col=1,[cyclocomp_linter] Reduce the cyclomatic complexity of this expression from 69 to at most 40. Consider replacing high-complexity sections like loops and branches with helper functions.
model,
ci,
component,
Expand Down Expand Up @@ -522,7 +522,8 @@
ci = ci,
vcov = vcov,
vcov_args = vcov_args,
verbose = verbose
verbose = verbose,
method = ci_method
)
fun_args <- c(fun_args, dots)
ci_df <- suppressMessages(do.call("ci", fun_args))
Expand Down Expand Up @@ -567,7 +568,13 @@

# p value
if (!is.null(vcov)) {
fun_args <- list(model, vcov = vcov, vcov_args = vcov_args, verbose = verbose)
fun_args <- list(
model,
vcov = vcov,
vcov_args = vcov_args,
verbose = verbose,
method = ci_method
)
fun_args <- c(fun_args, dots)
parameters <- merge(
parameters,
Expand All @@ -588,7 +595,7 @@
} else {
parameters <- merge(
parameters,
p_value(model, dof = dof, effects = "fixed"),
p_value(model, dof = dof, method = ci_method, effects = "fixed"),
by = "Parameter",
sort = FALSE
)
Expand Down
3 changes: 2 additions & 1 deletion R/format.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#' @inheritParams print.parameters_model
#' @rdname print.parameters_model
#' @export
format.parameters_model <- function(

Check warning on line 6 in R/format.R

View workflow job for this annotation

GitHub Actions / lint-changed-files / lint-changed-files

file=R/format.R,line=6,col=1,[cyclocomp_linter] Reduce the cyclomatic complexity of this expression from 67 to at most 40. Consider replacing high-complexity sections like loops and branches with helper functions.
x,
pretty_names = TRUE,
split_components = TRUE,
Expand Down Expand Up @@ -259,7 +259,7 @@
#' @rdname print.compare_parameters
#' @inheritParams print.parameters_model
#' @export
format.compare_parameters <- function(

Check warning on line 262 in R/format.R

View workflow job for this annotation

GitHub Actions / lint-changed-files / lint-changed-files

file=R/format.R,line=262,col=1,[cyclocomp_linter] Reduce the cyclomatic complexity of this expression from 41 to at most 40. Consider replacing high-complexity sections like loops and branches with helper functions.
x,
split_components = TRUE,
select = NULL,
Expand Down Expand Up @@ -736,7 +736,7 @@


# footer: type of uncertainty interval
.print_footer_cimethod <- function(x) {

Check warning on line 739 in R/format.R

View workflow job for this annotation

GitHub Actions / lint-changed-files / lint-changed-files

file=R/format.R,line=739,col=1,[cyclocomp_linter] Reduce the cyclomatic complexity of this expression from 49 to at most 40. Consider replacing high-complexity sections like loops and branches with helper functions.
if (!isTRUE(getOption("parameters_cimethod", TRUE))) {
return()
}
Expand Down Expand Up @@ -869,7 +869,8 @@
show_re_msg <- (identical(model_class, "glmmTMB") &&
(!string_method %in% c("Wald z-", "Wald normal") ||
!ci_method %in% c("wald", "normal"))) ||
((identical(model_class, "lmerMod") || identical(model_class, "glmerMod")) &&
(length(model_class) == 1L &&
model_class %in% c("lmerMod", "lmerModLmerTest", "glmerMod") &&
!ci_method %in% c("wald", "normal", "profile", "boot"))

if (
Expand Down Expand Up @@ -954,5 +955,5 @@
"Some coefficients seem to be rather large, which may indicate issues with (quasi) complete separation. Consider using bias-corrected or penalized regression models."
)
}
return(NULL)

Check warning on line 958 in R/format.R

View workflow job for this annotation

GitHub Actions / lint-changed-files / lint-changed-files

file=R/format.R,line=958,col=3,[return_linter] Use implicit return behavior; explicit return() is not needed.
}
Loading
Loading