Skip to content

Commit 16f1338

Browse files
committed
adding ppc_rootogram_grouped
1 parent d831b30 commit 16f1338

7 files changed

Lines changed: 572 additions & 16 deletions

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ export(ppc_ribbon)
155155
export(ppc_ribbon_data)
156156
export(ppc_ribbon_grouped)
157157
export(ppc_rootogram)
158+
export(ppc_rootogram_grouped)
158159
export(ppc_scatter)
159160
export(ppc_scatter_avg)
160161
export(ppc_scatter_avg_data)

R/ppc-discrete.R

Lines changed: 94 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
#' [ggplot2::geom_line()] and [ggplot2::geom_pointrange()].
2525
#' @param freq For bar plots only, if `TRUE` (the default) the y-axis will
2626
#' display counts. Setting `freq=FALSE` will put proportions on the y-axis.
27-
#' @param bound_distinct For `ppc_rootogram(style = "discrete)`,
27+
#' @param bound_distinct For `ppc_rootogram(style = "discrete)` and `ppc_rootogram_grouped(style = "discrete)`,
2828
#' if `TRUE` then the observed counts will be plotted with different shapes
2929
#' depending on whether they are within the bounds of the `y` quantiles.
3030
#'
@@ -75,6 +75,10 @@
7575
#' and Zeileis (2016) for advice on interpreting rootograms and selecting
7676
#' among the different styles.
7777
#' }
78+
#' \item{`ppc_rootogram_grouped()`}{
79+
#' Same as `ppc_rootogram()` but a separate plot (facet) is generated for each
80+
#' level of a grouping variable.
81+
#' }
7882
#' }
7983
#'
8084
#' @section Related functions:
@@ -147,6 +151,24 @@
147151
#' )
148152
#' }
149153
#'
154+
#' # rootograms for counts
155+
#' y <- rpois(100, 20)
156+
#' yrep <- matrix(rpois(10000, 20), ncol = 100)
157+
#'
158+
#' color_scheme_set("brightblue")
159+
#' ppc_rootogram(y, yrep)
160+
#' ppc_rootogram(y, yrep, prob = 0)
161+
#'
162+
#' ppc_rootogram(y, yrep, style = "hanging", prob = 0.8)
163+
#' ppc_rootogram(y, yrep, style = "suspended")
164+
#' ppc_rootogram(y, yrep, style = "discrete")
165+
#'
166+
#' # rootograms for counts with groups
167+
#' group <- gl(2, 50, length = 100, labels = c("GroupA", "GroupB"))
168+
#' ppc_rootogram_grouped(y, yrep, group)
169+
#' ppc_rootogram_grouped(y, yrep, group, style = "hanging", facet_args = list(nrow = 2))
170+
#' ppc_rootogram_grouped(y, yrep, group, style = "discrete", prob = 0.5)
171+
#'
150172
NULL
151173

152174
#' @rdname PPC-discrete
@@ -253,32 +275,26 @@ ppc_bars_grouped <-
253275
#' *The American Statistician*. 70(3): 296--303.
254276
#' <https://arxiv.org/abs/1605.01311>.
255277
#'
256-
#' @examples
257-
#' # rootograms for counts
258-
#' y <- rpois(100, 20)
259-
#' yrep <- matrix(rpois(10000, 20), ncol = 100)
260-
#'
261-
#' color_scheme_set("brightblue")
262-
#' ppc_rootogram(y, yrep)
263-
#' ppc_rootogram(y, yrep, prob = 0)
264-
#'
265-
#' ppc_rootogram(y, yrep, style = "hanging", prob = 0.8)
266-
#' ppc_rootogram(y, yrep, style = "suspended")
267-
#' ppc_rootogram(y, yrep, style = "discrete")
268-
#'
269278
ppc_rootogram <- function(y,
270279
yrep,
271280
style = c("standing", "hanging", "suspended", "discrete"),
272281
...,
273282
prob = 0.9,
274283
size = 1,
275284
bound_distinct = TRUE) {
276-
check_ignored_arguments(...)
285+
286+
dots <- list(...)
287+
if (!from_grouped(dots)) {
288+
check_ignored_arguments(...)
289+
dots$group <- NULL
290+
}
291+
277292
style <- match.arg(style)
278293

279294
data <- .ppc_rootogram_data(
280295
y = y,
281296
yrep = yrep,
297+
group = dots$group,
282298
style = style,
283299
prob = prob,
284300
bound_distinct = bound_distinct
@@ -367,6 +383,33 @@ ppc_rootogram <- function(y,
367383
}
368384

369385

386+
#' @rdname PPC-discrete
387+
#' @export
388+
ppc_rootogram_grouped <-
389+
function(y,
390+
yrep,
391+
group,
392+
style = c("standing", "hanging", "suspended", "discrete"),
393+
...,
394+
facet_args = list(),
395+
prob = 0.9,
396+
size = 1,
397+
bound_distinct = TRUE) {
398+
check_ignored_arguments(...)
399+
style <- match.arg(style)
400+
call <- match.call(expand.dots = FALSE)
401+
g <- eval(ungroup_call("ppc_rootogram", call), parent.frame())
402+
403+
# In style = discrete, scale_y_sqrt() can't handle -Inf values in axis segments
404+
# so force_axes_in_facets() results in errors
405+
if (style != "discrete") {
406+
g <- g + force_axes_in_facets()
407+
}
408+
409+
g + bars_group_facets(facet_args)
410+
}
411+
412+
370413
#' @rdname PPC-discrete
371414
#' @export
372415
ppc_bars_data <-
@@ -481,11 +524,13 @@ fixed_y <- function(facet_args) {
481524

482525
#' Internal function for `ppc_rootogram()`
483526
#' @param y,yrep User's `y` and `yrep` arguments.
527+
#' @param group User's `group` argument (can be NULL).
484528
#' @param style,prob,bound_distinct User's `style`, `prob`, and
485529
#' (if applicable) `bound_distinct` arguments.
486530
#' @noRd
487531
.ppc_rootogram_data <- function(y,
488532
yrep,
533+
group = NULL,
489534
style = c("standing", "hanging", "suspended", "discrete"),
490535
prob = 0.9,
491536
bound_distinct) {
@@ -498,7 +543,41 @@ fixed_y <- function(facet_args) {
498543
if (!all_counts(yrep)) {
499544
abort("ppc_rootogram expects counts as inputs to 'yrep'.")
500545
}
546+
547+
if (!is.null(group)) {
548+
group <- validate_group(group, length(y))
549+
}
550+
551+
# Handle grouped data
552+
if (!is.null(group)) {
553+
group_levels <- unique(group)
554+
all_data <- list()
555+
556+
for (g in seq_along(group_levels)) {
557+
grp <- group_levels[g]
558+
idx <- which(group == grp)
559+
560+
y_g <- y[idx]
561+
yrep_g <- yrep[, idx, drop = FALSE]
562+
563+
# Call this function recursively without group
564+
data_g <- .ppc_rootogram_data(
565+
y = y_g,
566+
yrep = yrep_g,
567+
group = NULL,
568+
style = style,
569+
prob = prob,
570+
bound_distinct = bound_distinct
571+
)
572+
573+
data_g$group <- grp
574+
all_data[[g]] <- data_g
575+
}
576+
577+
return(do.call(rbind, all_data))
578+
}
501579

580+
# Ungrouped data processing
502581
alpha <- (1 - prob) / 2
503582
probs <- c(alpha, 1 - alpha)
504583
ymax <- max(y, yrep)

man/PPC-discrete.Rd

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

0 commit comments

Comments
 (0)