diff --git a/NEWS.md b/NEWS.md index 941ef230..522d5bf6 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,6 +4,7 @@ * `ppc_error_scatter_avg_vs_x(x = some_expression)` labels the *x* axis with `some_expression`. * Add `ppc_dots()` and `ppd_dots()` by @behramulukir (#357) * Add `x` argument to `ppc_error_binned` by @behramulukir (#359) +* Add `x` argument to `ppc_error_scatter_avg()` by @behramulukir (#367) # bayesplot 1.13.0 diff --git a/R/ppc-errors.R b/R/ppc-errors.R index f53f869d..31ecfb2b 100644 --- a/R/ppc-errors.R +++ b/R/ppc-errors.R @@ -54,10 +54,12 @@ #' `y` and each dataset (row) in `yrep`. For each individual data point #' `y[n]` the average error is the average of the errors for `y[n]` computed #' over the the draws from the posterior predictive distribution. +#' +#' When the optional `x` argument is provided, the average error is plotted +#' on the y-axis and the predictor variable `x` is plotted on the x-axis. #' } #' \item{`ppc_error_scatter_avg_vs_x()`}{ -#' Same as `ppc_error_scatter_avg()`, except the average is plotted on the -#' y-axis and a predictor variable `x` is plotted on the x-axis. +#' Deprecated. Use `ppc_error_scatter_avg(x = x)` instead. #' } #' \item{`ppc_error_binned()`}{ #' Intended for use with binomial data. A separate binned error plot (similar @@ -92,7 +94,7 @@ #' ppc_error_scatter_avg(y, yrep) #' #' x <- example_x_data() -#' ppc_error_scatter_avg_vs_x(y, yrep, x) +#' ppc_error_scatter_avg(y, yrep, x) #' #' \dontrun{ #' # binned error plot with binomial model from rstanarm @@ -217,6 +219,7 @@ ppc_error_scatter <- ppc_error_scatter_avg <- function(y, yrep, + x = NULL, ..., stat = "mean", size = 2.5, @@ -225,19 +228,31 @@ ppc_error_scatter_avg <- y <- validate_y(y) yrep <- validate_predictions(yrep, length(y)) + + if (!missing(x)) { + qx <- enquo(x) + x <- validate_x(x, y) + } errors <- compute_errors(y, yrep) stat <- as_tagged_function({{ stat }}) ppc_scatter_avg( - y = y, + y = if (is_null(x)) y else x, yrep = errors, size = size, alpha = alpha, ref_line = FALSE, stat = stat ) + - labs(x = error_avg_label(stat), y = y_label()) + labs( + x = error_avg_label(stat), + y = if (is_null(x)) y_label() else as_label((qx)) + ) + if (is_null(x)) { + NULL + } else { + coord_flip() + } } @@ -286,6 +301,8 @@ ppc_error_scatter_avg_vs_x <- function( ) { check_ignored_arguments(...) + .Deprecated(new = "ppc_error_scatter_avg(y, yrep, x)") + y <- validate_y(y) yrep <- validate_predictions(yrep, length(y)) qx <- enquo(x) diff --git a/man/PPC-errors.Rd b/man/PPC-errors.Rd index a3aec9d8..fafd0212 100644 --- a/man/PPC-errors.Rd +++ b/man/PPC-errors.Rd @@ -37,7 +37,15 @@ ppc_error_hist_grouped( ppc_error_scatter(y, yrep, ..., facet_args = list(), size = 2.5, alpha = 0.8) -ppc_error_scatter_avg(y, yrep, ..., stat = "mean", size = 2.5, alpha = 0.8) +ppc_error_scatter_avg( + y, + yrep, + x = NULL, + ..., + stat = "mean", + size = 2.5, + alpha = 0.8 +) ppc_error_scatter_avg_grouped( y, @@ -116,12 +124,12 @@ to the corresponding observation.} binned error plot, arguments controlling the size of the outline and opacity of the shaded region indicating the 2-SE bounds.} +\item{x}{A numeric vector the same length as \code{y} to use as the x-axis variable.} + \item{stat}{A function or a string naming a function for computing the posterior average. In both cases, the function should take a vector input and return a scalar statistic. The function name is displayed in the axis-label. Defaults to \code{"mean"}.} - -\item{x}{A numeric vector the same length as \code{y} to use as the x-axis variable.} } \value{ A ggplot object that can be further customized using the \strong{ggplot2} package. @@ -165,10 +173,12 @@ A single scatterplot of \code{y} vs. the average of the errors computed from \code{y} and each dataset (row) in \code{yrep}. For each individual data point \code{y[n]} the average error is the average of the errors for \code{y[n]} computed over the the draws from the posterior predictive distribution. + +When the optional \code{x} argument is provided, the average error is plotted +on the y-axis and the predictor variable \code{x} is plotted on the x-axis. } \item{\code{ppc_error_scatter_avg_vs_x()}}{ -Same as \code{ppc_error_scatter_avg()}, except the average is plotted on the -y-axis and a predictor variable \code{x} is plotted on the x-axis. +Deprecated. Use \code{ppc_error_scatter_avg(x = x)} instead. } \item{\code{ppc_error_binned()}}{ Intended for use with binomial data. A separate binned error plot (similar @@ -199,7 +209,7 @@ ppc_error_scatter(y, yrep[10:14, ]) ppc_error_scatter_avg(y, yrep) x <- example_x_data() -ppc_error_scatter_avg_vs_x(y, yrep, x) +ppc_error_scatter_avg(y, yrep, x) \dontrun{ # binned error plot with binomial model from rstanarm diff --git a/tests/testthat/_snaps/ppc-errors/ppc-error-scatter-avg-with-x.svg b/tests/testthat/_snaps/ppc-errors/ppc-error-scatter-avg-with-x.svg new file mode 100644 index 00000000..634b9e4e --- /dev/null +++ b/tests/testthat/_snaps/ppc-errors/ppc-error-scatter-avg-with-x.svg @@ -0,0 +1,166 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +-2 +-1 +0 +1 +2 +3 + + + + + + + + + + + + +0 +25 +50 +75 +100 +seq_along(vdiff_y) +mean +( +y + +y +r +e +p +) +ppc_error_scatter_avg (with x) + + diff --git a/tests/testthat/test-ppc-errors.R b/tests/testthat/test-ppc-errors.R index e7f0ad8f..1792e7b7 100644 --- a/tests/testthat/test-ppc-errors.R +++ b/tests/testthat/test-ppc-errors.R @@ -26,6 +26,10 @@ test_that("ppc_error_scatter_avg returns ggplot2 object", { skip_if_not_installed("rstantools") expect_gg(ppc_error_scatter_avg(y, yrep)) expect_gg(ppc_error_scatter_avg(y, yrep[1:5, ])) + + # when x is provided + expect_gg(ppc_error_scatter_avg(y, yrep, x = rnorm(length(y)))) + expect_gg(ppc_error_scatter_avg(y, yrep[1:5, ], x = rnorm(length(y)))) }) test_that("ppc_error_scatter_avg same as ppc_error_scatter if nrow(yrep) = 1", { @@ -42,8 +46,12 @@ test_that("ppc_error_scatter_avg same as ppc_error_scatter if nrow(yrep) = 1", { test_that("ppc_error_scatter_avg_vs_x returns ggplot2 object", { skip_if_not_installed("rstantools") - expect_gg(ppc_error_scatter_avg_vs_x(y, yrep, x = rnorm(length(y)))) - expect_gg(ppc_error_scatter_avg_vs_x(y, yrep[1:5, ], x = rnorm(length(y)))) + + # expect warning + expect_warning(expect_gg(ppc_error_scatter_avg_vs_x(y, yrep, x = rnorm(length(y)))), + "'ppc_error_scatter_avg_vs_x' is deprecated.") + expect_warning(expect_gg(ppc_error_scatter_avg_vs_x(y, yrep[1:5, ], x = rnorm(length(y)))), + "'ppc_error_scatter_avg_vs_x' is deprecated.") }) test_that("ppc_error_binned returns ggplot object", { @@ -105,6 +113,9 @@ test_that("ppc_error_scatter_avg renders correctly", { p_base <- ppc_error_scatter_avg(vdiff_y, vdiff_yrep) vdiffr::expect_doppelganger("ppc_error_scatter_avg (default)", p_base) + + p_base_x <- ppc_error_scatter_avg(vdiff_y, vdiff_yrep, x = seq_along(vdiff_y)) + vdiffr::expect_doppelganger("ppc_error_scatter_avg (with x)", p_base_x) }) test_that("ppc_error_scatter_avg_grouped renders correctly", { @@ -121,8 +132,13 @@ test_that("ppc_error_scatter_avg_vs_x renders correctly", { testthat::skip_if_not_installed("vdiffr") skip_on_r_oldrel() - p_base <- ppc_error_scatter_avg_vs_x(vdiff_y, vdiff_yrep, x = seq_along(vdiff_y)) + # expect warning + expect_warning( + p_base <- ppc_error_scatter_avg_vs_x(vdiff_y, vdiff_yrep, x = seq_along(vdiff_y)), + "'ppc_error_scatter_avg_vs_x' is deprecated." + ) vdiffr::expect_doppelganger("ppc_error_scatter_avg_vs_x (default)", p_base) + }) test_that("ppc_error_binned renders correctly", {