diff --git a/DESCRIPTION b/DESCRIPTION index 5998603cd..cf473fc57 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Type: Package Package: performance Title: Assessment of Regression Models Performance -Version: 0.11.0.2 +Version: 0.11.0.3 Authors@R: c(person(given = "Daniel", family = "Lüdecke", diff --git a/NAMESPACE b/NAMESPACE index 2ecdbf751..7a20bd1dc 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -113,8 +113,10 @@ S3method(check_overdispersion,performance_simres) S3method(check_overdispersion,poissonirr) S3method(check_overdispersion,poissonmfx) S3method(check_predictions,BFBayesFactor) +S3method(check_predictions,brmsfit) S3method(check_predictions,default) S3method(check_predictions,lme) +S3method(check_predictions,stanreg) S3method(check_residuals,DHARMa) S3method(check_residuals,default) S3method(check_residuals,performance_simres) diff --git a/NEWS.md b/NEWS.md index 805cb0dbd..71bc0b355 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,9 +1,20 @@ # performance 0.11.1 +## Breaking + +* Aliases `posterior_predictive_check()` and `check_posterior_predictions()` for + `check_predictions()` are deprecated. + +## General + * Improved documentation and new vignettes added. * `check_model()` gets a `base_size` argument, to set the base font size for plots. +* `check_predictions()` for `stanreg` and `brmsfit` models now returns plots in + the usual style as for other models and no longer returns plots from + `bayesplot::pp_check()`. + # performance 0.11.0 ## New supported models diff --git a/R/check_predictions.R b/R/check_predictions.R index eaa94219b..3fff06ce3 100644 --- a/R/check_predictions.R +++ b/R/check_predictions.R @@ -115,27 +115,99 @@ check_predictions.default <- function(object, # args type <- match.arg(type, choices = c("density", "discrete_dots", "discrete_interval", "discrete_both")) - if (isTRUE(minfo$is_bayesian) && isFALSE(inherits(object, "BFBayesFactor"))) { - insight::check_if_installed( - "bayesplot", - "to create posterior prediction plots for Stan models" + pp_check.lm( + object, + iterations = iterations, + check_range = check_range, + re_formula = re_formula, + bandwidth = bandwidth, + type = type, + verbose = verbose, + model_info = minfo, + ... + ) +} + + +#' @export +check_predictions.stanreg <- function(object, + iterations = 50, + check_range = FALSE, + re_formula = NULL, + bandwidth = "nrd", + type = "density", + verbose = TRUE, + ...) { + # retrieve model information + minfo <- insight::model_info(object, verbose = FALSE) + + # try to find sensible default for "type" argument + suggest_dots <- (minfo$is_bernoulli || minfo$is_count || minfo$is_ordinal || minfo$is_categorical || minfo$is_multinomial) # nolint + if (missing(type) && suggest_dots) { + type <- "discrete_interval" + } + + # args + type <- match.arg(type, choices = c("density", "discrete_dots", "discrete_interval", "discrete_both")) + + # convert to type-argument for pp_check + pp_type <- switch(type, + density = "dens", + "bars" + ) + + insight::check_if_installed( + "bayesplot", + "to create posterior prediction plots for Stan models" + ) + + # for plotting + resp_string <- insight::find_terms(object)$response + + if (inherits(object, "brmsfit")) { + out <- as.data.frame(bayesplot::pp_check(object, type = pp_type, ndraws = iterations, ...)$data) + } else { + out <- as.data.frame(bayesplot::pp_check(object, type = pp_type, nreps = iterations, ...)$data) + } + + # bring data into shape, like we have for other models with `check_predictions()` + if (pp_type == "dens") { + d_filter <- out[!out$is_y, ] + d_filter <- datawizard::data_to_wide( + d_filter, + id_cols = "y_id", + values_from = "value", + names_from = "rep_id" ) - bayesplot::pp_check(object) + d_filter$y_id <- NULL + colnames(d_filter) <- paste0("sim_", colnames(d_filter)) + d_filter$y <- out$value[out$is_y] + out <- d_filter } else { - pp_check.lm( - object, - iterations = iterations, - check_range = check_range, - re_formula = re_formula, - bandwidth = bandwidth, - type = type, - verbose = verbose, - model_info = minfo, - ... + colnames(out) <- c("x", "y", "CI_low", "Mean", "CI_high") + # to long, for plotting + out <- datawizard::data_to_long( + out, + select = c("y", "Mean"), + names_to = "Group", + values_to = "Count" ) } + + attr(out, "is_stan") <- TRUE + attr(out, "check_range") <- check_range + attr(out, "response_name") <- resp_string + attr(out, "bandwidth") <- bandwidth + attr(out, "model_info") <- minfo + attr(out, "type") <- type + class(out) <- c("performance_pp_check", "see_performance_pp_check", class(out)) + out } +#' @export +check_predictions.brmsfit <- check_predictions.stanreg + + #' @export check_predictions.BFBayesFactor <- function(object, iterations = 50, @@ -347,11 +419,17 @@ pp_check.glmmTMB <- #' @rdname check_predictions #' @export -posterior_predictive_check <- check_predictions +posterior_predictive_check <- function(object, ...) { + .Deprecated("check_predictions()") + check_predictions(object, ...) +} #' @rdname check_predictions #' @export -check_posterior_predictions <- check_predictions +check_posterior_predictions <- function(object, ...) { + .Deprecated("check_predictions()") + check_predictions(object, ...) +}