Skip to content

Commit 2597b90

Browse files
committed
Template for new lag function.
1 parent 05e688f commit 2597b90

File tree

1 file changed

+123
-0
lines changed

1 file changed

+123
-0
lines changed

R/epi_lag2.R

Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
#' Create a lagged predictor
2+
#'
3+
#' `step_epi_lag` creates a *specification* of a recipe step that
4+
#' will add new columns of lagged data. Lagged data will
5+
#' by default include NA values where the lag was induced.
6+
#' These can be removed with [step_naomit()], or you may
7+
#' specify an alternative filler value with the `default`
8+
#' argument.
9+
#'
10+
#' @param lag A vector of positive integers. Each specified column will be
11+
#' lagged for each value in the vector.
12+
#' @template step-return
13+
#'
14+
#' @details The step assumes that the data are already _in the proper sequential
15+
#' order_ for lagging.
16+
#'
17+
#' @family row operation steps
18+
#' @export
19+
#' @rdname step_epi_ahead
20+
step_epi_lag2 <-
21+
function(recipe,
22+
...,
23+
role = "predictor",
24+
trained = FALSE,
25+
lag = 1,
26+
prefix = "lag_",
27+
default = NA,
28+
keys = epi_keys(recipe),
29+
columns = NULL,
30+
skip = FALSE,
31+
id = rand_id("epi_lag")) {
32+
add_step(
33+
recipe,
34+
step_epi_lag_new(
35+
terms = dplyr::enquos(...),
36+
role = role,
37+
trained = trained,
38+
lag = lag,
39+
prefix = prefix,
40+
default = default,
41+
keys = keys,
42+
columns = columns,
43+
skip = skip,
44+
id = id
45+
)
46+
)
47+
}
48+
49+
step_epi_lag2_new <-
50+
function(terms, role, trained, lag, prefix, default, keys,
51+
columns, skip, id) {
52+
step(
53+
subclass = "epi_lag",
54+
terms = terms,
55+
role = role,
56+
trained = trained,
57+
lag = lag,
58+
prefix = prefix,
59+
default = default,
60+
keys = keys,
61+
columns = columns,
62+
skip = skip,
63+
id = id
64+
)
65+
}
66+
67+
#' @export
68+
prep.step_epi_lag2 <- function(x, training, info = NULL, ...) {
69+
step_epi_lag_new(
70+
terms = x$terms,
71+
role = x$role,
72+
trained = TRUE,
73+
lag = x$lag,
74+
prefix = x$prefix,
75+
default = x$default,
76+
keys = x$keys,
77+
columns = recipes_eval_select(x$terms, training, info),
78+
skip = x$skip,
79+
id = x$id
80+
)
81+
}
82+
83+
#' @export
84+
bake.step_epi_lag2 <- function(object, new_data, ...) {
85+
if (!all(object$lag == as.integer(object$lag))) {
86+
rlang::abort("step_epi_lag requires 'lag' argument to be integer valued.")
87+
}
88+
89+
grid <- tidyr::expand_grid(col = object$columns, lag_val = object$lag) %>%
90+
dplyr::mutate(newname = glue::glue("{object$prefix}{lag_val}_{col}"))
91+
92+
## ensure no name clashes
93+
new_data_names <- colnames(new_data)
94+
intersection <- new_data_names %in% grid$newname
95+
if (any(intersection)) {
96+
rlang::abort(
97+
paste0("Name collision occured in `", class(object)[1],
98+
"`. The following variable names already exists: ",
99+
paste0(new_data_names[intersection], collapse = ", "),
100+
"."))
101+
}
102+
ok <- object$keys
103+
lagged <- purrr::reduce(
104+
purrr::pmap(grid, epi_shift_single, x = new_data, key_cols = ok),
105+
dplyr::full_join,
106+
by = ok
107+
)
108+
109+
dplyr::full_join(new_data, lagged, by = ok) %>%
110+
dplyr::group_by(dplyr::across(dplyr::all_of(ok[-1]))) %>%
111+
dplyr::arrange(time_value) %>%
112+
dplyr::ungroup()
113+
114+
}
115+
116+
#' @export
117+
print.step_epi_lag2 <-
118+
function(x, width = max(20, options()$width - 30), ...) {
119+
## TODO add printing of the lags
120+
title <- "Lagging "
121+
recipes::print_step(x$columns, x$terms, x$trained, title, width)
122+
invisible(x)
123+
}

0 commit comments

Comments
 (0)