diff --git a/DESCRIPTION b/DESCRIPTION index 1b7edaf8..8241c261 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -7,7 +7,8 @@ Authors@R: c(person("Jonah", "Gabry", role = c("aut", "cre"), email = "jsg2201@c person("Tristan", "Mahr", role = "aut"), person("Paul-Christian", "Bürkner", role = "ctb"), person("Martin", "Modrák", role = "ctb"), - person("Malcolm", "Barrett", role = "ctb")) + person("Malcolm", "Barrett", role = "ctb"), + person("Frank", "Weber", role = "ctb")) Maintainer: Jonah Gabry Description: Plotting functions for posterior analysis, MCMC diagnostics, prior and posterior predictive checks, and other visualizations @@ -36,6 +37,7 @@ Imports: tidyselect, utils Suggests: + ggfortify, gridExtra (>= 2.2.1), hexbin, knitr (>= 1.16), @@ -47,6 +49,7 @@ Suggests: rstantools (>= 1.5.0), scales, shinystan (>= 2.3.0), + survival, testthat (>= 2.0.0), vdiffr RoxygenNote: 7.1.1 diff --git a/NAMESPACE b/NAMESPACE index 5bf2b8bd..3c3eae7d 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -117,6 +117,7 @@ export(ppc_hist) export(ppc_intervals) export(ppc_intervals_data) export(ppc_intervals_grouped) +export(ppc_km_overlay) export(ppc_loo_intervals) export(ppc_loo_pit) export(ppc_loo_pit_overlay) diff --git a/NEWS.md b/NEWS.md index 46c528e1..720d1d33 100644 --- a/NEWS.md +++ b/NEWS.md @@ -8,13 +8,19 @@ * Items for next release go here --> +* New plotting function `ppc_km_overlay()` for outcome variables that are + right-censored. Empirical CCDF estimates of `yrep` are compared with the + Kaplan-Meier estimate of `y`. (#233, #234, @fweber144) + * CmdStanMCMC objects (from CmdStanR) can now be used with extractor functions `nuts_params()`, `log_posterior()`, `rhat()`, and `neff_ratio()`. (#227) * Added missing `facet_args` argument to `mcmc_rank_overlay()`. (#221, @hhau) + * Size of points and interval lines can set in `mcmc_intervals(..., outer_size, inner_size, point_size)`. (#215, #228, #229) + * `mcmc_areas()` tries to use less blank vertical blank space. (#218, #230) diff --git a/R/bayesplot-package.R b/R/bayesplot-package.R index a0697fbd..a886f7c0 100644 --- a/R/bayesplot-package.R +++ b/R/bayesplot-package.R @@ -98,6 +98,6 @@ NULL # release reminders (for devtools) release_questions <- function() { # nocov start c( - "Have you reduced the size of the vignettes for CRAN?", + "Have you reduced the size of the vignettes for CRAN?" ) } # nocov end diff --git a/R/helpers-ppc.R b/R/helpers-ppc.R index 5abebbc6..1f8ee245 100644 --- a/R/helpers-ppc.R +++ b/R/helpers-ppc.R @@ -70,7 +70,8 @@ validate_yrep <- function(yrep, y) { #' Checks that grouping variable has same length as `y` and is either a vector or #' factor variable. #' -#' @param group,y The user's `group` object and the `y` object returned by `validate_y()`. +#' @param group,y The user's `group` object and the `y` object returned by +#' `validate_y()`. #' @return Either throws an error or returns `group` (coerced to a factor). #' @noRd validate_group <- function(group, y) { @@ -88,10 +89,6 @@ validate_group <- function(group, y) { abort("length(group) must be equal to length(y).") } - if (length(unique(group)) == 1) { - abort("'group' must have more than one unique value.") - } - unname(group) } diff --git a/R/ppc-censoring.R b/R/ppc-censoring.R new file mode 100644 index 00000000..d7c3ecae --- /dev/null +++ b/R/ppc-censoring.R @@ -0,0 +1,136 @@ +#' PPC censoring +#' +#' @description Compare the empirical distribution of censored data `y` to the +#' distributions of simulated/replicated data `yrep` from the posterior +#' predictive distribution. See the **Plot Descriptions** section, below, for +#' details. +#' +#' Although some of the other plots can be used with censored data, +#' `ppc_km_overlay()` is currently the only plotting function designed +#' *specifically* for censored data. We encourage you to suggest or contribute +#' additional plots at [https://github.com/stan-dev/bayesplot](github.com/stan-dev/bayesplot). +#' +#' +#' +#' @name PPC-censoring +#' @family PPCs +#' +#' @template args-y-yrep +#' @param size,alpha Passed to the appropriate geom to control the appearance of +#' the `yrep` distributions. +#' @param ... Currently unused. +#' +#' @template return-ggplot +#' +#' @section Plot Descriptions: +#' \describe{ +#' \item{`ppc_km_overlay()`}{ +#' Empirical CCDF estimates of each dataset (row) in `yrep` are overlaid, +#' with the Kaplan-Meier estimate (Kaplan and Meier, 1958) for `y` itself +#' on top (and in a darker shade). This is a PPC suitable for +#' right-censored `y`. Note that the replicated data from `yrep` is assumed +#' to be uncensored. +#' } +#' } +#' +#' @templateVar bdaRef (Ch. 6) +#' @template reference-bda +#' @template reference-km +#' +#' @examples +#' color_scheme_set("brightblue") +#' y <- example_y_data() +#' # For illustrative purposes, (right-)censor values y > 110: +#' status_y <- as.numeric(y <= 110) +#' y <- pmin(y, 110) +#' # In reality, the replicated data (yrep) would be obtained from a +#' # model which takes the censoring of y properly into account. Here, +#' # for illustrative purposes, we simply use example_yrep_draws(): +#' yrep <- example_yrep_draws() +#' dim(yrep) +#' \donttest{ +#' ppc_km_overlay(y, yrep[1:25, ], status_y = status_y) +#' } +NULL + +#' @export +#' @rdname PPC-censoring +#' @param status_y The status indicator for the observations from `y`. This must +#' be a numeric vector of the same length as `y` with values in \{0, 1\} (0 = +#' right censored, 1 = event). +ppc_km_overlay <- + function(y, + yrep, + ..., + status_y, + size = 0.25, + alpha = 0.7) { + check_ignored_arguments(...) + + if(!requireNamespace("survival", quietly = TRUE)){ + abort("Package 'survival' required.") + } + if(!requireNamespace("ggfortify", quietly = TRUE)){ + abort("Package 'ggfortify' required.") + } + + # Checks for 'status_y': + stopifnot(is.numeric(status_y)) + stopifnot(all(status_y %in% c(0, 1))) + + # Create basic PPC dataset: + data <- ppc_data(y, yrep, group = status_y) + + # Modify the status indicator: + # * For the observed data ("y"), convert the status indicator back to + # a numeric. + # * For the replicated data ("yrep"), set the status indicator + # to 1 ("event"). This way, the Kaplan-Meier estimator reduces + # to "1 - ECDF" with ECDF denoting the ordinary empirical cumulative + # distribution function. + data <- data %>% + dplyr::mutate(group = ifelse(.data$is_y, + as.numeric(as.character(.data$group)), + 1)) + + # Create 'survfit' object and 'fortify' it + sf <- survival::survfit( + survival::Surv(value, group) ~ rep_label, + data = data + ) + fsf <- fortify(sf) + + # Add variables specifying color, size, and alpha: + fsf$is_y_color <- as.factor(sub("\\[rep\\] \\(.*$", "rep", sub("^italic\\(y\\)", "y", fsf$strata))) + fsf$is_y_size <- ifelse(fsf$is_y_color == "yrep", size, 1) + fsf$is_y_alpha <- ifelse(fsf$is_y_color == "yrep", alpha, 1) + + # Ensure that the observed data gets plotted last by reordering the + # levels of the factor "strata": + fsf$strata <- factor(fsf$strata, levels = rev(levels(fsf$strata))) + + # Plot: + ggplot(data = fsf, + mapping = aes_(x = ~ time, + y = ~ surv, + color = ~ is_y_color, + group = ~ strata, + size = ~ is_y_size, + alpha = ~ is_y_alpha)) + + geom_step() + + hline_at( + c(0, 0.5, 1), + size = c(0.2, 0.1, 0.2), + linetype = 2, + color = get_color("dh") + ) + + scale_size_identity() + + scale_alpha_identity() + + scale_color_ppc_dist() + + scale_y_continuous(breaks = c(0, 0.5, 1)) + + xlab(y_label()) + + yaxis_title(FALSE) + + xaxis_title(FALSE) + + yaxis_ticks(FALSE) + + bayesplot_theme_get() + } diff --git a/R/ppc-overview.R b/R/ppc-overview.R index e2c61b37..051ee691 100644 --- a/R/ppc-overview.R +++ b/R/ppc-overview.R @@ -87,6 +87,9 @@ #' multinomial outcomes. #' * [LOO predictive checks][PPC-loo]: PPC functions for predictive checks #' based on (approximate) leave-one-out (LOO) cross-validation. +#' * [Censored data][PPC-censoring]: PPC functions comparing the empirical +#' distribution of censored data `y` to the distributions of individual +#' simulated datasets (rows) in `yrep`. #' #' @section Providing an interface for predictive checking from another package: #' diff --git a/man-roxygen/reference-km.R b/man-roxygen/reference-km.R new file mode 100644 index 00000000..48f72212 --- /dev/null +++ b/man-roxygen/reference-km.R @@ -0,0 +1,4 @@ +#' @references Kaplan, E. L. and Meier, P. (1958). Nonparametric estimation +#' from incomplete observations. +#' *Journal of the American Statistical Association*. 53(282), 457--481. +#' doi:10.1080/01621459.1958.10501452. diff --git a/man/PPC-censoring.Rd b/man/PPC-censoring.Rd new file mode 100644 index 00000000..fdec5202 --- /dev/null +++ b/man/PPC-censoring.Rd @@ -0,0 +1,92 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/ppc-censoring.R +\name{PPC-censoring} +\alias{PPC-censoring} +\alias{ppc_km_overlay} +\title{PPC censoring} +\usage{ +ppc_km_overlay(y, yrep, ..., status_y, size = 0.25, alpha = 0.7) +} +\arguments{ +\item{y}{A vector of observations. See \strong{Details}.} + +\item{yrep}{An \eqn{S} by \eqn{N} matrix of draws from the posterior +predictive distribution, where \eqn{S} is the size of the posterior sample +(or subset of the posterior sample used to generate \code{yrep}) and \eqn{N} is +the number of observations (the length of \code{y}). The columns of \code{yrep} +should be in the same order as the data points in \code{y} for the plots to make +sense. See \strong{Details} for additional instructions.} + +\item{...}{Currently unused.} + +\item{status_y}{The status indicator for the observations from \code{y}. This must +be a numeric vector of the same length as \code{y} with values in \{0, 1\} (0 = +right censored, 1 = event).} + +\item{size, alpha}{Passed to the appropriate geom to control the appearance of +the \code{yrep} distributions.} +} +\value{ +A ggplot object that can be further customized using the \strong{ggplot2} package. +} +\description{ +Compare the empirical distribution of censored data \code{y} to the +distributions of simulated/replicated data \code{yrep} from the posterior +predictive distribution. See the \strong{Plot Descriptions} section, below, for +details. + +Although some of the other plots can be used with censored data, +\code{ppc_km_overlay()} is currently the only plotting function designed +\emph{specifically} for censored data. We encourage you to suggest or contribute +additional plots at \href{github.com/stan-dev/bayesplot}{https://github.com/stan-dev/bayesplot}. +} +\section{Plot Descriptions}{ + +\describe{ +\item{\code{ppc_km_overlay()}}{ +Empirical CCDF estimates of each dataset (row) in \code{yrep} are overlaid, +with the Kaplan-Meier estimate (Kaplan and Meier, 1958) for \code{y} itself +on top (and in a darker shade). This is a PPC suitable for +right-censored \code{y}. Note that the replicated data from \code{yrep} is assumed +to be uncensored. +} +} +} + +\examples{ +color_scheme_set("brightblue") +y <- example_y_data() +# For illustrative purposes, (right-)censor values y > 110: +status_y <- as.numeric(y <= 110) +y <- pmin(y, 110) +# In reality, the replicated data (yrep) would be obtained from a +# model which takes the censoring of y properly into account. Here, +# for illustrative purposes, we simply use example_yrep_draws(): +yrep <- example_yrep_draws() +dim(yrep) +\donttest{ +ppc_km_overlay(y, yrep[1:25, ], status_y = status_y) +} +} +\references{ +Gelman, A., Carlin, J. B., Stern, H. S., Dunson, D. B., Vehtari, +A., and Rubin, D. B. (2013). \emph{Bayesian Data Analysis.} Chapman & Hall/CRC +Press, London, third edition. (Ch. 6) + +Kaplan, E. L. and Meier, P. (1958). Nonparametric estimation +from incomplete observations. +\emph{Journal of the American Statistical Association}. 53(282), 457--481. +doi:10.1080/01621459.1958.10501452. +} +\seealso{ +Other PPCs: +\code{\link{PPC-discrete}}, +\code{\link{PPC-distributions}}, +\code{\link{PPC-errors}}, +\code{\link{PPC-intervals}}, +\code{\link{PPC-loo}}, +\code{\link{PPC-overview}}, +\code{\link{PPC-scatterplots}}, +\code{\link{PPC-test-statistics}} +} +\concept{PPCs} diff --git a/man/PPC-discrete.Rd b/man/PPC-discrete.Rd index d3df4b62..e8e8d753 100644 --- a/man/PPC-discrete.Rd +++ b/man/PPC-discrete.Rd @@ -173,6 +173,7 @@ Visualizing count data regressions using rootograms. } \seealso{ Other PPCs: +\code{\link{PPC-censoring}}, \code{\link{PPC-distributions}}, \code{\link{PPC-errors}}, \code{\link{PPC-intervals}}, diff --git a/man/PPC-distributions.Rd b/man/PPC-distributions.Rd index 525999c6..ab203a13 100644 --- a/man/PPC-distributions.Rd +++ b/man/PPC-distributions.Rd @@ -247,6 +247,7 @@ Press, London, third edition. (Ch. 6) } \seealso{ Other PPCs: +\code{\link{PPC-censoring}}, \code{\link{PPC-discrete}}, \code{\link{PPC-errors}}, \code{\link{PPC-intervals}}, diff --git a/man/PPC-errors.Rd b/man/PPC-errors.Rd index 61aeabda..079d2fd1 100644 --- a/man/PPC-errors.Rd +++ b/man/PPC-errors.Rd @@ -174,6 +174,7 @@ Press, London, third edition. (Ch. 6) } \seealso{ Other PPCs: +\code{\link{PPC-censoring}}, \code{\link{PPC-discrete}}, \code{\link{PPC-distributions}}, \code{\link{PPC-intervals}}, diff --git a/man/PPC-intervals.Rd b/man/PPC-intervals.Rd index 9e8b6cd9..552ae7be 100644 --- a/man/PPC-intervals.Rd +++ b/man/PPC-intervals.Rd @@ -211,6 +211,7 @@ Press, London, third edition. (Ch. 6) } \seealso{ Other PPCs: +\code{\link{PPC-censoring}}, \code{\link{PPC-discrete}}, \code{\link{PPC-distributions}}, \code{\link{PPC-errors}}, diff --git a/man/PPC-loo.Rd b/man/PPC-loo.Rd index a59f9cab..75f2f131 100644 --- a/man/PPC-loo.Rd +++ b/man/PPC-loo.Rd @@ -256,6 +256,7 @@ doi:10.1007/s11222-016-9696-4. arXiv preprint: } \seealso{ Other PPCs: +\code{\link{PPC-censoring}}, \code{\link{PPC-discrete}}, \code{\link{PPC-distributions}}, \code{\link{PPC-errors}}, diff --git a/man/PPC-overview.Rd b/man/PPC-overview.Rd index ce184709..b982f127 100644 --- a/man/PPC-overview.Rd +++ b/man/PPC-overview.Rd @@ -89,6 +89,9 @@ count outcomes and bar plots for ordinal, categorical, and multinomial outcomes. \item \link[=PPC-loo]{LOO predictive checks}: PPC functions for predictive checks based on (approximate) leave-one-out (LOO) cross-validation. +\item \link[=PPC-censoring]{Censored data}: PPC functions comparing the empirical +distribution of censored data \code{y} to the distributions of individual +simulated datasets (rows) in \code{yrep}. } } @@ -117,6 +120,7 @@ Press, London, third edition. (Ch. 6) } \seealso{ Other PPCs: +\code{\link{PPC-censoring}}, \code{\link{PPC-discrete}}, \code{\link{PPC-distributions}}, \code{\link{PPC-errors}}, diff --git a/man/PPC-scatterplots.Rd b/man/PPC-scatterplots.Rd index b591e8e6..a21e6da7 100644 --- a/man/PPC-scatterplots.Rd +++ b/man/PPC-scatterplots.Rd @@ -89,6 +89,7 @@ Press, London, third edition. (Ch. 6) } \seealso{ Other PPCs: +\code{\link{PPC-censoring}}, \code{\link{PPC-discrete}}, \code{\link{PPC-distributions}}, \code{\link{PPC-errors}}, diff --git a/man/PPC-test-statistics.Rd b/man/PPC-test-statistics.Rd index ab11a0bf..0f8968de 100644 --- a/man/PPC-test-statistics.Rd +++ b/man/PPC-test-statistics.Rd @@ -163,6 +163,7 @@ Press, London, third edition. (Ch. 6) } \seealso{ Other PPCs: +\code{\link{PPC-censoring}}, \code{\link{PPC-discrete}}, \code{\link{PPC-distributions}}, \code{\link{PPC-errors}}, diff --git a/tests/figs/ppc-distributions/ppc-km-overlay-default.svg b/tests/figs/ppc-distributions/ppc-km-overlay-default.svg new file mode 100644 index 00000000..c9a18e10 --- /dev/null +++ b/tests/figs/ppc-distributions/ppc-km-overlay-default.svg @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +0.0 +0.5 +1.0 + + + + + + + + + + +0 +1 +2 +3 +4 +5 + + +y +y +r +e +p +ppc_km_overlay (default) + diff --git a/tests/figs/ppc-distributions/ppc-km-overlay-size-alpha.svg b/tests/figs/ppc-distributions/ppc-km-overlay-size-alpha.svg new file mode 100644 index 00000000..0284d7e1 --- /dev/null +++ b/tests/figs/ppc-distributions/ppc-km-overlay-size-alpha.svg @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +0.0 +0.5 +1.0 + + + + + + + + + + +0 +1 +2 +3 +4 +5 + + +y +y +r +e +p +ppc_km_overlay (size, alpha) + diff --git a/tests/testthat/data-for-ppc-tests.R b/tests/testthat/data-for-ppc-tests.R index 57a9991d..752b10f8 100644 --- a/tests/testthat/data-for-ppc-tests.R +++ b/tests/testthat/data-for-ppc-tests.R @@ -2,10 +2,12 @@ set.seed(8420) y <- rnorm(100) yrep <- matrix(rnorm(2500), ncol = 100) group <- gl(4, 25, labels = LETTERS[1:4]) +status_y <- rep_len(0:1, length.out = length(y)) y2 <- rpois(30, 1) yrep2 <- matrix(rpois(30, 1), ncol = 30) group2 <- rep(1, 30) +status_y2 <- rep_len(0:1, length.out = length(y2)) # for vdiffr visual tests @@ -13,8 +15,10 @@ set.seed(11172017) vdiff_y <- rnorm(100) vdiff_yrep <- matrix(rnorm(2500), ncol = 100) vdiff_group <- gl(4, 25, labels = LETTERS[1:4]) +vdiff_status_y <- rep_len(0:1, length.out = length(vdiff_y)) vdiff_y2 <- rpois(30, 1) vdiff_yrep2 <- matrix(rpois(30 * 10, 1), ncol = 30, nrow = 10) vdiff_group2 <- rep_len(c(1,2), length.out = 30) +vdiff_status_y2 <- rep_len(0:1, length.out = length(vdiff_y2)) set.seed(seed = NULL) diff --git a/tests/testthat/test-ppc-distributions.R b/tests/testthat/test-ppc-distributions.R index b5504bc0..469fb603 100644 --- a/tests/testthat/test-ppc-distributions.R +++ b/tests/testthat/test-ppc-distributions.R @@ -13,6 +13,11 @@ test_that("ppc_ecdf_overlay returns a ggplot object", { expect_gg(ppc_ecdf_overlay(y2, yrep2)) }) +test_that("ppc_km_overlay returns a ggplot object", { + expect_gg(ppc_km_overlay(y, yrep, status_y = status_y, size = 0.5, alpha = 0.2)) + expect_gg(ppc_km_overlay(y2, yrep2, status_y = status_y2)) +}) + test_that("ppc_dens,pp_hist,ppc_freqpoly,ppc_boxplot return ggplot objects", { expect_gg(ppc_hist(y, yrep[1,, drop = FALSE])) expect_gg(ppc_hist(y, yrep[1:8, ])) @@ -39,9 +44,6 @@ test_that("ppc_freqpoly_grouped returns a ggplot object", { expect_gg(ppc_freqpoly_grouped(y, yrep[1:4, ], group)) expect_gg(ppc_freqpoly_grouped(y, yrep[1:4, ], group, freq = TRUE, alpha = 0.5)) - - expect_error(ppc_freqpoly_grouped(y2, yrep2, group2), - "'group' must have more than one unique value") }) test_that("ppc_violin_grouped returns a ggplot object", { @@ -49,9 +51,6 @@ test_that("ppc_violin_grouped returns a ggplot object", { expect_gg(ppc_violin_grouped(y, yrep, as.numeric(group))) expect_gg(ppc_violin_grouped(y, yrep, as.integer(group))) expect_gg(ppc_violin_grouped(y, yrep, group, y_draw = "both", y_jitter = 0.3)) - - expect_error(ppc_violin_grouped(y2, yrep2, group2), - "'group' must have more than one unique value") }) @@ -127,6 +126,22 @@ test_that("ppc_ecdf_overlay renders correctly", { vdiffr::expect_doppelganger("ppc_ecdf_overlay (discrete, size, alpha)", p_custom) }) +test_that("ppc_km_overlay renders correctly", { + testthat::skip_on_cran() + testthat::skip_if_not_installed("vdiffr") + + p_base <- ppc_km_overlay(vdiff_y2, vdiff_yrep2, status_y = vdiff_status_y2) + vdiffr::expect_doppelganger("ppc_km_overlay (default)", p_base) + + p_custom <- ppc_km_overlay( + vdiff_y2, + vdiff_yrep2, + status_y = vdiff_status_y2, + size = 2, + alpha = .2) + vdiffr::expect_doppelganger("ppc_km_overlay (size, alpha)", p_custom) +}) + test_that("ppc_dens renders correctly", { testthat::skip_on_cran() testthat::skip_if_not_installed("vdiffr") diff --git a/tests/testthat/test-ppc-errors.R b/tests/testthat/test-ppc-errors.R index 253c9709..008569d4 100644 --- a/tests/testthat/test-ppc-errors.R +++ b/tests/testthat/test-ppc-errors.R @@ -18,8 +18,6 @@ test_that("ppc_error_hist_grouped returns ggplot object", { expect_gg(ppc_error_hist_grouped(y, yrep[1:5, ], group)) expect_gg(ppc_error_hist_grouped(y, yrep[1,, drop = FALSE], group, freq = FALSE, binwidth = 1)) - expect_error(ppc_error_hist_grouped(y2, yrep2, group2), - "'group' must have more than one unique value") }) test_that("ppc_error_scatter_avg returns ggplot2 object", { diff --git a/tests/testthat/test-ppc-input-validation.R b/tests/testthat/test-ppc-input-validation.R index 6d4246cf..93bbbd77 100644 --- a/tests/testthat/test-ppc-input-validation.R +++ b/tests/testthat/test-ppc-input-validation.R @@ -46,8 +46,6 @@ test_that("validate_group throws errors", { expect_error(validate_group(array(1:3), y = 1:3), "vector") expect_error(validate_group(c(1,2,NA), y = 1:3), "NAs not allowed") expect_error(validate_group(1:4, y = 1:3), "must be equal to") - expect_error(validate_group(rep(1,3), y = 1:3), - "must have more than one unique value") }) diff --git a/tests/testthat/test-ppc-scatterplots.R b/tests/testthat/test-ppc-scatterplots.R index d4b7b7c3..7669d1c5 100644 --- a/tests/testthat/test-ppc-scatterplots.R +++ b/tests/testthat/test-ppc-scatterplots.R @@ -25,9 +25,6 @@ test_that("ppc_scatter_avg_grouped returns a ggplot object", { expect_gg(ppc_scatter_avg_grouped(y, yrep, group)) expect_gg(ppc_scatter_avg_grouped(y, yrep, as.numeric(group))) expect_gg(ppc_scatter_avg_grouped(y, yrep, as.integer(group))) - - expect_error(ppc_scatter_avg_grouped(y2, yrep2, group2), - "'group' must have more than one unique value") }) diff --git a/tests/testthat/test-ppc-test-statistics.R b/tests/testthat/test-ppc-test-statistics.R index d2756c87..6da5c6c2 100644 --- a/tests/testthat/test-ppc-test-statistics.R +++ b/tests/testthat/test-ppc-test-statistics.R @@ -48,9 +48,6 @@ test_that("ppc_stat_grouped returns ggplot object", { expect_gg(ppc_stat_grouped(y, yrep, group)) expect_gg(ppc_stat_grouped(y, yrep, as.numeric(group), stat = function(z) var(z))) expect_gg(ppc_stat_grouped(y, yrep, as.integer(group), stat = "sd")) - - expect_error(ppc_stat_grouped(y2, yrep2, group2), - "'group' must have more than one unique value") }) test_that("ppc_stat_freqpoly_grouped returns ggplot object", { expect_gg(ppc_stat_freqpoly_grouped(y, yrep, group, stat = "sd", freq = FALSE))