diff --git a/DESCRIPTION b/DESCRIPTION index 564af64cb..cfaa868d6 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Type: Package Package: bayestestR Title: Understand and Describe Bayesian Models and Posterior Distributions -Version: 0.15.0.3 +Version: 0.15.0.4 Authors@R: c(person(given = "Dominique", family = "Makowski", @@ -95,7 +95,7 @@ Suggests: lavaan, lme4, logspline (>= 2.1.21), - marginaleffects (>= 0.24.0), + marginaleffects (>= 0.24.0.6), MASS, mclust, mediation, @@ -128,4 +128,4 @@ Config/testthat/parallel: true Config/rcmdcheck/ignore-inconsequential-notes: true Config/Needs/website: easystats/easystatstemplate Config/Needs/check: stan-dev/cmdstanr -Remotes: easystats/datawizard +Remotes: easystats/datawizard, vincentarelbundock/marginaleffects diff --git a/NEWS.md b/NEWS.md index 1af4ab5a5..bd534d59e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,10 @@ +# bayestestR 0.15.0.4 + +## Bug fixes + +* Fix to `emmeans` / `marginaleffects` / `data.frame()` methods when using multiple credible levels (#688). + + # bayestestR 0.15.0 ## Changes diff --git a/R/utils.R b/R/utils.R index 9bf719549..206a9c951 100644 --- a/R/utils.R +++ b/R/utils.R @@ -230,7 +230,7 @@ datagrid <- insight::get_datagrid(object) grid_names <- colnames(datagrid) - if (long) { + if (long || nrow(datagrid) < nrow(results)) { datagrid$Parameter <- unique(results$Parameter) results <- datawizard::data_merge(datagrid, results, by = "Parameter") results$Parameter <- NULL @@ -270,7 +270,7 @@ grid_names <- colnames(object)[!is_rvar] datagrid <- data.frame(object[, grid_names, drop = FALSE]) - if (long) { + if (long || nrow(datagrid) < nrow(results)) { datagrid$Parameter <- unique(results$Parameter) results <- datawizard::data_merge(datagrid, results, by = "Parameter") results$Parameter <- NULL diff --git a/tests/testthat/test-data.frame-with-rvar.R b/tests/testthat/test-data.frame-with-rvar.R index 4399c75b0..4c5c373e1 100644 --- a/tests/testthat/test-data.frame-with-rvar.R +++ b/tests/testthat/test-data.frame-with-rvar.R @@ -45,6 +45,13 @@ test_that("data.frame w/ rvar_col descrive_posterior etc", { res <- eti(dfx, rvar_col = "my_rvar", ci = c(0.8, 0.95)) res.ref <- eti(dfx$my_rvar, ci = c(0.8, 0.95)) expect_true(all(c("mu", "sigma") %in% colnames(res))) + expect_identical( + as.data.frame(res[c("mu", "sigma")]), + data.frame( + mu = c(0, 0, 0.5, 0.5, 1, 1), + sigma = c(1, 1, 0.5, 0.5, 0.25, 0.25) + ) + ) expect_identical(nrow(format(res)), 3L) expect_identical(ncol(format(res)), 4L) expect_equal(res[setdiff(colnames(res), c("mu", "sigma"))], diff --git a/tests/testthat/test-emmGrid.R b/tests/testthat/test-emmGrid.R index ed05ad940..a5186830c 100644 --- a/tests/testthat/test-emmGrid.R +++ b/tests/testthat/test-emmGrid.R @@ -30,7 +30,16 @@ test_that("emmGrid hdi", { expect_equal(xhdi$CI_high, all_summ$upper.HPD, tolerance = 0.1) xhdi2 <- hdi(emc_, ci = 0.95) - expect_equal(xhdi$CI_low, xhdi2$CI_low) + expect_identical(xhdi$CI_low, xhdi2$CI_low) + + xhdi3 <- hdi(all_, ci = c(0.9, 0.95)) + expect_identical( + as.data.frame(xhdi3[1:2]), + data.frame( + group = c("1", "1", "2", "2", ".", "."), + contrast = c(".", ".", ".", ".", "group1 - group2", "group1 - group2"), stringsAsFactors = FALSE + ) + ) }) test_that("emmGrid point_estimate", { @@ -39,7 +48,7 @@ test_that("emmGrid point_estimate", { expect_equal(xpest$Median, all_summ$emmean, tolerance = 0.1) xpest2 <- point_estimate(emc_, centrality = "all", dispersion = TRUE) - expect_equal(xpest$Median, xpest2$Median) + expect_identical(xpest$Median, xpest2$Median) }) @@ -114,7 +123,7 @@ test_that("emmGrid rope", { # describe_posterior ------------------------------------------------------ test_that("emmGrid describe_posterior", { - expect_equal( + expect_identical( describe_posterior(all_)$median, describe_posterior(emc_)$median ) @@ -122,7 +131,7 @@ test_that("emmGrid describe_posterior", { expect_identical(colnames(describe_posterior(all_))[1:2], c("group", "contrast")) skip_on_cran() - expect_equal( + expect_identical( describe_posterior(all_, bf_prior = model_p, test = "bf")$log_BF, describe_posterior(emc_, bf_prior = model_p, test = "bf")$log_BF ) @@ -167,9 +176,9 @@ test_that("emmGrid bayesfactor_restricted", { hyps <- c("`1` < `2`", "`1` < 0") xrbf <- bayesfactor_restricted(em_, prior = model_p, hypothesis = hyps) - expect_equal(length(xrbf$log_BF), 2) - expect_equal(length(xrbf$p_prior), 2) - expect_equal(length(xrbf$p_posterior), 2) + expect_length(xrbf$log_BF, 2) + expect_length(xrbf$p_prior, 2) + expect_length(xrbf$p_posterior, 2) expect_warning(bayesfactor_restricted(em_, hypothesis = hyps)) xrbf2 <- bayesfactor_restricted(emc_, prior = model_p, hypothesis = hyps) @@ -182,12 +191,12 @@ test_that("emmGrid si", { xrsi <- si(all_, prior = model_p, verbose = FALSE) expect_identical(colnames(xrsi)[1:2], c("group", "contrast")) - expect_equal(length(xrsi$CI_low), 3) - expect_equal(length(xrsi$CI_high), 3) + expect_length(xrsi$CI_low, 3) + expect_length(xrsi$CI_high, 3) xrsi2 <- si(emc_, prior = model_p, verbose = FALSE) - expect_equal(xrsi$CI_low, xrsi2$CI_low) - expect_equal(xrsi$CI_high, xrsi2$CI_high) + expect_identical(xrsi$CI_low, xrsi2$CI_low) + expect_identical(xrsi$CI_high, xrsi2$CI_high) }) diff --git a/tests/testthat/test-marginaleffects.R b/tests/testthat/test-marginaleffects.R index 8fb654499..e7cecf4d9 100644 --- a/tests/testthat/test-marginaleffects.R +++ b/tests/testthat/test-marginaleffects.R @@ -26,11 +26,34 @@ withr::with_environment( ) expect_true(all(c("term", "contrast") %in% colnames(results))) - expect_equal(results[setdiff(colnames(results), c("term", "contrast"))], + expect_equal(results[setdiff(colnames(results), c("term", "contrast", "am"))], results_draws[setdiff(colnames(results_draws), "Parameter")], ignore_attr = TRUE ) + # multi ci levels + res <- hdi(mfx, ci = c(0.8, 0.9)) + expect_identical( + as.data.frame(res[1:3]), + data.frame( + term = c( + "am", "am", "am", "am", "cyl", "cyl", + "cyl", "cyl", "cyl", "cyl", "cyl", "cyl", + "hp", "hp", "hp", "hp" + ), + contrast = c( + "1 - 0", "1 - 0", "1 - 0", "1 - 0", + "6 - 4", "6 - 4", "8 - 4", "8 - 4", + "6 - 4", "6 - 4", "8 - 4", "8 - 4", + "dY/dX", "dY/dX", "dY/dX", "dY/dX" + ), + am = c( + 0, 0, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, + 1, 1 + ), stringsAsFactors = FALSE + ) + ) + # estimate_density mfx <- marginaleffects::comparisons(mod, variables = "cyl", @@ -67,8 +90,8 @@ withr::with_environment( outsi <- si(mfx, prior = mfxp, verbose = FALSE) outsiref <- si(mfx_samps, prior = mfxp_samps, verbose = FALSE) - expect_true(all(c("term", "contrast") %in% colnames(outsi))) - expect_equal(outsi[setdiff(colnames(outsi), c("term", "contrast"))], + expect_true(all(c("term", "contrast", "am") %in% colnames(outsi))) + expect_equal(outsi[setdiff(colnames(outsi), c("term", "contrast", "am"))], outsiref[setdiff(colnames(outsiref), "Parameter")], ignore_attr = TRUE ) @@ -76,7 +99,7 @@ withr::with_environment( # bayesfactor_parameters bfp <- bayesfactor_parameters(mfx, prior = mfxp, verbose = FALSE) bfpref <- bayesfactor_parameters(mfx_samps, prior = mfxp_samps, verbose = FALSE) - expect_equal(bfp[setdiff(colnames(bfp), c("term", "contrast"))], + expect_equal(bfp[setdiff(colnames(bfp), c("term", "contrast", "am"))], bfpref[setdiff(colnames(bfpref), "Parameter")], ignore_attr = TRUE ) diff --git a/vignettes/bayes_factors.Rmd b/vignettes/bayes_factors.Rmd index fd66023e6..1ff4b13dc 100644 --- a/vignettes/bayes_factors.Rmd +++ b/vignettes/bayes_factors.Rmd @@ -121,7 +121,7 @@ Here we provide functions for computing Bayes factors in two different contexts: - **testing single parameters (coefficients) within a model** - **comparing statistical models themselves** -# Testing Models' Parameters with Bayes Factors {#bayesfactor_parameters} +# 1. Testing Models' Parameters with Bayes Factors {#bayesfactor_parameters} A **Bayes factor for a single parameter** can be used to answer the question: @@ -428,13 +428,8 @@ than the prior densities. In `bayestestR`, this can be achieved with the `si()` function: -```{r} -my_first_si <- si( - posterior = data.frame(group2 = posterior), - prior = data.frame(group2 = prior), - BF = 1, - verbose = FALSE -) +```{r, eval=FALSE} +my_first_si <- si(model, BF = 1) print(my_first_si) ``` @@ -471,7 +466,7 @@ observing the data. decreased by observing the data. Testing against values outside this interval will produce a Bayes factor larger than $1/BF$ in support of the alternative. -# Comparing Models using Bayes Factors {#bayesfactor_models} +# 2. Comparing Models using Bayes Factors {#bayesfactor_models} Bayes factors can also be used to compare statistical **models**. In this statistical context, they answer the following question: @@ -738,7 +733,7 @@ $$ **NOTE**: See the *Specifying Correct Priors for Factors with More Than 2 Levels* appendix below. -# Bayesian Model Averaging +# 3. Bayesian Model Averaging In the previous section, we discussed the direct comparison of two models to determine if an effect is supported by the data. However, in many cases there @@ -792,7 +787,9 @@ bayesfactor_inclusion(comparison, match_models = TRUE) `bayesfactor_inclusion()` is meant to provide Bayes Factors per predictor, similar to JASP's *Effects* option. -Let's compare the two: +Let's compare the two. +Note that for this comparison we will use the `{BayesFactor}` package, which is what _JASP_ uses under the hood. +(Note that this package used different model-parameterization and different default prior-specifications compared to _Stan_-based packages.) 1. **Across all models**: