Skip to content

Commit 4085016

Browse files
ECDF with simultaneous confidence bands for the PIT values in ppc.
1 parent 3a0a61c commit 4085016

File tree

2 files changed

+182
-0
lines changed

2 files changed

+182
-0
lines changed

R/ppc-distributions.R

Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,16 @@
4747
#' quantiles. `y` is overlaid on the plot either as a violin, points, or
4848
#' both, depending on the `y_draw` argument.
4949
#' }
50+
#' \item{`ppc_pit_ecdf()`}{
51+
#' The `100 * prob`% central simultaneous confidence intervals for the ECDF
52+
#' of the empirical PIT values of `y` computed with respect to the
53+
#' corresponding `yrep` values. If 'y' and 'yrep'. Th PIT values can also be
54+
#' provided directly as `pit`.
55+
#' See Säilynoja et al. for more details.}
5056
#' }
5157
#'
5258
#' @template reference-vis-paper
59+
#' @template reference-uniformity-test
5360
#' @templateVar bdaRef (Ch. 6)
5461
#' @template reference-bda
5562
#'
@@ -528,6 +535,146 @@ ppc_violin_grouped <- function(y, yrep, group, ..., probs = c(0.1, 0.5, 0.9),
528535
bayesplot_theme_get()
529536
}
530537

538+
#' @export
539+
#' @rdname PPC-distributions
540+
#'
541+
ppc_pit_ecdf <- function(y,
542+
yrep,
543+
...,
544+
pit = NULL,
545+
K = NULL,
546+
confidence_level = .99,
547+
difference = TRUE,
548+
adj_method = "interpolate") {
549+
check_ignored_arguments(...)
550+
551+
if (is.null(pit)) {
552+
pit <- ppc_data(y, yrep) %>%
553+
group_by(y_id) %>%
554+
dplyr::group_map(~ mean(.x$value[.x$is_y] >= .x$value[!.x$is_y])) %>%
555+
unlist()
556+
if (is.null(K)) {
557+
K <- min(length(unique(ppc_data(y, yrep)$rep_id)) + 1, length(pit))
558+
}
559+
} else {
560+
inform("'pit' specified so ignoring 'y', and 'yrep' if specified.")
561+
pit <- validate_pit(pit)
562+
if (is.null(K)) {
563+
K <- length(pit)
564+
}
565+
}
566+
N <- length(pit)
567+
gamma <- adjust_gamma(N,
568+
K = K,
569+
conf_level = confidence_level,
570+
adj_method = adj_method
571+
)
572+
lims <- ecdf_intervals(N, K = K, gamma = gamma)
573+
ggplot() +
574+
aes_(
575+
x = 0:K / K,
576+
y = ecdf(pit)(0:K / K) - (difference == TRUE) * 0:K / K,
577+
color = "y"
578+
) +
579+
geom_step(show.legend = FALSE) +
580+
geom_step(aes(
581+
y = lims$upper / N - (difference == TRUE) * 0:K / K,
582+
color = "yrep"
583+
), show.legend = FALSE) +
584+
geom_step(aes(
585+
y = lims$lower / N - (difference == TRUE) * 0:K / K,
586+
color = "yrep"
587+
), show.legend = FALSE) +
588+
yaxis_title(FALSE) +
589+
xaxis_title(FALSE) +
590+
yaxis_ticks(FALSE) +
591+
scale_color_ppc_dist() +
592+
bayesplot_theme_get()
593+
}
594+
595+
#' @export
596+
#' @rdname PPC-distributions
597+
#'
598+
ppc_pit_ecdf_grouped <-
599+
function(y,
600+
yrep,
601+
group,
602+
...,
603+
K,
604+
pit,
605+
confidence_level = .99,
606+
difference = TRUE,
607+
adj_method) {
608+
check_ignored_arguments(...)
609+
610+
if (missing(pit)) {
611+
pit <- ppc_data(y, yrep, group) %>%
612+
group_by(y_id) %>%
613+
dplyr::group_map(~ mean(.x$value[.x$is_y] >= .x$value[!.x$is_y])) %>%
614+
unlist()
615+
if (missing(K)) {
616+
K0 <- length(unique(ppc_data(y, yrep)$rep_id))
617+
}
618+
} else {
619+
inform("'pit' specified so ignoring 'y', and 'yrep' if specified.")
620+
pit <- validate_pit(pit)
621+
}
622+
N <- length(pit)
623+
624+
gammas <- lapply(unique(group), function(g) {
625+
N_g <- sum(group == g)
626+
adjust_gamma(
627+
N_g,
628+
K = min(N_g, K0),
629+
conf_level = confidence_level,
630+
adj_method = adj_method
631+
)
632+
})
633+
names(gammas) <- unique(group)
634+
635+
data <- data.frame(pit = pit, group = group) %>%
636+
group_by(group) %>%
637+
dplyr::group_map(~ data.frame(
638+
ecdf_value = ecdf(.x$pit)(
639+
seq(0, 1, length.out = min(nrow(.x) + 1, K0 + 1))),
640+
group = .y[1],
641+
lims_upper = ecdf_intervals(
642+
N = nrow(.x),
643+
K = min(nrow(.x), K0),
644+
gamma = gammas[[unlist(.y[1])]]
645+
)$upper / nrow(.x),
646+
lims_lower = ecdf_intervals(
647+
N = nrow(.x),
648+
K = min(nrow(.x), K0),
649+
gamma = gammas[[unlist(.y[1])]]
650+
)$lower / nrow(.x),
651+
x = seq(0, 1, length.out = min(nrow(.x) + 1, K0 + 1))
652+
)) %>%
653+
dplyr::bind_rows()
654+
ggplot(data) +
655+
aes_(
656+
x = ~x,
657+
y = ~ ecdf_value - (difference == TRUE) * x,
658+
group = ~group,
659+
color = "y"
660+
) +
661+
geom_step(show.legend = FALSE) +
662+
geom_step(aes_(
663+
y = ~ lims_upper - (difference == TRUE) * x,
664+
color = "yrep"
665+
), show.legend = FALSE) +
666+
geom_step(aes_(
667+
y = ~ lims_lower - (difference == TRUE) * x,
668+
color = "yrep"
669+
), show.legend = FALSE) +
670+
xaxis_title(FALSE) +
671+
yaxis_title(FALSE) +
672+
yaxis_ticks(FALSE) +
673+
bayesplot_theme_get() +
674+
facet_wrap("group") +
675+
scale_color_ppc_dist() +
676+
force_axes_in_facets()
677+
}
531678

532679
# internal ----------------------------------------------------------------
533680
scale_color_ppc_dist <- function(name = NULL, values = NULL, labels = NULL) {

man/PPC-distributions.Rd

Lines changed: 35 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)