1919# ' argument must be named `.x`. A common, though very difficult to debug
2020# ' error is using something like `function(x) mean`. This will not work
2121# ' because it returns the function mean, rather than `mean(x)`
22- # ' @param before,after the size of the sliding window on the left and the right
23- # ' of the center. Usually non-negative integers for data indexed by date, but
24- # ' more restrictive in other cases (see [epiprocess::epi_slide()] for details).
25- # ' @param f_name a character string of at most 20 characters that describes
26- # ' the function. This will be combined with `prefix` and the columns in `...`
27- # ' to name the result using `{prefix}{f_name}_{column}`. By default it will be determined
28- # ' automatically using `clean_f_name()`.
22+ # ' @param .window_size the size of the sliding window, required. Usually a
23+ # ' non-negative integer will suffice (e.g. for data indexed by date, but more
24+ # ' restrictive in other time_type cases (see [epiprocess::epi_slide()] for
25+ # ' details). For example, set to 7 for a 7-day window.
26+ # ' @param .align a character string indicating how the window should be aligned.
27+ # ' By default, this is "right", meaning the slide_window will be anchored with
28+ # ' its right end point on the reference date. (see [epiprocess::epi_slide()]
29+ # ' for details).
30+ # ' @param f_name a character string of at most 20 characters that describes the
31+ # ' function. This will be combined with `prefix` and the columns in `...` to
32+ # ' name the result using `{prefix}{f_name}_{column}`. By default it will be
33+ # ' determined automatically using `clean_f_name()`.
2934# '
3035# ' @template step-return
3136# '
3742# ' rec <- epi_recipe(jhu) %>%
3843# ' step_epi_slide(case_rate, death_rate,
3944# ' .f = \(x) mean(x, na.rm = TRUE),
40- # ' before = 6L
45+ # ' .window_size = 7L
4146# ' )
4247# ' bake(prep(rec, jhu), new_data = NULL)
43- step_epi_slide <-
44- function (recipe ,
45- ... ,
46- .f ,
47- before = 0L ,
48- after = 0L ,
49- role = " predictor" ,
50- prefix = " epi_slide_" ,
51- f_name = clean_f_name(.f ),
52- skip = FALSE ,
53- id = rand_id(" epi_slide" )) {
54- if (! is_epi_recipe(recipe )) {
55- cli_abort(" This recipe step can only operate on an {.cls epi_recipe}." )
56- }
57- .f <- validate_slide_fun(.f )
58- epiprocess ::: validate_slide_window_arg(before , attributes(recipe $ template )$ metadata $ time_type )
59- epiprocess ::: validate_slide_window_arg(after , attributes(recipe $ template )$ metadata $ time_type )
60- arg_is_chr_scalar(role , prefix , id )
61- arg_is_lgl_scalar(skip )
48+ step_epi_slide <- function (recipe ,
49+ ... ,
50+ .f ,
51+ .window_size = NULL ,
52+ .align = c(" right" , " center" , " left" ),
53+ role = " predictor" ,
54+ prefix = " epi_slide_" ,
55+ f_name = clean_f_name(.f ),
56+ skip = FALSE ,
57+ id = rand_id(" epi_slide" )) {
58+ if (! is_epi_recipe(recipe )) {
59+ cli_abort(" This recipe step can only operate on an {.cls epi_recipe}." )
60+ }
61+ .f <- validate_slide_fun(.f )
62+ if (is.null(.window_size )) {
63+ cli_abort(" step_epi_slide: `.window_size` must be specified." )
64+ }
65+ epiprocess ::: validate_slide_window_arg(.window_size , attributes(recipe $ template )$ metadata $ time_type )
66+ arg_is_chr(.align )
67+ .align <- rlang :: arg_match(.align )
68+ arg_is_chr_scalar(role , prefix , id )
69+ arg_is_lgl_scalar(skip )
6270
63- recipes :: add_step(
64- recipe ,
65- step_epi_slide_new(
66- terms = enquos(... ),
67- before = before ,
68- after = after ,
69- .f = .f ,
70- f_name = f_name ,
71- role = role ,
72- trained = FALSE ,
73- prefix = prefix ,
74- keys = key_colnames(recipe ),
75- columns = NULL ,
76- skip = skip ,
77- id = id
78- )
71+ recipes :: add_step(
72+ recipe ,
73+ step_epi_slide_new(
74+ terms = enquos(... ),
75+ .window_size = .window_size ,
76+ .align = .align ,
77+ .f = .f ,
78+ f_name = f_name ,
79+ role = role ,
80+ trained = FALSE ,
81+ prefix = prefix ,
82+ keys = key_colnames(recipe ),
83+ columns = NULL ,
84+ skip = skip ,
85+ id = id
7986 )
80- }
87+ )
88+ }
8189
8290
8391step_epi_slide_new <-
8492 function (terms ,
85- before ,
86- after ,
93+ .window_size ,
94+ .align ,
8795 .f ,
8896 f_name ,
8997 role ,
@@ -96,8 +104,8 @@ step_epi_slide_new <-
96104 recipes :: step(
97105 subclass = " epi_slide" ,
98106 terms = terms ,
99- before = before ,
100- after = after ,
107+ .window_size = .window_size ,
108+ .align = .align ,
101109 .f = .f ,
102110 f_name = f_name ,
103111 role = role ,
@@ -119,8 +127,8 @@ prep.step_epi_slide <- function(x, training, info = NULL, ...) {
119127
120128 step_epi_slide_new(
121129 terms = x $ terms ,
122- before = x $ before ,
123- after = x $ after ,
130+ .window_size = x $ .window_size ,
131+ .align = x $ .align ,
124132 .f = x $ .f ,
125133 f_name = x $ f_name ,
126134 role = x $ role ,
@@ -165,8 +173,8 @@ bake.step_epi_slide <- function(object, new_data, ...) {
165173 # }
166174 epi_slide_wrapper(
167175 new_data ,
168- object $ before ,
169- object $ after ,
176+ object $ .window_size ,
177+ object $ .align ,
170178 object $ columns ,
171179 c(object $ .f ),
172180 object $ f_name ,
@@ -190,7 +198,7 @@ bake.step_epi_slide <- function(object, new_data, ...) {
190198# ' @importFrom dplyr bind_cols group_by ungroup
191199# ' @importFrom epiprocess epi_slide
192200# ' @keywords internal
193- epi_slide_wrapper <- function (new_data , before , after , columns , fns , fn_names , group_keys , name_prefix ) {
201+ epi_slide_wrapper <- function (new_data , .window_size , .align , columns , fns , fn_names , group_keys , name_prefix ) {
194202 cols_fns <- tidyr :: crossing(col_name = columns , fn_name = fn_names , fn = fns )
195203 # Iterate over the rows of cols_fns. For each row number, we will output a
196204 # transformed column. The first result returns all the original columns along
@@ -204,10 +212,10 @@ epi_slide_wrapper <- function(new_data, before, after, columns, fns, fn_names, g
204212 result <- new_data %> %
205213 group_by(across(all_of(group_keys ))) %> %
206214 epi_slide(
207- before = before ,
208- after = after ,
209- new_col_name = result_name ,
210- f = function (slice , geo_key , ref_time_value ) {
215+ .window_size = .window_size ,
216+ .align = .align ,
217+ . new_col_name = result_name ,
218+ . f = function (slice , geo_key , ref_time_value ) {
211219 fn(slice [[col_name ]])
212220 }
213221 ) %> %
0 commit comments