Skip to content

Commit da6e957

Browse files
Update type_histogram.R (#288)
* Update type_histogram.R do not force common break points across facets. this can be done through the break option. however, passing a vector to break is currently broken as is.null() is not vectorised. * introduce option to allow for free breaks across groups and facets * tweak free.breaks + add drop.zeros arg - document * Update type_histogram.Rd * Update type_histogram.R Fix borked merge --------- Co-authored-by: Grant McDermott <grant.mcdermott@gmail.com>
1 parent 7a44a84 commit da6e957

File tree

2 files changed

+106
-14
lines changed

2 files changed

+106
-14
lines changed

R/type_histogram.R

Lines changed: 60 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@
1414
#' it was larger). If breaks is a function, the x vector is supplied to it as
1515
#' the only argument (and the number of breaks is only limited by the amount of
1616
#' available memory).
17+
#' @param free.breaks Logical indicating whether the breakpoints should be
18+
#' computed separately for each group or facet? Default is `FALSE`, meaning
19+
#' that the breakpoints are computed from the full dataset; thus ensuring
20+
#' common bin widths across each group/facet. Can also use `free` as an
21+
#' acceptable argument alias. Ignored if there are no groups and/or facets.
22+
#' @param drop.zeros Logical indicating whether bins with zero counts should be
23+
#' dropped before plotting. Default is `TRUE`. Note that switching to `FALSE`
24+
#' may interfere with faceted plot behaviour if `facet.args = list(free)`,
25+
#' since the `x` variable is effectively recorded over the full range of the
26+
#' x-axis (even if it does not extend over this range for every group).
1727
#' @examples
1828
#' # "histogram"/"hist" type convenience string(s)
1929
#' tinyplot(Nile, type = "histogram")
@@ -22,11 +32,42 @@
2232
#' tinyplot(Nile, type = type_histogram(breaks = 30))
2333
#'
2434
#' # Grouped histogram example
25-
#' tinyplot(~Petal.Width | Species, data = iris, type = type_histogram(breaks = 30))
35+
#' tinyplot(
36+
#' ~Petal.Width | Species,
37+
#' type = "histogram",
38+
#' data = iris
39+
#' )
40+
#'
41+
#' # Faceted version
42+
#' tinyplot(
43+
#' ~Petal.Width, facet = ~Species,
44+
#' type = "histogram",
45+
#' data = iris
46+
#' )
47+
#'
48+
#' # For visualizing faceted histograms across varying scales, you may also wish
49+
#' # to impose free histogram breaks too (i.e., calculate breaks separately for
50+
#' # each group). Compare:
51+
#'
52+
#' # free facet scales + shared histogram breaks, versus...
53+
#' tinyplot(
54+
#' ~Petal.Width, facet = ~Species,
55+
#' facet.args = list(free = TRUE),
56+
#' type = type_histogram(),
57+
#' data = iris
58+
#' )
59+
#' # ... free facet scales + free histogram breaks
60+
#' tinyplot(
61+
#' ~Petal.Width, facet = ~Species,
62+
#' facet.args = list(free = TRUE),
63+
#' type = type_histogram(free = TRUE),
64+
#' data = iris
65+
#' )
66+
#'
2667
#' @export
27-
type_histogram = function(breaks = "Sturges") {
68+
type_histogram = function(breaks = "Sturges", free.breaks = FALSE, drop.zeros = TRUE) {
2869
out = list(
29-
data = data_histogram(breaks = breaks),
70+
data = data_histogram(breaks = breaks, free.breaks = free.breaks, drop.zeros = drop.zeros),
3071
draw = draw_rect(),
3172
name = "histogram"
3273
)
@@ -39,10 +80,12 @@ type_histogram = function(breaks = "Sturges") {
3980
type_hist = type_histogram
4081

4182

42-
data_histogram = function(breaks = "Sturges") {
83+
data_histogram = function(breaks = "Sturges", free.breaks = FALSE, drop.zeros = TRUE) {
4384
hbreaks = breaks
44-
fun = function(by, facet, ylab, col, bg, ribbon.alpha, datapoints, .breaks = hbreaks, ...) {
45-
hbreaks = ifelse(!is.null(.breaks), .breaks, "Sturges")
85+
hfree.breaks = free.breaks
86+
hdrop.zeros = drop.zeros
87+
fun = function(by, facet, ylab, col, bg, ribbon.alpha, datapoints, .breaks = hbreaks, .freebreaks = hfree.breaks, .drop.zeros = hdrop.zeros, ...) {
88+
hbreaks = ifelse(!sapply(.breaks, is.null), .breaks, "Sturges")
4689

4790
if (is.null(ylab)) ylab = "Frequency"
4891
if (is.null(by) && is.null(palette)) {
@@ -52,12 +95,20 @@ data_histogram = function(breaks = "Sturges") {
5295
if (is.null(bg)) bg = ribbon.alpha
5396
}
5497

55-
datapoints_breaks = hist(datapoints$x, breaks = hbreaks, plot = FALSE)
98+
if (!.freebreaks) xbreaks = hist(datapoints$x, breaks = hbreaks, plot = FALSE)$breaks
5699
datapoints = split(datapoints, list(datapoints$by, datapoints$facet))
57100
datapoints = Filter(function(k) nrow(k) > 0, datapoints)
58-
101+
59102
datapoints = lapply(datapoints, function(k) {
60-
h = hist(k$x, breaks = datapoints_breaks$breaks, plot = FALSE)
103+
if (.freebreaks) xbreaks = breaks
104+
h = hist(k$x, breaks = xbreaks, plot = FALSE)
105+
# zero count cases
106+
if (.drop.zeros) {
107+
nzidx = which(h$counts > 0)
108+
h$counts = h$counts[nzidx]
109+
h$breaks = h$breaks[c(1, nzidx+1)]
110+
h$mids = h$mids[nzidx]
111+
}
61112
out = data.frame(
62113
by = k$by[1], # already split
63114
facet = k$facet[1], # already split
@@ -88,5 +139,3 @@ data_histogram = function(breaks = "Sturges") {
88139
}
89140
return(fun)
90141
}
91-
92-

man/type_histogram.Rd

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

0 commit comments

Comments
 (0)