19
19
# ' argument must be named `.x`. A common, though very difficult to debug
20
20
# ' error is using something like `function(x) mean`. This will not work
21
21
# ' 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()`.
29
34
# '
30
35
# ' @template step-return
31
36
# '
37
42
# ' rec <- epi_recipe(jhu) %>%
38
43
# ' step_epi_slide(case_rate, death_rate,
39
44
# ' .f = \(x) mean(x, na.rm = TRUE),
40
- # ' before = 6L
45
+ # ' .window_size = 7L
41
46
# ' )
42
47
# ' 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 )
62
70
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
79
86
)
80
- }
87
+ )
88
+ }
81
89
82
90
83
91
step_epi_slide_new <-
84
92
function (terms ,
85
- before ,
86
- after ,
93
+ .window_size ,
94
+ .align ,
87
95
.f ,
88
96
f_name ,
89
97
role ,
@@ -96,8 +104,8 @@ step_epi_slide_new <-
96
104
recipes :: step(
97
105
subclass = " epi_slide" ,
98
106
terms = terms ,
99
- before = before ,
100
- after = after ,
107
+ .window_size = .window_size ,
108
+ .align = .align ,
101
109
.f = .f ,
102
110
f_name = f_name ,
103
111
role = role ,
@@ -119,8 +127,8 @@ prep.step_epi_slide <- function(x, training, info = NULL, ...) {
119
127
120
128
step_epi_slide_new(
121
129
terms = x $ terms ,
122
- before = x $ before ,
123
- after = x $ after ,
130
+ .window_size = x $ .window_size ,
131
+ .align = x $ .align ,
124
132
.f = x $ .f ,
125
133
f_name = x $ f_name ,
126
134
role = x $ role ,
@@ -165,8 +173,8 @@ bake.step_epi_slide <- function(object, new_data, ...) {
165
173
# }
166
174
epi_slide_wrapper(
167
175
new_data ,
168
- object $ before ,
169
- object $ after ,
176
+ object $ .window_size ,
177
+ object $ .align ,
170
178
object $ columns ,
171
179
c(object $ .f ),
172
180
object $ f_name ,
@@ -190,7 +198,7 @@ bake.step_epi_slide <- function(object, new_data, ...) {
190
198
# ' @importFrom dplyr bind_cols group_by ungroup
191
199
# ' @importFrom epiprocess epi_slide
192
200
# ' @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 ) {
194
202
cols_fns <- tidyr :: crossing(col_name = columns , fn_name = fn_names , fn = fns )
195
203
# Iterate over the rows of cols_fns. For each row number, we will output a
196
204
# 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
204
212
result <- new_data %> %
205
213
group_by(across(all_of(group_keys ))) %> %
206
214
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 ) {
211
219
fn(slice [[col_name ]])
212
220
}
213
221
) %> %
0 commit comments