File: seq.R

package info (click to toggle)
r-cran-tidyr 1.3.1-1
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 2,720 kB
  • sloc: cpp: 268; sh: 9; makefile: 2
file content (51 lines) | stat: -rw-r--r-- 1,455 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
#' Create the full sequence of values in a vector
#'
#' This is useful if you want to fill in missing values that should have
#' been observed but weren't. For example, `full_seq(c(1, 2, 4, 6), 1)`
#' will return `1:6`.
#'
#' @param x A numeric vector.
#' @param period Gap between each observation. The existing data will be
#'   checked to ensure that it is actually of this periodicity.
#' @param tol Numerical tolerance for checking periodicity.
#' @export
#' @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) {
  check_number_decimal(period)
  check_number_decimal(tol, min = 0)

  rng <- range(x, na.rm = TRUE)
  if (any(((x - rng[1]) %% period > tol) &
          (period - (x - rng[1]) %% period > tol))) {
    cli::cli_abort("{.arg x} is not a regular sequence.")
  }

  # in cases where the last element is within tolerance, pad it so that
  #   the output length is correct
  if (period - ((rng[2] - rng[1]) %% period) <= tol) {
    rng[2] <- rng[2] + tol
  }

  seq(rng[1], rng[2], by = period)
}

#' @export
full_seq.Date <- function(x, period, tol = 1e-6) {
  restore(x, full_seq(as.numeric(x), period, tol))
}

#' @export
full_seq.POSIXct <- function(x, period, tol = 1e-6) {
  restore(x, full_seq(as.numeric(x), period, tol))
}

restore <- function(old, new) {
  mostattributes(new) <- attributes(old)
  new
}