Skip to content

Commit d648910

Browse files
committed
Update epix_slide before docs, add validation
- Try to describe `before` in a similar manner as the PR for `epi_slide` `before`&`after` currently does. - Fix some example discussion not yet adjusted for `before` being off by one relative to `n`. - Update some discussion about differences between `epix_slide` and `epi_slide` `time_value` windows. - Add tests for the `before` validation code
1 parent 6c56208 commit d648910

File tree

4 files changed

+95
-27
lines changed

4 files changed

+95
-27
lines changed

R/archive.R

+14-1
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,20 @@ epi_archive =
597597
ref_time_values = ref_time_values[ref_time_values %in%
598598
unique(self$DT$time_value)]
599599
}
600-
600+
601+
# Validate and pre-process `before`:
602+
if (missing(before)) {
603+
Abort("`before` is required (and must be passed by name);
604+
if you did not want to apply a sliding window but rather
605+
to map `as_of` and `f` across various `ref_time_values`,
606+
pass a large `before` value (e.g., if time steps are days,
607+
`before=365000`).")
608+
}
609+
before <- vctrs::vec_cast(before, integer())
610+
if (length(before) != 1L || is.na(before) || before < 0L) {
611+
Abort("`before` must be length-1, non-NA, non-negative")
612+
}
613+
601614
# If a custom time step is specified, then redefine units
602615
if (!missing(time_step)) before <- time_step(before)
603616

R/methods-epi_archive.R

+23-8
Original file line numberDiff line numberDiff line change
@@ -358,10 +358,21 @@ epix_merge = function(x, y,
358358
#' @param ... Additional arguments to pass to the function or formula specified
359359
#' via `f`. Alternatively, if `f` is missing, then the current argument is
360360
#' interpreted as an expression for tidy evaluation.
361-
#' @param before Number of time steps to use in the running window. For example,
362-
#' if `before = 7`, and one time step is one day, then to produce a value on
363-
#' January 7 we apply the given function or formula to data in between January
364-
#' 1 and 7.
361+
#' @param before How far `before` each `ref_time_value` should the sliding
362+
#' window extend? If provided, should be a single, non-NA,
363+
#' [integer-compatible][vctrs::vec_cast] number of time steps. This window
364+
#' endpoint is inclusive. For example, if `before = 7`, and one time step is
365+
#' one day, then to produce a value for a `ref_time_value` of January 8, we
366+
#' apply the given function or formula to data (for each group present) with
367+
#' `time_value`s from January 1 onward, as they were reported on January 8.
368+
#' For typical disease surveillance sources, this will not include any data
369+
#' with a `time_value` of January 8, and, depending on the amount of reporting
370+
#' latency, may not include January 7 or even earlier `time_value`s. (If
371+
#' instead the archive were to hold nowcasts instead of regular surveillance
372+
#' data, then we would indeed expect data for `time_value` January 8. If it
373+
#' were to hold forecasts, then we would expect data for `time_value`s after
374+
#' January 8, and the sliding window would extend as far after each
375+
#' `ref_time_value` as needed to include all such `time_value`s.)
365376
#' @param group_by The variable(s) to group by before slide computation. If
366377
#' missing, then the keys in the underlying data table, excluding `time_value`
367378
#' and `version`, will be used for grouping. To omit a grouping entirely, use
@@ -396,10 +407,14 @@ epix_merge = function(x, y,
396407
#' values.
397408
#'
398409
#' @details Two key distinctions between inputs to the current function and
399-
#' `epi_slide()`:
400-
#' 1. `epix_slide()` uses windows that are **always right-aligned** (in
401-
#' `epi_slide()`, custom alignments could be specified using the `align` or
402-
#' `before` arguments).
410+
#' [`epi_slide()`]:
411+
#' 1. `epix_slide()` doesn't accept an `after` argument; its windows extend
412+
#' from `before` time steps before a given `ref_time_value` through the last
413+
#' `time_value` available as of version `ref_time_value` (typically, this
414+
#' won't include `ref_time_value` itself, as observations about a particular
415+
#' time interval (e.g., day) are only published after that time interval ends);
416+
#' `epi_slide` windows extend from `before` time steps before a
417+
#' `ref_time_value` through `after` time steps after `ref_time_value`.
403418
#' 2. `epix_slide()` uses a `group_by` to specify the grouping upfront (in
404419
#' `epi_slide()`, this would be accomplished by a preceding function call to
405420
#' `dplyr::group_by()`).

man/epix_slide.Rd

+23-8
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/test-epix_slide.R

+35-10
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@ test_that("epix_slide only works on an epi_archive",{
44
expect_error(epix_slide(data.frame(x=1)))
55
})
66

7+
x <- tibble::tribble(~version, ~time_value, ~binary,
8+
4, c(1:3), 2^(1:3),
9+
5, c(1:2,4), 2^(4:6),
10+
6, c(1:2,4:5), 2^(7:10),
11+
7, 2:6, 2^(11:15)) %>%
12+
tidyr::unnest(c(time_value,binary))
13+
14+
xx <- bind_cols(geo_value = rep("x",15), x) %>%
15+
as_epi_archive()
16+
717
test_that("epix_slide works as intended",{
8-
x <- tibble::tribble(~version, ~time_value, ~binary,
9-
4, c(1:3), 2^(1:3),
10-
5, c(1:2,4), 2^(4:6),
11-
6, c(1:2,4:5), 2^(7:10),
12-
7, 2:6, 2^(11:15)) %>%
13-
tidyr::unnest(c(time_value,binary))
14-
15-
xx <- bind_cols(geo_value = rep("x",15), x) %>%
16-
as_epi_archive()
17-
1818
xx1 <- epix_slide(x = xx,
1919
f = ~ sum(.x$binary),
2020
before = 2,
@@ -38,3 +38,28 @@ test_that("epix_slide works as intended",{
3838

3939
expect_identical(xx1,xx3) # This and * Imply xx2 and xx3 are identical
4040
})
41+
42+
test_that("epix_slide `before` validation works", {
43+
expect_error(xx$slide(f = ~ sum(.x$binary)),
44+
"`before` is required")
45+
expect_error(xx$slide(f = ~ sum(.x$binary), before=NA),
46+
"`before`.*NA")
47+
expect_error(xx$slide(f = ~ sum(.x$binary), before=-1),
48+
"`before`.*negative")
49+
expect_error(xx$slide(f = ~ sum(.x$binary), before=1.5),
50+
regexp="before",
51+
class="vctrs_error_incompatible_type")
52+
# We might want to allow this at some point (issue #219):
53+
expect_error(xx$slide(f = ~ sum(.x$binary), before=Inf),
54+
regexp="before",
55+
class="vctrs_error_incompatible_type")
56+
# (wrapper shouldn't introduce a value:)
57+
expect_error(epix_slide(xx, f = ~ sum(.x$binary)), "`before` is required")
58+
# These `before` values should be accepted:
59+
expect_error(xx$slide(f = ~ sum(.x$binary), before=0),
60+
NA)
61+
expect_error(xx$slide(f = ~ sum(.x$binary), before=2L),
62+
NA)
63+
expect_error(xx$slide(f = ~ sum(.x$binary), before=365000),
64+
NA)
65+
})

0 commit comments

Comments
 (0)