Skip to content

Commit 9a4e2dd

Browse files
authored
equivalence_test() bug when applied to glmmTMB models using the beta family (#1159)
* equivalence_test() bug when applied to glmmTMB models using the beta family Fixes #1137 * add test * version * news * fixes * fix * fix * fix * fix * fix test * trigger CI
1 parent eab8054 commit 9a4e2dd

File tree

6 files changed

+60
-25
lines changed

6 files changed

+60
-25
lines changed

DESCRIPTION

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Type: Package
22
Package: parameters
33
Title: Processing of Model Parameters
4-
Version: 0.28.0.10
4+
Version: 0.28.0.13
55
Authors@R:
66
c(person(given = "Daniel",
77
family = "Lüdecke",
@@ -231,4 +231,4 @@ Config/testthat/parallel: true
231231
Config/Needs/website: easystats/easystatstemplate
232232
Config/Needs/check: stan-dev/cmdstanr
233233
Config/rcmdcheck/ignore-inconsequential-notes: true
234-
Remotes: easystats/insight, easystats/bayestestR, easystats/modelbased, vincentarelbundock/marginaleffects
234+
Remotes: easystats/insight, easystats/bayestestR, easystats/modelbased#557, vincentarelbundock/marginaleffects

NEWS.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,11 @@
88
* `model_parameters()` for *marginaleffects* objects is now more robust in
99
detecting Bayesian models.
1010

11+
## Bug fixes
12+
13+
* Fixed issue with `equivalence_test()` for models of class `glmmTMB` with
14+
`beta_family()`.
15+
1116
# parameters 0.28.0
1217

1318
## Breaking Changes

R/equivalence_test.R

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -736,6 +736,11 @@ equivalence_test.parameters_model <- function(x,
736736
{
737737
params <- insight::get_parameters(model)
738738

739+
# remove dispersion components
740+
if (!is.null(params$Component)) {
741+
params <- params[params$Component != "dispersion", ]
742+
}
743+
739744
# degrees of freedom
740745
dof <- insight::get_df(x = model, type = "wald")
741746

@@ -745,6 +750,11 @@ equivalence_test.parameters_model <- function(x,
745750
# se
746751
se <- standard_error(model, vcov = vcov, vcov_args = vcov_args, ...)
747752

753+
# remove dispersion components
754+
if (!is.null(se$Component)) {
755+
se <- se[se$Component != "dispersion", ]
756+
}
757+
748758
stats::pt((range[1] - params$mu) / se$SE, df = dof, lower.tail = TRUE) +
749759
stats::pt((range[2] - params$mu) / se$SE, df = dof, lower.tail = FALSE)
750760
},

R/methods_marginaleffects.R

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,23 +9,22 @@ model_parameters.marginaleffects <- function(model,
99
exponentiate = FALSE,
1010
verbose = TRUE,
1111
...) {
12-
insight::check_if_installed("marginaleffects", minimum_version = "0.28.0.21")
12+
insight::check_if_installed("marginaleffects", minimum_version = "0.28.0.22")
1313

1414
# Bayesian models have posterior draws as attribute
1515
is_bayesian <- !is.null(suppressWarnings(marginaleffects::get_draws(model, "PxD")))
1616

1717
if (is_bayesian) {
1818
# Bayesian
19-
tidy_model <- suppressWarnings(bayestestR::describe_posterior(
19+
out <- suppressWarnings(bayestestR::describe_posterior(
2020
model,
2121
ci = ci,
2222
verbose = verbose,
2323
...
2424
))
2525
} else {
26-
# handle non-Bayesian models
27-
tidy_model <- marginaleffects::tidy(model, conf_level = ci, ...)
28-
26+
# non-Bayesian
27+
out <- as.data.frame(model)
2928
# all columns in data grid and model data, we only want to keep "by" variables
3029
all_data_cols <- union(
3130
colnames(marginaleffects::components(model, "newdata")),
@@ -36,16 +35,12 @@ model_parameters.marginaleffects <- function(model,
3635
marginaleffects::components(model, "variable_names_by"),
3736
marginaleffects::components(model, "variable_names_by_hypothesis")
3837
)
39-
40-
## FIXME: hack to workaround https://github.com/vincentarelbundock/marginaleffects/issues/1573
41-
tidy_model <- .fix_duplicated_by_columns(tidy_model, by_cols)
42-
4338
# remove redundant columns
4439
to_remove <- setdiff(all_data_cols, by_cols)
45-
tidy_model <- tidy_model[, !colnames(tidy_model) %in% to_remove, drop = FALSE]
40+
out <- out[, !colnames(out) %in% to_remove, drop = FALSE]
4641
}
4742

48-
out <- .rename_reserved_marginaleffects(tidy_model)
43+
out <- .rename_reserved_marginaleffects(out)
4944

5045
# need to standardize names for non-Bayesian models. Bayesian models have
5146
# been processed through describe_posterior() already
@@ -118,7 +113,7 @@ model_parameters.predictions <- function(model,
118113
exponentiate = FALSE,
119114
verbose = TRUE,
120115
...) {
121-
insight::check_if_installed("marginaleffects", minimum_version = "0.28.0.21")
116+
insight::check_if_installed("marginaleffects", minimum_version = "0.28.0.22")
122117

123118
# Bayesian models have posterior draws as attribute
124119
is_bayesian <- !is.null(suppressWarnings(marginaleffects::get_draws(model, "PxD")))
@@ -137,10 +132,6 @@ model_parameters.predictions <- function(model,
137132
marginaleffects::components(model, "variable_names_by"),
138133
marginaleffects::components(model, "variable_names_by_hypothesis")
139134
)
140-
141-
## FIXME: hack to workaround https://github.com/vincentarelbundock/marginaleffects/issues/1573
142-
model <- .fix_duplicated_by_columns(model, by_cols)
143-
144135
# handle non-Bayesian models
145136
out <- .rename_reserved_marginaleffects(model)
146137
out <- datawizard::data_rename(out, "estimate", "predicted")

tests/testthat/test-equivalence_test.R

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,36 @@ test_that("equivalence_test, robust", {
1818
expect_snapshot(print(x))
1919
})
2020

21+
test_that("equivalence_test, robust", {
22+
skip_on_cran()
23+
skip_if_not_installed("glmmTMB")
24+
25+
set.seed(123)
26+
sim_data <- data.frame(
27+
x = rbeta(100, 2, 5),
28+
y = sample(0:1, 100, replace = TRUE),
29+
z = rnorm(100),
30+
dataset = rep(1:10, each = 10)
31+
)
32+
33+
mod <- glmmTMB::glmmTMB(
34+
x ~ y * z + (1 | dataset),
35+
data = sim_data,
36+
family = glmmTMB::beta_family(link = "logit")
37+
)
38+
out <- equivalence_test(mod)
39+
expect_identical(dim(out), c(4L, 10L))
40+
expect_identical(
41+
out$ROPE_Equivalence,
42+
c("Rejected", "Undecided", "Accepted", "Undecided")
43+
)
44+
expect_equal(
45+
out$SGPV,
46+
c(0, 0.8726, 0.9739, 0.6741),
47+
tolerance = 1e-3
48+
)
49+
})
50+
2151
test_that("equivalence_test, unequal rope-range", {
2252
data(iris)
2353
m <- lm(Sepal.Length ~ Species, data = iris)

tests/testthat/test-marginaleffects.R

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
skip_if_not_installed("marginaleffects", minimum_version = "0.25.0")
1+
skip_if_not_installed("marginaleffects", minimum_version = "0.28.0.22")
22
skip_if_not_installed("rstanarm")
33

44
test_that("marginaleffects()", {
@@ -48,12 +48,12 @@ test_that("marginaleffects()", {
4848
model <- mgcv::gam(Sepal.Width ~ s(Petal.Length, by = Species), data = iris)
4949
mfx <- marginaleffects::avg_slopes(model, variables = "Petal.Length")
5050
out <- model_parameters(mfx)
51-
expect_identical(dim(out), c(1L, 11L))
51+
expect_identical(dim(out), c(1L, 10L))
5252
expect_named(
5353
out,
5454
c(
5555
"Parameter", "Comparison", "Coefficient", "SE", "Statistic",
56-
"p", "S", "CI", "CI_low", "CI_high", "Predicted"
56+
"p", "S", "CI", "CI_low", "CI_high"
5757
)
5858
)
5959
mfx <- marginaleffects::avg_slopes(model, variables = "Petal.Length", by = "Species")
@@ -181,7 +181,7 @@ test_that("predictions, bmrs with special response formula", {
181181
skip_if_offline()
182182
skip_if_not_installed("httr2")
183183
skip_if_not_installed("brms")
184-
skip_if_not_installed("marginaleffects", minimum_version = "0.28.0.21")
184+
skip_if_not_installed("marginaleffects", minimum_version = "0.28.0.22")
185185

186186
m <- insight::download_model("brms_ipw_1")
187187
skip_if(is.null(m))
@@ -193,14 +193,13 @@ test_that("predictions, bmrs with special response formula", {
193193

194194

195195
test_that("modelbased, tidiers work", {
196-
skip_if_not_installed("marginaleffects", minimum_version = "0.28.0.21")
196+
skip_if_not_installed("marginaleffects", minimum_version = "0.28.0.22")
197197
skip_if_not_installed("modelbased", minimum_version = "0.12.0.17")
198198
skip_if(getRversion() < "4.5.0")
199199

200200
data(penguins)
201201
m <- lm(bill_len ~ island * sex + bill_dep + species, data = penguins)
202202

203-
## FIXME: Need to wait for https://github.com/vincentarelbundock/marginaleffects/issues/1573
204203
out <- modelbased::estimate_contrasts(m, "island", by = "sex", comparison = ratio ~ pairwise)
205204
expect_named(
206205
out,
@@ -266,7 +265,7 @@ test_that("predictions, using bayestestR #1063", {
266265
skip_if_offline()
267266
skip_if_not_installed("httr2")
268267
skip_if_not_installed("brms")
269-
skip_if_not_installed("marginaleffects", minimum_version = "0.28.0.21")
268+
skip_if_not_installed("marginaleffects", minimum_version = "0.28.0.22")
270269

271270
m <- insight::download_model("brms_mixed_3")
272271
skip_if(is.null(m))

0 commit comments

Comments
 (0)