Skip to content

Replaced n in epi_slide and epix_slide #203

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 68 commits into from
Closed
Show file tree
Hide file tree
Changes from 66 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
1cf5aec
Updated code for separate PR to deal with coupling.
kenmawer Jul 14, 2022
d730876
Removed file that can cause conflicts due to differing branches.
kenmawer Jul 14, 2022
2d96c5a
Updated tests.
kenmawer Jul 14, 2022
4c45aa5
Fixed a typo.
kenmawer Jul 14, 2022
f06b7fe
Still needs work.
kenmawer Jul 14, 2022
8683249
Made updates as to be able to check after misunderstandings.
kenmawer Jul 15, 2022
3f42e60
Added spacing.
kenmawer Jul 15, 2022
08b22e5
Fixed a typo.
kenmawer Jul 15, 2022
d5a402c
Added a test that should be granted.
kenmawer Jul 15, 2022
dfc3566
Finally fixed epix_slide to work with the right value.
kenmawer Jul 15, 2022
62ce720
Updated data for testing
kenmawer Jul 15, 2022
5ee25e6
Still needs ref_time_values refactoring.
kenmawer Jul 15, 2022
ee9e9f6
Refactored `n` to `max_version_gap` and addressed a typo.
kenmawer Jul 18, 2022
ce44a28
Refactored code.
kenmawer Jul 18, 2022
7a32fbd
Merge branch 'main' of https://github.com/cmu-delphi/epiprocess into …
kenmawer Jul 18, 2022
2a0c97e
Changed outdated name.
kenmawer Jul 18, 2022
35f53d4
Removed defaults for `slide`.
kenmawer Jul 18, 2022
0258a03
Finally fixed an annoying bug on `advanced.Rmd`.
kenmawer Jul 18, 2022
c1369c2
Fixed errors; archive vignette still has errors.
kenmawer Jul 19, 2022
e2172a3
Pulled again to ensure matching.
kenmawer Jul 19, 2022
04302b6
Updated datasets as to run properly.
kenmawer Jul 19, 2022
feb0f47
0 errors or warnings!
kenmawer Jul 20, 2022
08a580d
Refactor of `ref_time_values` still needs fixing!
kenmawer Jul 20, 2022
666c4f7
Finally refactored incorrect time_values on epix_slide.
kenmawer Jul 20, 2022
3134a55
Changed ref_versions to refer to versions by default.
kenmawer Jul 21, 2022
bb39209
Some cleanup of slide; still incomplete.
kenmawer Jul 26, 2022
5984d8d
Still needs changes as before and after numbers are wrong.
kenmawer Jul 26, 2022
b68af0b
Changed bad formatting.
kenmawer Jul 26, 2022
b3229f2
Still needs refactoring.
kenmawer Jul 27, 2022
d18d98c
Redocumented with changes; still needs changes.
kenmawer Jul 27, 2022
121f9d2
Bad changes that break things.
kenmawer Jul 29, 2022
35811f1
Seems like merge is broken.
kenmawer Jul 29, 2022
06a6190
Updates relating to checking on main.
kenmawer Jul 29, 2022
37b3815
Merge branch 'main' of https://github.com/cmu-delphi/epiprocess into …
kenmawer Jul 29, 2022
f6e8795
Merge branch 'km-slide-n-replace' of https://github.com/dajmcdon/epip…
kenmawer Jul 29, 2022
ee10963
Seems broken beyond repair.
kenmawer Jul 29, 2022
05d84ca
Fixed tests.
kenmawer Jul 29, 2022
846b6ca
Fixed improper use of n.
kenmawer Jul 29, 2022
d55e6b8
This finally runs without errors.
kenmawer Jul 29, 2022
1158c8a
Note that epix_slide still hasn't been updated, and some epi_slide do…
kenmawer Jul 29, 2022
bbf5d6b
Need to ensure tests pass.
kenmawer Aug 5, 2022
b55d411
This shouldn't be here.
kenmawer Aug 5, 2022
b22ace3
Removed repetitive code and added more tests.
kenmawer Aug 6, 2022
feea2f4
Merge branch 'main' into km-slide-n-replace2.1
kenmawer Aug 8, 2022
1038e15
Ran document after updating to epidatr.
kenmawer Aug 9, 2022
6e2b207
Addressed first two comments.
kenmawer Aug 9, 2022
77b5bb9
Replaced `n` in details.
kenmawer Aug 9, 2022
db99a67
Updated some poorly typed documentation and an imporperly refactored …
kenmawer Aug 9, 2022
0456aff
Cleared unclear documentation and removed redundancy with slide's code.
kenmawer Aug 10, 2022
950ee8c
Added a test for blank `after`.
kenmawer Aug 10, 2022
d43cede
Refactored edf with grouped.
kenmawer Aug 10, 2022
039f33f
More fixes.
kenmawer Aug 10, 2022
93738aa
Updated `align`.
kenmawer Aug 10, 2022
8c601f8
Fixed inconsistency with test formatting.
kenmawer Aug 10, 2022
cfe2b55
Updated compactify on a vignette, added two tests for NA and put a te…
kenmawer Aug 10, 2022
6f91a55
Still need to do refactoring upon pulling.
kenmawer Aug 13, 2022
271ffe6
Still needs work.
kenmawer Aug 13, 2022
b0d751b
Still needs work, as slide necessitates that group_by be a string.
kenmawer Aug 15, 2022
9f46090
Pulled from v2.1.
kenmawer Aug 15, 2022
0498777
Still needs fixing.
kenmawer Aug 15, 2022
b9b9e6a
I somehow broke this.
kenmawer Aug 15, 2022
28a9c12
Vignettes are still failing.
kenmawer Aug 15, 2022
b407fdd
Check fails, but code chunk has `error = TRUE`.
kenmawer Aug 15, 2022
d14c0e8
Updated incorrect info.
kenmawer Aug 15, 2022
2b8690f
Added changes to awkward spacing and for the argument of before and a…
kenmawer Aug 17, 2022
3bd1368
I documented it.
kenmawer Aug 17, 2022
581648d
Refactored many things, but this still needs work.
kenmawer Aug 18, 2022
9980ec2
IDK what happened, but the refactoring went wrong.
kenmawer Aug 18, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 14 additions & 12 deletions R/archive.R
Original file line number Diff line number Diff line change
Expand Up @@ -584,23 +584,24 @@ epi_archive =
#' details.
#' @importFrom data.table key
#' @importFrom rlang !! !!! enquo quo_is_missing enquos is_quosure sym syms
slide = function(f, ..., n, group_by, ref_time_values,
slide = function(f, ..., max_version_gap, group_by,
ref_versions,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on discussion with Ryan, max_version_gap should be called before.

time_step, new_col_name = "slide_value",
as_list_col = FALSE, names_sep = "_",
all_rows = FALSE) {
# If missing, then set ref time values to be everything; else make
# sure we intersect with observed time values
if (missing(ref_time_values)) {
ref_time_values = unique(self$DT$time_value)
if (missing(ref_versions)) {
ref_versions = unique(self$DT$version)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Based on discussion with Ryan, we shouldn't rename ref_time_values (yet, at least).

}
else {
ref_time_values = ref_time_values[ref_time_values %in%
ref_versions = ref_versions[ref_versions %in%
unique(self$DT$time_value)]
}

# If a custom time step is specified, then redefine units
before_num = n-1
if (!missing(time_step)) before_num = time_step(n-1)
before_num = max_version_gap-1
if (!missing(time_step)) before_num = time_step(max_version_gap-1)

# What to group by? If missing, set according to internal keys;
# otherwise, tidyselect.
Expand All @@ -619,7 +620,7 @@ epi_archive =
# Computation for one group, one time value
comp_one_grp = function(.data_group,
f, ...,
time_value,
version,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In line with the above, please call this ref_time_value.

key_vars,
new_col) {
# Carry out the specified computation
Expand Down Expand Up @@ -665,21 +666,22 @@ epi_archive =

# Note that we've already recycled comp value to make size stable,
# so tibble() will just recycle time value appropriately
return(tibble::tibble(time_value = time_value,
return(tibble::tibble(version = version,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Again, we've put such changes on hold / are still discussing; this should be time_value = ref_time_value. (#163)

!!new_col := comp_value))
}

# If f is not missing, then just go ahead, slide by group
if (!missing(f)) {

if (rlang::is_formula(f)) f = rlang::as_function(f)

x = purrr::map_dfr(ref_time_values, function(t) {
x = purrr::map_dfr(ref_versions, function(t) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please rename t -> ref_time_value to improve consistency with the current naming approach.

self$as_of(t, min_time_value = t - before_num) %>%
tibble::as_tibble() %>%
dplyr::group_by(!!!group_by) %>%
dplyr::group_modify(comp_one_grp,
f = f, ...,
time_value = t,
version = t,
key_vars = key_vars,
new_col = new_col,
.keep = TRUE) %>%
Expand All @@ -701,13 +703,13 @@ epi_archive =
f = function(x, quo, ...) rlang::eval_tidy(quo, x)
new_col = sym(names(rlang::quos_auto_name(quos)))

x = purrr::map_dfr(ref_time_values, function(t) {
x = purrr::map_dfr(ref_versions, function(t) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

self$as_of(t, min_time_value = t - before_num) %>%
tibble::as_tibble() %>%
dplyr::group_by(!!!group_by) %>%
dplyr::group_modify(comp_one_grp,
f = f, quo = quo,
time_value = t,
version = t,
key_vars = key_vars,
new_col = new_col,
.keep = TRUE) %>%
Expand Down
6 changes: 3 additions & 3 deletions R/growth_rate.R
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
#' implicitly defined by the `x` variable; for example, if `x` is a vector of
#' `Date` objects, `h = 7`, and the reference point is January 7, then the
#' sliding window contains all data in between January 1 and 14 (matching the
#' behavior of `epi_slide()` with `n = 2 * h` and `align = "center"`).
#' behavior of `epi_slide()` with `before = h-1` and `after = h`).
#'
#' @section Additional Arguments:
#' For the global methods, "smooth_spline" and "trend_filter", additional
Expand Down Expand Up @@ -104,12 +104,12 @@
#' # COVID cases growth rate by state using default method relative change
#' jhu_csse_daily_subset %>%
#' group_by(geo_value) %>%
#' mutate(cases_gr = growth_rate(x = time_value, y = cases))
#' mutate(cases_gr = growth_rate(x = time_value, y = cases))
#'
#' # Log scale, degree 4 polynomial and 6-fold cross validation
#' jhu_csse_daily_subset %>%
#' group_by(geo_value) %>%
#' mutate(gr_poly = growth_rate( x = time_value, y = cases, log_scale = TRUE, ord = 4, k = 6))
#' mutate(gr_poly = growth_rate(x = time_value, y = cases, log_scale = TRUE, ord = 4, k = 6))

growth_rate = function(x = seq_along(y), y, x0 = x,
method = c("rel_change", "linear_reg",
Expand Down
29 changes: 16 additions & 13 deletions R/methods-epi_archive.R
Original file line number Diff line number Diff line change
Expand Up @@ -358,15 +358,17 @@ epix_merge = function(x, y,
#' @param ... Additional arguments to pass to the function or formula specified
#' via `f`. Alternatively, if `f` is missing, then the current argument is
#' interpreted as an expression for tidy evaluation.
#' @param n Number of time steps to use in the running window. For example, if
#' `n = 7`, and one time step is one day, then to produce a value on January 7
#' @param max_version_gap Number of time steps to use in the running window.
#' For example, if
#' `max_version_gap = 7`, and one time step is one day, then to produce a
#' value on January 7
#' we apply the given function or formula to data in between January 1 and
#' 7.
#' @param group_by The variable(s) to group by before slide computation. If
#' missing, then the keys in the underlying data table, excluding `time_value`
#' and `version`, will be used for grouping. To omit a grouping entirely, use
#' `group_by = NULL`.
#' @param ref_time_values Time values for sliding computations, meaning, each
#' @param ref_versions Time values for sliding computations, meaning, each
#' element of this vector serves as the reference time point for one sliding
#' window. If missing, then this will be set to all unique time values in the
#' underlying data table, by default.
Expand Down Expand Up @@ -422,11 +424,11 @@ epix_merge = function(x, y,
#' Finally, this is simply a wrapper around the `slide()` method of the
#' `epi_archive` class, so if `x` is an `epi_archive` object, then:
#' ```
#' epix_slide(x, new_var = comp(old_var), n = 120)
#' epix_slide(x, new_var = comp(old_var), max_version_gap = 120)
#' ```
#' is equivalent to:
#' ```
#' x$slide(x, new_var = comp(old_var), n = 120)
#' x$slide(new_var = comp(old_var), max_version_gap = 120)
#' ```
#'
#' @importFrom rlang enquo
Expand All @@ -437,24 +439,25 @@ epix_merge = function(x, y,
#' # 0 day which has no results, for 2020-06-01
#' # 1 day, for 2020-06-02
#' # 2 days, for the rest of the results
#' # never 3 days dur to data latency
#' # never 3 days due to data latency
#'
#' time_values <- seq(as.Date("2020-06-01"),
#' versions <- seq(as.Date("2020-06-01"),
#' as.Date("2020-06-15"),
#' by = "1 day")
#' epix_slide(x = archive_cases_dv_subset,
#' f = ~ mean(.x$case_rate_7d_av),
#' n = 3,
#' max_version_gap = 3,
#' group_by = geo_value,
#' ref_time_values = time_values,
#' ref_versions = versions,
#' new_col_name = 'case_rate_3d_av')
epix_slide = function(x, f, ..., n, group_by, ref_time_values,
time_step, new_col_name = "slide_value",
epix_slide = function(x, f, ..., max_version_gap, group_by, ref_versions,
time_step, new_col_name = "devslide_value",
as_list_col = FALSE, names_sep = "_", all_rows = FALSE) {
if (!inherits(x, "epi_archive")) Abort("`x` must be of class `epi_archive`.")
return(x$slide(f, ..., n = n,
return(x$slide(f, ...,
max_version_gap = max_version_gap,
group_by = {{group_by}},
ref_time_values = ref_time_values,
ref_versions = ref_versions,
time_step = time_step,
new_col_name = new_col_name,
as_list_col = as_list_col,
Expand Down
4 changes: 2 additions & 2 deletions R/outliers.R
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ detect_outlr_rm = function(x = seq_along(y), y, n = 21,

# Calculate lower and upper thresholds and replacement value
z = z %>%
epi_slide(fitted = median(y), n = n, align = "center") %>%
epi_slide(fitted = median(y), before = floor((n-1)/2), after = ceiling((n-1)/2)) %>%
dplyr::mutate(resid = y - fitted) %>%
roll_iqr(n = n,
detection_multiplier = detection_multiplier,
Expand Down Expand Up @@ -332,7 +332,7 @@ roll_iqr = function(z, n, detection_multiplier, min_radius,
if (typeof(z$y) == "integer") as_type = as.integer
else as_type = as.numeric

epi_slide(z, roll_iqr = stats::IQR(resid), n = n, align = "center") %>%
epi_slide(z, roll_iqr = stats::IQR(resid), before = floor((n-1)/2), after = ceiling((n-1)/2)) %>%
dplyr::mutate(
lower = pmax(min_lower,
fitted - pmax(min_radius, detection_multiplier * roll_iqr)),
Expand Down
119 changes: 66 additions & 53 deletions R/slide.R
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
#'
#' @param x The `epi_df` object under consideration.
#' @param f Function or formula to slide over variables in `x`. To "slide" means
#' to apply a function or formula over a running window of `n` time steps
#' to apply a function or formula over a running window of `before`
#' and `after` time steps
#' (where one time step is typically one day or one week; see details for more
#' explanation). If a function, `f` should take `x`, an `epi_df` with the same
#' names as the non-grouping columns, followed by `g` to refer to the one row
Expand All @@ -19,24 +20,28 @@
#' @param ... Additional arguments to pass to the function or formula specified
#' via `f`. Alternatively, if `f` is missing, then the current argument is
#' interpreted as an expression for tidy evaluation. See details.
#' @param n Number of time steps to use in the running window. For example, if
#' `n = 7`, one time step is one day, and the alignment is "right", then to
#' produce a value on January 7 we apply the given function or formula to data
#' in between January 1 and 7.
#' @param before A nonnegative integer specifying the number of time steps
#' before each of the `ref_time_values` to extract data from.
#' This must be a vector of length 1.
#' Set to 0 for a right-aligned/trailing sliding window, meaning
#' that no
#' `time_value` after the slide will be used for the sliding calculation.
#' It is mandatory to specify a `before` value, unless `after` is specified
#' as a non-zero value. In this case, `before` will be assumed to be 0, as it
#' assumes the user wants to do a left-aligned/leading sliding window.
#' However, this usage is discouraged and will thus produce a warning.
#' @param after A nonnegative integer specifying the number of time steps after
#' each of the `ref_time_values` to extract data from.
#' This must be a vector of length 1. The default value for
#' this is 0. Set to 0 for a left-aligned/leading sliding
#' window, meaning that no
#' `time_value` before the slide will be used for the sliding calculation.
#' To specify this to be centrally aligned, set `before` and `after` to be
#' the same.
#' @param ref_time_values Time values for sliding computations, meaning, each
#' element of this vector serves as the reference time point for one sliding
#' window. If missing, then this will be set to all unique time values in the
#' underlying data table, by default.
#' @param align One of "right", "center", or "left", indicating the alignment of
#' the sliding window relative to the reference time point. If the alignment
#' is "center" and `n` is even, then one more time point will be used after
#' the reference time point than before. Default is "right".
#' @param before Positive integer less than `n`, specifying the number of time
#' points to use in the sliding window strictly before the reference time
#' point. For example, setting `before = n-1` would be the same as setting
#' `align = "right"`. The `before` argument allows for more flexible
#' specification of alignment than the `align` parameter, and if specified,
#' overrides `align`.
#' @param time_step Optional function used to define the meaning of one time
#' step, which if specified, overrides the default choice based on the
#' `time_value` column. This function must take a positive integer and return
Expand All @@ -60,14 +65,15 @@
#' according to the `new_col_name` argument.
#'
#' @details To "slide" means to apply a function or formula over a running
#' window of `n` time steps, where the unit (the meaning of one time step) is
#' window of `before` time steps before and `after` time steps after,
#' where the unit (the meaning of one time step) is
#' implicitly defined by the way the `time_value` column treats addition and
#' subtraction; for example, if the time values are coded as `Date` objects,
#' then one time step is one day, since `as.Date("2022-01-01") + 1` equals
#' `as.Date("2022-01-02")`. Alternatively, the time step can be set explicitly
#' using the `time_step` argument (which if specified would override the
#' default choice based on `time_value` column). If less than `n` time steps
#' are available at any given reference time value, then `epi_slide()` still
#' default choice based on `time_value` column). If certain time steps
#' are unavailable at any given reference time value, then `epi_slide()` still
#' attempts to perform the computation anyway (it does not require a complete
#' window). The issue of what to do with partial computations (those run on
#' incomplete windows) is therefore left up to the user, either through the
Expand All @@ -76,11 +82,11 @@
#' If `f` is missing, then an expression for tidy evaluation can be specified,
#' for example, as in:
#' ```
#' epi_slide(x, cases_7dav = mean(cases), n = 7)
#' epi_slide(x, cases_7dav = mean(cases), before = 6)
#' ```
#' which would be equivalent to:
#' ```
#' epi_slide(x, function(x, ...) mean(x$cases), n = 7,
#' epi_slide(x, function(x, ...) mean(x$cases), before = 6,
#' new_col_name = "cases_7dav")
#' ```
#' Thus, to be clear, when the computation is specified via an expression for
Expand All @@ -95,16 +101,21 @@
#' # slide a 7-day trailing average formula on cases
#' jhu_csse_daily_subset %>%
#' group_by(geo_value) %>%
#' epi_slide(cases_7dav = mean(cases), n = 7,
#' align = "right") %>%
#' epi_slide(cases_7dav = mean(cases), before = 6) %>%
#' # rmv a nonessential var. to ensure new col is printed
#' dplyr::select(-death_rate_7d_av)
#'
#' # slide a left-aligned 7-day average
#' # slide a 7-day leading average
#' jhu_csse_daily_subset %>%
#' group_by(geo_value) %>%
#' epi_slide(cases_7dav = mean(cases), n = 7,
#' align = "left") %>%
#' epi_slide(cases_7dav = mean(cases), before = 0, after = 6) %>%
#' # rmv a nonessential var. to ensure new col is printed
#' dplyr::select(-death_rate_7d_av)
#'
#' # slide a 7-day centre-aligned average
#' jhu_csse_daily_subset %>%
#' group_by(geo_value) %>%
#' epi_slide(cases_7dav = mean(cases), before = 3, after = 3) %>%
#' # rmv a nonessential var. to ensure new col is printed
#' dplyr::select(-death_rate_7d_av)
#'
Expand All @@ -113,11 +124,12 @@
#' group_by(geo_value) %>%
#' epi_slide(a = data.frame(cases_2dav = mean(cases),
#' cases_2dma = mad(cases)),
#' n = 2, as_list_col = TRUE)
epi_slide = function(x, f, ..., n, ref_time_values,
align = c("right", "center", "left"), before, time_step,
#' before = 1, as_list_col = TRUE)
epi_slide = function(x, f, ..., before, after = 0, ref_time_values,
time_step,
new_col_name = "slide_value", as_list_col = FALSE,
names_sep = "_", all_rows = FALSE) {

# Check we have an `epi_df` object
if (!inherits(x, "epi_df")) Abort("`x` must be of class `epi_df`.")

Expand All @@ -133,44 +145,45 @@ epi_slide = function(x, f, ..., n, ref_time_values,
ref_time_values = ref_time_values[ref_time_values %in%
unique(x$time_value)]
}

# If before is missing, then use align to set up alignment

# We must ensure that both before and after are of length 1
if (length(after) != 1L || (!missing(before) && length(before) != 1L)) {
Abort("`before` and `after` must be vectors of length 1.")
}

# Before cannot be missing if after is set to 0. If after is set to a nonzero
# number, then before must be set to 0
if (missing(before)) {
align = match.arg(align)
if (align == "right") {
before_num = n-1
after_num = 0
}
else if (align == "center") {
before_num = floor((n-1)/2)
after_num = ceiling((n-1)/2)
}
else {
before_num = 0
after_num = n-1
if (after == 0) {
Abort("`before` cannot be missing when `after` is set to 0.")
} else {
Warn("`before` missing, `after` nonzero; assuming that left-aligned/leading window is desired and setting `before` = 0.")
before = 0
}
}

if (!(is.numeric(before) && is.numeric(after))||
floor(before) < ceiling(before) ||
floor(after) < ceiling(after)) {
Abort("`before` and `after` must be integers.")
}


# Otherwise set up alignment based on passed before value
else {
if (before < 0 || before > n-1) {
Abort("`before` must be in between 0 and n-1`.")
}

before_num = before
after_num = n-1-before
if (before < 0 || after < 0) {
Abort("`before` and `after` must be at least 0.")
}

# If a custom time step is specified, then redefine units
if (!missing(time_step)) {
before_num = time_step(before_num)
after_num = time_step(after_num)
before = time_step(before)
after = time_step(after)
}

# Now set up starts and stops for sliding/hopping
time_range = range(unique(x$time_value))
starts = in_range(ref_time_values - before_num, time_range)
stops = in_range(ref_time_values + after_num, time_range)
starts = in_range(ref_time_values - before, time_range)
stops = in_range(ref_time_values + after, time_range)

if( length(starts) == 0 || length(stops) == 0 ) {
Abort("The starting and/or stopping times for sliding are out of bounds with respect to the range of times in your data. Check your settings for ref_time_values and align (and before, if specified).")
Expand Down
Loading