Skip to content

Commit

Permalink
bayesian_as_frequentist() fails for brms 0 + Intercept formula (#654
Browse files Browse the repository at this point in the history
)

* `bayesian_as_frequentist()` fails for brms `0 + Intercept` formula
Fixes #646

* add test

* simplify

* add test

* fix
  • Loading branch information
strengejacke authored Jul 9, 2024
1 parent 5c5fbdc commit 42fb1da
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 19 deletions.
4 changes: 3 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Type: Package
Package: bayestestR
Title: Understand and Describe Bayesian Models and Posterior Distributions
Version: 0.13.2.4
Version: 0.13.2.5
Authors@R:
c(person(given = "Dominique",
family = "Makowski",
Expand Down Expand Up @@ -76,6 +76,7 @@ Suggests:
BayesFactor (>= 0.9.12-4.4),
bayesQR,
bayesplot,
betareg,
BH,
blavaan,
bridgesampling,
Expand All @@ -88,6 +89,7 @@ Suggests:
ggplot2,
glmmTMB,
httr,
httr2,
KernSmooth,
knitr,
lavaan,
Expand Down
5 changes: 5 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@
* `bayesian_as_frequentist()` now supports more model families from Bayesian
models that can be successfully converted to their frequentists counterparts.

## Bug fixes

* Fixed issue in `bayesian_as_frequentist()` for *brms* models with `0 + Intercept`
specification in the model formula.

# bayestestR 0.13.2

## Breaking Changes
Expand Down
15 changes: 9 additions & 6 deletions R/convert_bayesian_to_frequentist.R
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,14 @@ convert_bayesian_as_frequentist <- function(model, data = NULL, REML = TRUE) {
model_formula <- insight::find_formula(model)
model_family <- insight::get_family(model)

# fix exception: The 0 + Intercept syntax in brms can be used to facilitate
# prior specification for the intercept, but but it leads to issues where it
# wrongly can be believed that Intercept is a variable and not a special term.
f_string <- insight::safe_deparse(model_formula$conditional)
if (grepl("0 + Intercept", f_string, fixed = TRUE)) {
model_formula$conditional <- stats::as.formula(gsub("0 + Intercept", "1", f_string, fixed = TRUE))
}

if (inherits(model_family, "brmsfamily")) {
insight::check_if_installed("glmmTMB")
# exception: ordbetareg()
Expand Down Expand Up @@ -200,12 +208,7 @@ convert_bayesian_as_frequentist <- function(model, data = NULL, REML = TRUE) {
}

fixed_formula <- paste(as.character(formula$conditional)[c(2, 1, 3)], collapse = " ")
cond_formula <- stats::as.formula(paste(
fixed_formula, random_formula,
sep = " + "
))

cond_formula
stats::as.formula(paste(fixed_formula, random_formula, sep = " + "))
}

#' @rdname convert_bayesian_as_frequentist
Expand Down
41 changes: 29 additions & 12 deletions tests/testthat/test-bayesian_as_frequentist.R
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
skip_on_cran()
skip_if_offline()
skip_if_not_or_load_if_installed("httr2")

test_that("rstanarm to freq", {
skip_on_cran()
skip_if_offline()
skip_if_not_or_load_if_installed("rstanarm")
skip_if_not_or_load_if_installed("httr")

set.seed(333)
m <- insight::download_model("stanreg_glm_1")
Expand All @@ -14,11 +15,8 @@ test_that("rstanarm to freq", {


test_that("rstanarm to freq", {
skip_on_cran()
skip_if_offline()
skip_if_not_or_load_if_installed("rstanarm")
skip_if_not_or_load_if_installed("lme4")
skip_if_not_or_load_if_installed("httr")

set.seed(333)
m <- insight::download_model("stanreg_lmerMod_1")
Expand All @@ -30,12 +28,9 @@ test_that("rstanarm to freq", {


test_that("brms beta to freq", {
skip_on_cran()
skip_if_offline()
skip_if_not_or_load_if_installed("brms")
skip_if_not_or_load_if_installed("glmmTMB")
skip_if_not_or_load_if_installed("lme4")
skip_if_not_or_load_if_installed("httr")
skip_if_not_or_load_if_installed("betareg")

set.seed(333)
Expand All @@ -53,13 +48,10 @@ test_that("brms beta to freq", {


test_that("ordbetareg to freq", {
skip_on_cran()
skip_if_offline()
skip_if_not_or_load_if_installed("brms")
skip_if_not_or_load_if_installed("ordbetareg")
skip_if_not_or_load_if_installed("glmmTMB")
skip_if_not_or_load_if_installed("lme4")
skip_if_not_or_load_if_installed("httr")
skip_if_not_or_load_if_installed("datawizard")

set.seed(333)
Expand All @@ -75,3 +67,28 @@ test_that("ordbetareg to freq", {

expect_equal(lme4::fixef(m1), lme4::fixef(m2), tolerance = 1e-1)
})


test_that("brms 0 + Intercept to freq", {
skip_if_not_or_load_if_installed("brms")

set.seed(333)
data(mtcars)
m <- brms::brm(qsec ~ 0 + Intercept + mpg, data = mtcars, refresh = 0)
m1 <- lm(qsec ~ mpg, data = mtcars)
m2 <- convert_bayesian_as_frequentist(m)

expect_equal(coef(m1), coef(m2), tolerance = 1e-2)
})


test_that("brms Interaction terms to freq", {
skip_if_not_or_load_if_installed("brms")

set.seed(333)
m <- brms::brm(qsec ~ mpg * as.factor(am), data = mtcars, refresh = 0)
m1 <- lm(qsec ~ mpg * as.factor(am), data = mtcars)
m2 <- convert_bayesian_as_frequentist(m)

expect_equal(coef(m1), coef(m2), tolerance = 1e-2)
})

0 comments on commit 42fb1da

Please sign in to comment.