14
14
# ' it was larger). If breaks is a function, the x vector is supplied to it as
15
15
# ' the only argument (and the number of breaks is only limited by the amount of
16
16
# ' 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).
17
27
# ' @examples
18
28
# ' # "histogram"/"hist" type convenience string(s)
19
29
# ' tinyplot(Nile, type = "histogram")
22
32
# ' tinyplot(Nile, type = type_histogram(breaks = 30))
23
33
# '
24
34
# ' # 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
+ # '
26
67
# ' @export
27
- type_histogram = function (breaks = " Sturges" ) {
68
+ type_histogram = function (breaks = " Sturges" , free.breaks = FALSE , drop.zeros = TRUE ) {
28
69
out = list (
29
- data = data_histogram(breaks = breaks ),
70
+ data = data_histogram(breaks = breaks , free.breaks = free.breaks , drop.zeros = drop.zeros ),
30
71
draw = draw_rect(),
31
72
name = " histogram"
32
73
)
@@ -39,10 +80,12 @@ type_histogram = function(breaks = "Sturges") {
39
80
type_hist = type_histogram
40
81
41
82
42
- data_histogram = function (breaks = " Sturges" ) {
83
+ data_histogram = function (breaks = " Sturges" , free.breaks = FALSE , drop.zeros = TRUE ) {
43
84
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" )
46
89
47
90
if (is.null(ylab )) ylab = " Frequency"
48
91
if (is.null(by ) && is.null(palette )) {
@@ -52,12 +95,20 @@ data_histogram = function(breaks = "Sturges") {
52
95
if (is.null(bg )) bg = ribbon.alpha
53
96
}
54
97
55
- datapoints_breaks = hist(datapoints $ x , breaks = hbreaks , plot = FALSE )
98
+ if ( ! .freebreaks ) xbreaks = hist(datapoints $ x , breaks = hbreaks , plot = FALSE )$ breaks
56
99
datapoints = split(datapoints , list (datapoints $ by , datapoints $ facet ))
57
100
datapoints = Filter(function (k ) nrow(k ) > 0 , datapoints )
58
-
101
+
59
102
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
+ }
61
112
out = data.frame (
62
113
by = k $ by [1 ], # already split
63
114
facet = k $ facet [1 ], # already split
@@ -88,5 +139,3 @@ data_histogram = function(breaks = "Sturges") {
88
139
}
89
140
return (fun )
90
141
}
91
-
92
-
0 commit comments