@@ -99,17 +99,13 @@ StatBin <- ggproto("StatBin", Stat,
99
99
params $ closed <- if (params $ right ) " right" else " left"
100
100
params $ right <- NULL
101
101
}
102
- if (! is.null(params $ breaks )) {
103
- stop(" `breaks` is deprecated." , call. = FALSE )
104
- }
105
102
if (! is.null(params $ width )) {
106
103
stop(" `width` is deprecated. Do you want `geom_bar()`?" , call. = FALSE )
107
104
}
108
105
if (! is.null(params $ boundary ) && ! is.null(params $ center )) {
109
106
stop(" Only one of `boundary` and `center` may be specified." , call. = FALSE )
110
107
}
111
108
112
-
113
109
if (is.null(params $ breaks ) && is.null(params $ binwidth ) && is.null(params $ bins )) {
114
110
message_wrap(" `stat_bin()` using `bins = 30`. Pick better value with `binwidth`." )
115
111
params $ bins <- 30
@@ -126,151 +122,19 @@ StatBin <- ggproto("StatBin", Stat,
126
122
breaks = NULL , origin = NULL , right = NULL ,
127
123
drop = NULL , width = NULL ) {
128
124
129
- params <- bin_params(
130
- scales $ x $ dimension(),
131
- width = binwidth ,
132
- bins = bins ,
133
- center = center ,
134
- boundary = boundary ,
135
- closed = closed
136
- )
137
-
138
- bin_vector(data $ x , weight = data $ weight , width = params $ width ,
139
- origin = params $ origin , closed = params $ closed , pad = pad )
125
+ if (! is.null(breaks )) {
126
+ bins <- bin_breaks(breaks , closed )
127
+ } else if (! is.null(binwidth )) {
128
+ bins <- bin_breaks_width(scales $ x $ dimension(), binwidth , center = center ,
129
+ boundary = boundary , closed = closed )
130
+ } else {
131
+ bins <- bin_breaks_bins(scales $ x $ dimension(), bins , center = center ,
132
+ boundary = boundary , closed = closed )
133
+ }
134
+ bin_vector(data $ x , bins , weight = data $ weight , pad = pad )
140
135
},
141
136
142
137
default_aes = aes(y = ..count.. ),
143
138
required_aes = c(" x" )
144
139
)
145
140
146
-
147
- # Compute parameters -----------------------------------------------------------
148
-
149
- bin_params <- function (x_range , width = NULL , bins = 30 , center = NULL ,
150
- boundary = NULL , closed = c(" right" , " left" )) {
151
- closed <- match.arg(closed )
152
-
153
- if (length(x_range ) == 0 ) {
154
- return (list (width = width , origin = NULL , closed = closed ))
155
- }
156
-
157
- stopifnot(length(x_range ) == 2 )
158
- if (! is.null(boundary ) && ! is.null(center )) {
159
- stop(" Only one of 'boundary' and 'center' may be specified." )
160
- }
161
-
162
- if (is.null(width )) {
163
- width <- (x_range [2 ] - x_range [1 ]) / (bins - 1 )
164
- }
165
-
166
- if (is.null(boundary )) {
167
- if (is.null(center )) {
168
- # If neither edge nor center given, compute both using tile layer's
169
- # algorithm. This puts min and max of data in outer half of their bins.
170
- boundary <- width / 2
171
-
172
- } else {
173
- # If center given but not boundary, compute boundary.
174
- boundary <- center - width / 2
175
- }
176
- }
177
-
178
- # Inputs could be Dates or POSIXct, so make sure these are all numeric
179
- x_range <- as.numeric(x_range )
180
- width <- as.numeric(width )
181
- boundary <- as.numeric(boundary )
182
-
183
- origin <- find_origin(x_range , width , boundary )
184
-
185
- list (width = width , origin = origin , closed = closed )
186
- }
187
-
188
- # Find the left side of left-most bin
189
- find_origin <- function (x_range , width , boundary ) {
190
- shift <- floor((x_range [1 ] - boundary ) / width )
191
- boundary + shift * width
192
- }
193
-
194
- bin_vector <- function (x , weight = NULL , ... , width = 1 ,
195
- origin = 0 , closed = c(" right" , " left" ),
196
- pad = FALSE ) {
197
- closed <- match.arg(closed )
198
-
199
- if (all(is.na(x ))) {
200
- return (bin_out(length(x ), NA , NA , xmin = NA , xmax = NA ))
201
- }
202
-
203
- stopifnot(is.numeric(width ) && length(width ) == 1 )
204
- stopifnot(is.numeric(origin ) && length(origin ) == 1 )
205
-
206
- if (is.null(weight )) {
207
- weight <- rep(1 , length(x ))
208
- } else {
209
- weight [is.na(weight )] <- 0
210
- }
211
-
212
- min_x <- origin
213
- # Small correction factor so that we don't get an extra bin when, for
214
- # example, origin=0, max(x)=20, width=10.
215
- max_x <- max(x , na.rm = TRUE ) + (1 - 1e-08 ) * width
216
- breaks <- seq(min_x , max_x , width )
217
- fuzzybreaks <- adjust_breaks2(breaks , closed = closed )
218
-
219
- bins <- cut(x , fuzzybreaks , include.lowest = TRUE , right = (closed == " right" ))
220
-
221
- left <- breaks [- length(breaks )]
222
- right <- breaks [- 1 ]
223
- x <- (left + right ) / 2
224
- bin_widths <- diff(breaks )
225
-
226
- count <- as.numeric(tapply(weight , bins , sum , na.rm = TRUE ))
227
- count [is.na(count )] <- 0
228
-
229
- if (pad ) {
230
- count <- c(0 , count , 0 )
231
- bin_widths <- c(width , bin_widths , width )
232
- x <- c(x [1 ] - width , x , x [length(x )] + width )
233
- }
234
-
235
- # Add row for missings
236
- if (any(is.na(bins ))) {
237
- count <- c(count , sum(is.na(bins )))
238
- left <- c(left , NA )
239
- right <- c(right , NA )
240
- x <- c(x , NA )
241
- bin_widths <- c(bin_widths , NA )
242
- }
243
-
244
- bin_out(count , x , bin_widths )
245
- }
246
-
247
- bin_out <- function (count = integer(0 ), x = numeric (0 ), width = numeric (0 ),
248
- xmin = x - width / 2 , xmax = x + width / 2 ) {
249
- density <- count / width / sum(abs(count ))
250
-
251
- data.frame (
252
- count = count ,
253
- x = x ,
254
- xmin = xmin ,
255
- xmax = xmax ,
256
- width = width ,
257
- density = density ,
258
- ncount = count / max(abs(count )),
259
- ndensity = count / max(abs(density )),
260
- stringsAsFactors = FALSE
261
- )
262
- }
263
-
264
- # Adapt break fuzziness from base::hist - this protects from floating
265
- # point rounding errors
266
- adjust_breaks2 <- function (breaks , closed = " left" ) {
267
- closed <- match.arg(closed , c(" right" , " left" ))
268
-
269
- diddle <- 1e-08 * median(diff(breaks ))
270
- if (closed == " right" ) {
271
- fuzz <- c(- diddle , rep.int(diddle , length(breaks ) - 1 ))
272
- } else {
273
- fuzz <- c(rep.int(- diddle , length(breaks ) - 1 ), diddle )
274
- }
275
- sort(breaks ) + fuzz
276
- }
0 commit comments