Skip to content

Commit 14eb2dc

Browse files
Merge branch 'master' of github.com:stan-dev/bayesplot into add_ppc_calibration
2 parents 5efdf47 + 527c48c commit 14eb2dc

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

51 files changed

+8810
-1430
lines changed

.Rbuildignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,4 @@ book/*
1515
docs/*
1616
Rplots.pdf
1717
^\.github$
18+
^release-prep\.R$

.github/workflows/recheck.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
on:
2+
workflow_dispatch:
3+
inputs:
4+
which:
5+
type: choice
6+
description: Which dependents to check
7+
options:
8+
- strong
9+
- most
10+
11+
name: Reverse dependency check
12+
13+
jobs:
14+
revdep_check:
15+
name: Reverse check ${{ inputs.which }} dependents
16+
uses: r-devel/recheck/.github/workflows/recheck.yml@v1
17+
with:
18+
which: ${{ inputs.which }}
19+
subdirectory: '' # set if your R package is in a subdir of the git repo
20+
repository: '' # set to recheck an R package from another git repo
21+
ref: '' # set to recheck a custom tag/branch from another repo

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ cran-comments.md
1212
revdep/*
1313
CRAN-RELEASE
1414
CRAN-SUBMISSION
15+
release-prep.R

DESCRIPTION

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
Package: bayesplot
22
Type: Package
33
Title: Plotting for Bayesian Models
4-
Version: 1.12.0.9000
5-
Date: 2025-04-09
4+
Version: 1.13.0.9000
5+
Date: 2025-06-18
66
Authors@R: c(person("Jonah", "Gabry", role = c("aut", "cre"), email = "[email protected]"),
7-
person("Tristan", "Mahr", role = "aut"),
7+
person("Tristan", "Mahr", role = "aut", comment = c(ORCID = "0000-0002-8890-5116")),
88
person("Paul-Christian", "Bürkner", role = "ctb"),
99
person("Martin", "Modrák", role = "ctb"),
1010
person("Malcolm", "Barrett", role = "ctb"),
@@ -26,7 +26,7 @@ URL: https://mc-stan.org/bayesplot/
2626
BugReports: https://github.com/stan-dev/bayesplot/issues/
2727
SystemRequirements: pandoc (>= 1.12.3), pandoc-citeproc
2828
Depends:
29-
R (>= 3.1.0)
29+
R (>= 4.1.0)
3030
Imports:
3131
dplyr (>= 0.8.0),
3232
ggplot2 (>= 3.4.0),
@@ -41,6 +41,7 @@ Imports:
4141
tidyselect,
4242
utils
4343
Suggests:
44+
ggdist,
4445
ggfortify,
4546
gridExtra (>= 2.2.1),
4647
hexbin,

NAMESPACE

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ export(ppc_data)
127127
export(ppc_dens)
128128
export(ppc_dens_overlay)
129129
export(ppc_dens_overlay_grouped)
130+
export(ppc_dots)
130131
export(ppc_ecdf_overlay)
131132
export(ppc_ecdf_overlay_grouped)
132133
export(ppc_error_binned)
@@ -176,6 +177,7 @@ export(ppd_boxplot)
176177
export(ppd_data)
177178
export(ppd_dens)
178179
export(ppd_dens_overlay)
180+
export(ppd_dots)
179181
export(ppd_ecdf_overlay)
180182
export(ppd_freqpoly)
181183
export(ppd_freqpoly_grouped)

NEWS.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,16 @@
11
# bayesplot (development version)
22

3-
* Add possibility for left-truncation to `ppc_km_overlay()` and `ppc_km_overlay_grouped()` by @Sakuski
4-
* Added `ppc_loo_pit_ecdf()` by @TeemuSailynoja
3+
* PPC "avg" functions (`ppc_scatter_avg()`, `ppc_error_scatter_avg()`, etc.) gain a `stat` argument to set the averaging function. (Suggestion of #348, @kruschke).
4+
* `ppc_error_scatter_avg_vs_x(x = some_expression)` labels the *x* axis with `some_expression`.
5+
6+
# bayesplot 1.13.0
7+
8+
* Add `ppc_loo_pit_ecdf()` by @TeemuSailynoja (#345)
9+
* Add possibility for left-truncation to `ppc_km_overlay()` and `ppc_km_overlay_grouped()` by @Sakuski (#347)
10+
* Give user control over extrapolation in `ppc_km_overlay()` and `ppc_km_overlay_grouped()` by @Sakuski (#353)
11+
* Allow passing `moment_match` via `...` for loo functions by @n-kall (#351)
12+
* Skip some tests when missing Suggests by @MichaelChirico (#344)
13+
* Remove a test that will fail with next ggplot2 release (#356)
514

615
# bayesplot 1.12.0
716

R/bayesplot-helpers.R

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -469,3 +469,53 @@ grid_lines_y <- function(color = "gray50", size = 0.2) {
469469
overlay_function <- function(...) {
470470
stat_function(..., inherit.aes = FALSE)
471471
}
472+
473+
474+
475+
# Resolve a function name and store the expression passed in by the user
476+
#' @noRd
477+
#' @param f a function-like thing: a string naming a function, a function
478+
#' object, an anonymous function object, a formula-based lambda, and `NULL`.
479+
#' @param fallback character string providing a fallback function name
480+
#' @return the function named in `f` with an added `"tagged_expr"` attribute
481+
#' containing the expression to represent the function name and an
482+
#' `"is_anonymous_function"` attribute to flag if the expression is a call to
483+
#' `function()`.
484+
as_tagged_function <- function(f = NULL, fallback = "func") {
485+
qf <- enquo(f)
486+
f <- eval_tidy(qf)
487+
if (!is.null(attr(f, "tagged_expr"))) return(f)
488+
489+
f_expr <- quo_get_expr(qf)
490+
f_fn <- f
491+
492+
if (is_character(f)) { # f = "mean"
493+
# using sym() on the evaluated `f` means that a variable that names a
494+
# function string `x <- "mean"; as_tagged_function(x)` will be lost
495+
# but that seems okay
496+
f_expr <- sym(f)
497+
f_fn <- match.fun(f)
498+
} else if (is_null(f)) { # f = NULL
499+
f_fn <- identity
500+
f_expr <- sym(fallback)
501+
} else if (is_callable(f)) { # f = mean or f = function(x) mean(x)
502+
f_expr <- f_expr # or f = ~mean(.x)
503+
f_fn <- as_function(f)
504+
}
505+
506+
# Setting attributes on primitive functions is deprecated, so wrap them
507+
# and then tag
508+
if (is_primitive(f_fn)) {
509+
f_fn_old <- f_fn
510+
f_factory <- function(f) { function(...) f(...) }
511+
f_fn <- f_factory(f_fn_old)
512+
}
513+
514+
attr(f_fn, "tagged_expr") <- f_expr
515+
attr(f_fn, "is_anonymous_function") <-
516+
is_call(f_expr, name = "function") || is_formula(f_expr)
517+
f_fn
518+
}
519+
520+
521+

R/bayesplot-package.R

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
#' **bayesplot**: Plotting for Bayesian Models
22
#'
3-
#' @docType package
43
#' @name bayesplot-package
54
#' @aliases bayesplot
65
#'
@@ -96,7 +95,7 @@
9695
#' ppd_hist(ypred[1:8, ])
9796
#' }
9897
#'
99-
NULL
98+
"_PACKAGE"
10099

101100

102101
# internal ----------------------------------------------------------------

R/mcmc-distributions.R

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -472,7 +472,7 @@ mcmc_violin <- function(
472472
}
473473
}
474474

475-
geom_args <- list(size = 0.5, na.rm = TRUE, alpha = alpha)
475+
geom_args <- list(linewidth = 0.5, na.rm = TRUE, alpha = alpha)
476476
if (violin) {
477477
geom_args[["draw_quantiles"]] <- probs
478478
} else {

R/ppc-censoring.R

Lines changed: 50 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,11 +24,12 @@
2424
#' @section Plot Descriptions:
2525
#' \describe{
2626
#' \item{`ppc_km_overlay()`}{
27-
#' Empirical CCDF estimates of each dataset (row) in `yrep` are overlaid,
28-
#' with the Kaplan-Meier estimate (Kaplan and Meier, 1958) for `y` itself on
29-
#' top (and in a darker shade). This is a PPC suitable for right-censored
30-
#' `y`. Note that the replicated data from `yrep` is assumed to be
31-
#' uncensored.
27+
#' Empirical CCDF estimates of each dataset (row) in `yrep` are overlaid, with
28+
#' the Kaplan-Meier estimate (Kaplan and Meier, 1958) for `y` itself on top
29+
#' (and in a darker shade). This is a PPC suitable for right-censored `y`.
30+
#' Note that the replicated data from `yrep` is assumed to be uncensored. Left
31+
#' truncation (delayed entry) times for `y` can be specified using
32+
#' `left_truncation_y`.
3233
#' }
3334
#' \item{`ppc_km_overlay_grouped()`}{
3435
#' The same as `ppc_km_overlay()`, but with separate facets by `group`.
@@ -40,24 +41,33 @@
4041
#' @template reference-km
4142
#'
4243
#' @examples
44+
#' \donttest{
4345
#' color_scheme_set("brightblue")
44-
#' y <- example_y_data()
46+
#'
4547
#' # For illustrative purposes, (right-)censor values y > 110:
48+
#' y <- example_y_data()
4649
#' status_y <- as.numeric(y <= 110)
4750
#' y <- pmin(y, 110)
51+
#'
4852
#' # In reality, the replicated data (yrep) would be obtained from a
4953
#' # model which takes the censoring of y properly into account. Here,
5054
#' # for illustrative purposes, we simply use example_yrep_draws():
5155
#' yrep <- example_yrep_draws()
5256
#' dim(yrep)
53-
#' \donttest{
57+
#'
58+
#' # Overlay 25 curves
5459
#' ppc_km_overlay(y, yrep[1:25, ], status_y = status_y)
55-
#' }
60+
#'
61+
#' # With extrapolation_factor = 1 (no extrapolation)
62+
#' ppc_km_overlay(y, yrep[1:25, ], status_y = status_y, extrapolation_factor = 1)
63+
#'
64+
#' # With extrapolation_factor = Inf (show all posterior predictive draws)
65+
#' ppc_km_overlay(y, yrep[1:25, ], status_y = status_y, extrapolation_factor = Inf)
66+
#'
5667
#' # With separate facets by group:
5768
#' group <- example_group_data()
58-
#' \donttest{
5969
#' ppc_km_overlay_grouped(y, yrep[1:25, ], group = group, status_y = status_y)
60-
#' }
70+
#'
6171
#' # With left-truncation (delayed entry) times:
6272
#' min_vals <- pmin(y, apply(yrep, 2, min))
6373
#' left_truncation_y <- rep(0, length(y))
@@ -66,7 +76,6 @@
6676
#' runif(sum(condition), min = 0.6, max = 0.99) * y[condition],
6777
#' min_vals[condition] - 0.001
6878
#' )
69-
#' \donttest{
7079
#' ppc_km_overlay(y, yrep[1:25, ], status_y = status_y,
7180
#' left_truncation_y = left_truncation_y)
7281
#' }
@@ -78,15 +87,23 @@ NULL
7887
#' be a numeric vector of the same length as `y` with values in \{0, 1\} (0 =
7988
#' right censored, 1 = event).
8089
#' @param left_truncation_y Optional parameter that specifies left-truncation
81-
#' (delayed entry) times for the observations from `y`. This must
82-
#' be a numeric vector of the same length as `y`. If `NULL` (default),
83-
#' no left-truncation is assumed.
90+
#' (delayed entry) times for the observations from `y`. This must be a numeric
91+
#' vector of the same length as `y`. If `NULL` (default), no left-truncation
92+
#' is assumed.
93+
#' @param extrapolation_factor A numeric value (>=1) that controls how far the
94+
#' plot is extended beyond the largest observed value in `y`. The default
95+
#' value is 1.2, which corresponds to 20 % extrapolation. Note that all
96+
#' posterior predictive draws may not be shown by default because of the
97+
#' controlled extrapolation. To display all posterior predictive draws, set
98+
#' `extrapolation_factor = Inf`.
99+
#'
84100
ppc_km_overlay <- function(
85101
y,
86102
yrep,
87103
...,
88104
status_y,
89105
left_truncation_y = NULL,
106+
extrapolation_factor = 1.2,
90107
size = 0.25,
91108
alpha = 0.7
92109
) {
@@ -97,15 +114,25 @@ ppc_km_overlay <- function(
97114
suggested_package("ggfortify")
98115

99116
if (!is.numeric(status_y) || length(status_y) != length(y) || !all(status_y %in% c(0, 1))) {
100-
stop("`status_y` must be a numeric vector of 0s and 1s the same length as `y`.")
117+
stop("`status_y` must be a numeric vector of 0s and 1s the same length as `y`.", call. = FALSE)
101118
}
102119

103120
if (!is.null(left_truncation_y)) {
104121
if (!is.numeric(left_truncation_y) || length(left_truncation_y) != length(y)) {
105-
stop("`left_truncation_y` must be a numeric vector of the same length as `y`.")
122+
stop("`left_truncation_y` must be a numeric vector of the same length as `y`.", call. = FALSE)
106123
}
107124
}
108125

126+
if (extrapolation_factor < 1) {
127+
stop("`extrapolation_factor` must be greater than or equal to 1.", call. = FALSE)
128+
}
129+
if (extrapolation_factor == 1.2) {
130+
message(
131+
"Note: `extrapolation_factor` now defaults to 1.2 (20%).\n",
132+
"To display all posterior predictive draws, set `extrapolation_factor = Inf`."
133+
)
134+
}
135+
109136
data <- ppc_data(y, yrep, group = status_y)
110137

111138
# Modify the status indicator:
@@ -149,6 +176,10 @@ ppc_km_overlay <- function(
149176
fsf$is_y_size <- ifelse(fsf$is_y_color == "yrep", size, 1)
150177
fsf$is_y_alpha <- ifelse(fsf$is_y_color == "yrep", alpha, 1)
151178

179+
max_time_y <- max(y, na.rm = TRUE)
180+
fsf <- fsf %>%
181+
dplyr::filter(.data$is_y_color != "yrep" | .data$time <= max_time_y * extrapolation_factor)
182+
152183
# Ensure that the observed data gets plotted last by reordering the
153184
# levels of the factor "strata"
154185
fsf$strata <- factor(fsf$strata, levels = rev(levels(fsf$strata)))
@@ -194,6 +225,7 @@ ppc_km_overlay_grouped <- function(
194225
...,
195226
status_y,
196227
left_truncation_y = NULL,
228+
extrapolation_factor = 1.2,
197229
size = 0.25,
198230
alpha = 0.7
199231
) {
@@ -207,7 +239,8 @@ ppc_km_overlay_grouped <- function(
207239
status_y = status_y,
208240
left_truncation_y = left_truncation_y,
209241
size = size,
210-
alpha = alpha
242+
alpha = alpha,
243+
extrapolation_factor = extrapolation_factor
211244
)
212245

213246
p_overlay +

0 commit comments

Comments
 (0)