diff --git a/R/binned_residuals.R b/R/binned_residuals.R index 7d9ec9803..d7461c8c7 100644 --- a/R/binned_residuals.R +++ b/R/binned_residuals.R @@ -13,9 +13,15 @@ #' taken. #' @param ci Numeric, the confidence level for the error bounds. #' @param ci_type Character, the type of error bounds to calculate. Can be -#' `"gaussian"` (default), `"exact"` or `"boot"`. +#' `"exact"` (default), `"gaussian"` or `"boot"`. `"exact"` calculates the +#' error bounds based on the exact binomial distribution, using [`binom.test()`]. +#' `"gaussian"` uses the Gaussian approximation, while `"boot"` uses a simple +#' bootstrap method, where confidence intervals are calculated based on the +#' quantiles of the bootstrap distribution. #' @param residuals Character, the type of residuals to calculate. Can be -#' `"response"` (default), `"pearson"` or `"deviance"`. +#' `"deviance"` (default), `"pearson"` or `"response"`. It is recommended to +#' use `"response"` only for those models where other residuals are not +#' available. #' @param iterations Integer, the number of iterations to use for the #' bootstrap method. Only used if `ci_type = "boot"`. #' @param show_dots Logical, if `TRUE`, will show data points in the plot. Set @@ -74,8 +80,8 @@ binned_residuals <- function(model, n_bins = NULL, show_dots = NULL, ci = 0.95, - ci_type = c("gaussian", "exact", "boot"), - residuals = c("response", "pearson", "deviance"), + ci_type = c("exact", "gaussian", "boot"), + residuals = c("deviance", "pearson", "response"), iterations = 1000, ...) { # match arguments @@ -106,6 +112,11 @@ binned_residuals <- function(model, deviance = .safe(stats::residuals(model, type = "deviance")) ) + # make sure we really have residuals + if (is.null(y)) { + insight::format_error("Could not calculate residuals. Try using `residuals = \"response\"`.") + } + if (is.null(n_bins)) n_bins <- round(sqrt(length(pred))) breaks.index <- floor(length(pred) * (1:(n_bins - 1)) / n_bins) @@ -124,7 +135,7 @@ binned_residuals <- function(model, r <- switch(ci_type, gaussian = stats::qnorm(c((1 - ci) / 2, (1 + ci) / 2), mean = ybar, sd = sdev / sqrt(n)), exact = { - out <- stats:::binom.test(sum(y0[items]), n)$conf.int + out <- stats::binom.test(sum(y0[items]), n)$conf.int out <- out - (min(out) - ybar) - (diff(out) / 2) out }, @@ -138,8 +149,7 @@ binned_residuals <- function(model, n = n, x.lo = model.range[1], x.hi = model.range[2], - se = stats::qnorm((1 + ci) / 2) * sdev / sqrt(n), - ci_range = sdev / sqrt(n) + se = stats::qnorm((1 + ci) / 2) * sdev / sqrt(n) ) cbind(d0, rbind(r)) })) diff --git a/R/check_model.R b/R/check_model.R index bbf6c6a84..5e7567d7f 100644 --- a/R/check_model.R +++ b/R/check_model.R @@ -35,7 +35,8 @@ #' tries to guess whether performance will be poor due to a very large model #' and thus automatically shows or hides dots. #' @param verbose If `FALSE` (default), suppress most warning messages. -#' @param ... Currently not used. +#' @param ... Arguments passed down to the individual check functions, especially +#' to `check_predictions()` and `binned_residuals()`. #' @inheritParams check_predictions #' #' @return The data frame that is used for plotting. @@ -185,11 +186,11 @@ check_model.default <- function(x, ca <- tryCatch( { if (minfo$is_bayesian) { - suppressWarnings(.check_assumptions_stan(x)) + suppressWarnings(.check_assumptions_stan(x, ...)) } else if (minfo$is_linear) { - suppressWarnings(.check_assumptions_linear(x, minfo, verbose)) + suppressWarnings(.check_assumptions_linear(x, minfo, verbose, ...)) } else { - suppressWarnings(.check_assumptions_glm(x, minfo, verbose)) + suppressWarnings(.check_assumptions_glm(x, minfo, verbose, ...)) } }, error = function(e) { @@ -346,7 +347,7 @@ check_model.model_fit <- function(x, threshold <- NULL } dat$INFLUENTIAL <- .influential_obs(model, threshold = threshold) - dat$PP_CHECK <- .safe(check_predictions(model)) + dat$PP_CHECK <- .safe(check_predictions(model, ...)) dat <- insight::compact_list(dat) class(dat) <- c("check_model", "see_check_model") @@ -357,7 +358,7 @@ check_model.model_fit <- function(x, # compile plots for checks of generalized linear models ------------------------ -.check_assumptions_glm <- function(model, model_info, verbose = TRUE) { +.check_assumptions_glm <- function(model, model_info, verbose = TRUE, ...) { dat <- list() dat$VIF <- .diag_vif(model, verbose = verbose) @@ -371,9 +372,9 @@ check_model.model_fit <- function(x, threshold <- NULL } dat$INFLUENTIAL <- .influential_obs(model, threshold = threshold) - dat$PP_CHECK <- .safe(check_predictions(model)) + dat$PP_CHECK <- .safe(check_predictions(model, ...)) if (isTRUE(model_info$is_binomial)) { - dat$BINNED_RESID <- binned_residuals(model) + dat$BINNED_RESID <- binned_residuals(model, ...) } if (isTRUE(model_info$is_count)) { dat$OVERDISPERSION <- .diag_overdispersion(model) diff --git a/man/binned_residuals.Rd b/man/binned_residuals.Rd index b913ec53a..33e710f11 100644 --- a/man/binned_residuals.Rd +++ b/man/binned_residuals.Rd @@ -10,8 +10,8 @@ binned_residuals( n_bins = NULL, show_dots = NULL, ci = 0.95, - ci_type = c("gaussian", "exact", "boot"), - residuals = c("response", "pearson", "deviance"), + ci_type = c("exact", "gaussian", "boot"), + residuals = c("deviance", "pearson", "response"), iterations = 1000, ... ) @@ -37,10 +37,16 @@ and thus automatically shows or hides dots.} \item{ci}{Numeric, the confidence level for the error bounds.} \item{ci_type}{Character, the type of error bounds to calculate. Can be -\code{"gaussian"} (default), \code{"exact"} or \code{"boot"}.} +\code{"exact"} (default), \code{"gaussian"} or \code{"boot"}. \code{"exact"} calculates the +error bounds based on the exact binomial distribution, using \code{\link[=binom.test]{binom.test()}}. +\code{"gaussian"} uses the Gaussian approximation, while \code{"boot"} uses a simple +bootstrap method, where confidence intervals are calculated based on the +quantiles of the bootstrap distribution.} \item{residuals}{Character, the type of residuals to calculate. Can be -\code{"response"} (default), \code{"pearson"} or \code{"deviance"}.} +\code{"deviance"} (default), \code{"pearson"} or \code{"response"}. It is recommended to +use \code{"response"} only for those models where other residuals are not +available.} \item{iterations}{Integer, the number of iterations to use for the bootstrap method. Only used if \code{ci_type = "boot"}.} diff --git a/man/check_model.Rd b/man/check_model.Rd index 2bf82af92..d5ead9420 100644 --- a/man/check_model.Rd +++ b/man/check_model.Rd @@ -28,7 +28,8 @@ check_model(x, ...) \arguments{ \item{x}{A model object.} -\item{...}{Currently not used.} +\item{...}{Arguments passed down to the individual check functions, especially +to \code{check_predictions()} and \code{binned_residuals()}.} \item{dot_size, line_size}{Size of line and dot-geoms.}