context("compute_bin") comp_bin <- function(...) { suppressMessages(compute_bin(...)) } test_that("compute_bin preserves dates and times", { dates <- data.frame(val = as.Date("2013-06-01") + 0:100) NYtimes <- data.frame( val = as.POSIXct('2001-06-01 21:00', tz = 'America/New_York') + 0:10 * 100 ) UTCtimes <- data.frame( val = as.POSIXct('2001-06-01 21:00', tz = 'UTC') + seq(0, 1000, by = 10) ) res <- comp_bin(dates, ~val, width = 30) expect_true(inherits(res$x_, "Date")) expect_true(inherits(res$xmin_, "Date")) expect_true(inherits(res$xmax_, "Date")) expect_equal(sum(res$count_), length(dates$val)) res <- comp_bin(NYtimes, ~val, width = 120) expect_true(inherits(res$x_, "POSIXct")) expect_true(inherits(res$xmin_, "POSIXct")) expect_true(inherits(res$xmax_, "POSIXct")) expect_equal(sum(res$count_), length(NYtimes$val)) expect_identical(attr(NYtimes$val, "tzone"), attr(res$x_, "tzone")) res <- comp_bin(UTCtimes, ~val, width = 120) expect_equal(sum(res$count_), length(UTCtimes$val)) expect_identical(attr(UTCtimes$val, "tzone"), attr(res$x_, "tzone")) }) test_that("width in lubridate::Period", { UTCtimes <- data.frame( val = as.POSIXct('2001-06-01 21:00', tz = 'UTC') + seq(0, 1000, by = 10) ) # width specified as a Period from lubridate expect_identical( comp_bin(UTCtimes, ~val, width = lubridate::ms("1 42")), comp_bin(UTCtimes, ~val, width = 102) ) }) test_that("Closed left or right", { dat <- data.frame(x = c(0, 10)) res <- comp_bin(dat, ~x, width = 10, pad = FALSE) expect_identical(res$count_, c(1, 1)) res <- comp_bin(dat, ~x, width = 10, boundary = 5, pad = FALSE) expect_identical(res$count_, c(1, 1)) res <- comp_bin(dat, ~x, width = 10, boundary = 0, pad = FALSE) expect_identical(res$count_, 2) res <- comp_bin(dat, ~x, width = 5, boundary = 0, pad = FALSE) expect_identical(res$count_, c(1, 1)) res <- comp_bin(dat, ~x, width = 10, pad = FALSE, closed = "left") expect_identical(res$count_, c(1, 1)) res <- comp_bin(dat, ~x, width = 10, boundary = 5, pad = FALSE, closed = "left") expect_identical(res$count_, c(1, 1)) res <- comp_bin(dat, ~x, width = 10, boundary = 0, pad = FALSE, closed = "left") expect_identical(res$count_, c(2)) res <- comp_bin(dat, ~x, width = 5, boundary = 0, pad = FALSE, closed = "left") expect_identical(res$count_, c(1, 1)) }) test_that("Setting boundary and center", { # numeric dat <- data.frame(x = c(0, 30)) # Error if both boundary and center are specified expect_error(comp_bin(dat, ~x, width = 10, bondary = 5, center = 0, pad = FALSE)) res <- comp_bin(dat, ~x, width = 10, boundary = 0, pad = FALSE) expect_identical(res$count_, c(1, 0, 1)) expect_identical(res$xmin_[1], 0) expect_identical(res$xmax_[3], 30) res <- comp_bin(dat, ~x, width = 10, center = 0, pad = FALSE) expect_identical(res$count_, c(1, 0, 0, 1)) expect_identical(res$xmin_[1], dat$x[1] - 5) expect_identical(res$xmax_[4], dat$x[2] + 5) # Date dat <- data.frame(x = as.Date("2013-06-01") + c(0, 30)) res <- comp_bin(dat, ~x, width = 10, boundary = as.Date("2013-06-01"), pad = FALSE) expect_identical(res$count_, c(1, 0, 1)) expect_identical(res$xmin_[1], dat$x[1]) expect_identical(res$xmax_[3], dat$x[2]) res <- comp_bin(dat, ~x, width = 10, center = as.Date("2013-06-01"), pad = FALSE) expect_identical(res$count_, c(1, 0, 0, 1)) expect_identical(res$xmin_[1], dat$x[1] - 5) expect_identical(res$xmax_[4], dat$x[2] + 5) # POSIXct dat <- data.frame( x = as.POSIXct('2001-06-01 21:00', tz = 'America/New_York') + c(0, 30000) ) res <- comp_bin(dat, ~x, width = 10000, boundary = dat$x[1], pad = FALSE) expect_identical(res$count_, c(1, 0, 1)) expect_identical(res$xmin_[1], dat$x[1]) expect_identical(res$xmax_[3], dat$x[2]) res <- comp_bin(dat, ~x, width = 10000, center = dat$x[1], pad = FALSE) expect_identical(res$count_, c(1, 0, 0, 1)) expect_identical(res$xmin_[1], dat$x[1] - 5000) expect_identical(res$xmax_[4], dat$x[2] + 5000) }) test_that("Automatic width", { dat <- data.frame( num = c(0, 25.0), num2 = c(0, 50.0), int = c(1L, 25L), int2 = c(1L, 50L), date = as.Date("2013-06-01") + c(0, 100), posixct = as.POSIXct('2001-06-01 21:00', tz = 'UTC') + c(0, 1000) ) # numeric res <- comp_bin(dat, ~num) # It generates approx 30 bins, at round numbers, so should have width 1 expect_identical(res$width_, rep(1, length(res$width_))) res <- comp_bin(dat, ~num2) expect_identical(res$width_, rep(2, length(res$width_))) # integer res <- comp_bin(dat, ~int) expect_true(all(res$width_ == 1L)) res <- comp_bin(dat, ~int2) expect_true(all(res$width_ == 2L)) # Date res <- comp_bin(dat, ~date) # There was a change in behavior of `pretty` in 3.3.0 which results in # different output from earlier versions. r_version <- as.package_version(paste0(R.Version()$major, ".", R.Version()$minor)) if (r_version >= "3.3.0") expect_identical(res$width_, rep(7, length(res$width_))) else expect_identical(res$width_, rep(2, length(res$width_))) # POSIXct res <- comp_bin(dat, ~posixct) expect_identical(res$width_, rep(30, length(res$width_))) }) test_that("Boundaries across groups should be aligned", { dat <- data.frame(x = c(0:2, 0:2+0.7), g=c('a','a','a', 'b','b','b')) res <- dat %>% group_by(g) %>% compute_bin(~x, width = 1, pad = FALSE) expect_true(length(unique(res$x_ %% 1)) == 1) expect_identical(dplyr::groups(res), list(quote(g))) expect_identical(res$count_, rep(1, 6)) }) test_that("Zero-row inputs", { res <- mtcars[0,] %>% compute_bin(~mpg) expect_equal(nrow(res), 0) expect_true(setequal( names(res), c("count_", "x_", "xmin_", "xmax_", "width_") )) # Grouped res <- mtcars[0,] %>% group_by(cyl) %>% compute_bin(~mpg) expect_equal(nrow(res), 0) expect_true(setequal( names(res), c("cyl", "count_", "x_", "xmin_", "xmax_", "width_") )) }) test_that("weights are added", { df <- data.frame(x = 1:10, y = 1:10) binned <- df %>% compute_bin(~x, ~y, width = 1, pad = FALSE) expect_equal(binned$count_, df$y) }) # Bin vector ------------------------------------------------------------------- test_that("NAs get own bin", { x <- c(1:10, NA, NA, NA, NA) binned <- bin_vector(x, width = 100) expect_equal(binned$count_, c(10, 4)) expect_equal(binned$x_, c(50, NA)) }) test_that("only NA, one row of output", { x <- as.numeric(c(NA, NA, NA, NA)) binned <- bin_vector(x) expect_equal(binned$count_, 4) expect_equal(binned$x_, NA) })