Hop relative to an index
hop_index()
is the lower level engine that powers slide_index()
. It
has slightly different invariants than slide_index()
, and is useful when
you either need to hand craft boundary values, or want to compute a result
with a size that is different from .x
.
hop_index(.x, .i, .starts, .stops, .f, ...) hop_index_vec(.x, .i, .starts, .stops, .f, ..., .ptype = NULL)
.x |
The vector to iterate over and apply |
.i |
The index vector that determines the window sizes. It is fairly common to supply a date vector as the index, but not required. There are 3 restrictions on the index:
|
.starts, .stops |
Vectors of boundary values that make up the windows to bucket |
.f |
If a function, it is used as is. If a formula, e.g.
This syntax allows you to create very compact anonymous functions. |
... |
Additional arguments passed on to the mapped function. |
.ptype |
A prototype corresponding to the type of the output. If If supplied, the result of each call to If |
A vector fulfilling the following invariants:
hop_index()
vec_size(hop_index(.x, .starts, .stops)) == vec_size_common(.starts, .stops)
vec_ptype(hop_index(.x, .starts, .stops)) == list()
hop_index_vec()
vec_size(hop_index_vec(.x, .starts, .stops)) == vec_size_common(.starts, .stops)
vec_size(hop_index_vec(.x, .starts, .stops)[[1]]) == 1L
vec_ptype(hop_index_vec(.x, .starts, .stops, .ptype = ptype)) == ptype
library(vctrs) library(lubridate, warn.conflicts = FALSE) # --------------------------------------------------------------------------- # Returning a size smaller than `.x` i <- as.Date("2019-01-25") + c(0, 1, 2, 3, 10, 20, 35, 42, 45) # slide_index() allows you to slide relative to `i` slide_index(i, i, ~.x, .before = weeks(1)) # But you might be more interested in coarser summaries. This groups # by year-month and computes 2 `.f` on 2 month windows. i_yearmonth <- year(i) + (month(i) - 1) / 12 slide_index(i, i_yearmonth, ~.x, .before = 1) # ^ This works nicely when working with dplyr if you are trying to create # a new column in a data frame, but you'll notice that there are really only # 3 months, so only 3 values are being calculated. If you only want to return # a vector of those 3 values, you can use `hop_index()`. You'll have to # hand craft the boundaries, but this is a general strategy # I've found useful: first_start <- floor_date(i[1], "months") last_stop <- ceiling_date(i[length(i)], "months") dates <- seq(first_start, last_stop, "1 month") inner <- dates[2:(length(dates) - 1L)] starts <- vec_c(first_start, inner) stops <- vec_c(inner - 1, last_stop) hop_index(i, i, starts, stops, ~.x) # --------------------------------------------------------------------------- # Non-existant dates with `lubridate::months()` # Imagine you want to compute a 1 month rolling average on this # irregular daily data. i <- vec_c(as.Date("2019-02-27") + 0:3, as.Date("2019-03-27") + 0:5) x <- rnorm(vec_seq_along(i)) # You might try `slide_index()` like this, but you'd run into this error library(rlang) with_options( catch_cnd( slide_index(x, i, mean, .before = months(1)) ), rlang_backtrace_on_error = current_env() ) # This is because when you actually compute the `.i - .before` sequence, # you hit non-existant dates. i.e. `"2019-03-29" - months(1)` doesn't exist. i - months(1) # To get around this, lubridate provides `add_with_rollback()`, # and the shortcut operation `%m-%`, which subtracts the month, then rolls # forward/backward if it hits an `NA`. You can manually generate boundaries, # then provide them to `hop_index()`. starts <- i %m-% months(1) stops <- i hop_index(x, i, starts, stops, mean) hop_index(i, i, starts, stops, ~.x)
Please choose more modern alternatives, such as Google Chrome or Mozilla Firefox.