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# '
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:
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+ # '
150172NULL
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- # '
269278ppc_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
372415ppc_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 )
0 commit comments