diff --git a/NAMESPACE b/NAMESPACE index bc6c39b42..c2af91940 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -9,6 +9,9 @@ S3method(extract_,grouped_df) S3method(extract_,tbl_df) S3method(fill_,data.frame) S3method(fill_,grouped_df) +S3method(full_seq,Date) +S3method(full_seq,POSIXct) +S3method(full_seq,numeric) S3method(gather_,data.frame) S3method(gather_,grouped_df) S3method(gather_,tbl_df) diff --git a/NEWS.md b/NEWS.md index 0a5c17772..4117c9c3d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # tidyr 0.4.1.9000 +* `full_seq()` now preserve attributes for dates and date/times (#156). + * Sequences generated by `full_seq()` no now longer need to start at 0. * Moved in useful sample datasets from the DSR package. diff --git a/R/seq.R b/R/seq.R index 5cd7d242d..7fb3ce55c 100644 --- a/R/seq.R +++ b/R/seq.R @@ -12,6 +12,11 @@ #' @examples #' full_seq(c(1, 2, 4, 5, 10), 1) full_seq <- function(x, period, tol = 1e-6) { + UseMethod("full_seq") +} + +#' @export +full_seq.numeric <- function(x, period, tol = 1e-6) { rng <- range(x, na.rm = TRUE) if (any((x - rng[1]) %% period > tol)) { stop("`x` is not a regular sequence.", call. = FALSE) @@ -19,3 +24,19 @@ full_seq <- function(x, period, tol = 1e-6) { seq(rng[1], rng[2], by = period) } + +#' @export +full_seq.Date <- function(x, period, tol = 1e-6) { + restore(full_seq(as.numeric(x), period, tol), x) +} + +#' @export +full_seq.POSIXct <- function(x, period, tol = 1e-6) { + restore(full_seq(as.numeric(x), period, tol), x) +} + + +restore <- function(old, new) { + mostattributes(new) <- attributes(old) + new +} diff --git a/R/utils.R b/R/utils.R index 5d9c10697..c56bbafd0 100644 --- a/R/utils.R +++ b/R/utils.R @@ -73,3 +73,7 @@ regroup <- function(x, y, except) { # Allows tests to work with either dplyr 0.4 (which ignores value of # everything), and 0.5 which exports it as a proper function everything <- function(...) dplyr::everything(...) + +is_numeric <- function(x) { + typeof(x) %in% c("integer", "double") +} diff --git a/tests/testthat/test-full_seq.R b/tests/testthat/test-full_seq.R index 4e818993f..6c90871fe 100644 --- a/tests/testthat/test-full_seq.R +++ b/tests/testthat/test-full_seq.R @@ -11,3 +11,11 @@ test_that("sequences don't have to start at zero", { test_that("full_seq fills in gaps", { expect_equal(full_seq(c(1, 3), 1), c(1, 2, 3)) }) + +test_that("preserves attributes", { + x1 <- as.Date("2001-01-01") + c(0, 2) + x2 <- as.POSIXct(x1) + + expect_s3_class(full_seq(x1, 2), "Date") + expect_s3_class(full_seq(x2, 86400), c("POSIXct", "POSIXt")) +})