@@ -230,37 +230,15 @@ epi_slide <- function(x, f, ..., before, after, ref_time_values,
230
230
after <- time_step(after )
231
231
}
232
232
233
+ # Do set up to let us recover `ref_time_value`s later.
233
234
min_ref_time_values <- ref_time_values - before
234
235
min_ref_time_values_not_in_x <- min_ref_time_values [! (min_ref_time_values %in% unique(x $ time_value ))]
235
236
236
- # Do set up to let us recover `ref_time_value`s later.
237
- # A helper column marking real observations.
238
- x $ .real <- TRUE
239
-
240
- # Create df containing phony data. Df has the same columns and attributes as
241
- # `x`, but filled with `NA`s aside from grouping columns. Number of rows is
242
- # equal to the number of `min_ref_time_values_not_in_x` we have * the
243
- # number of unique levels seen in the grouping columns.
244
- before_time_values_df <- data.frame (time_value = min_ref_time_values_not_in_x )
245
- if (length(group_vars(x )) != 0 ) {
246
- before_time_values_df <- dplyr :: cross_join(
247
- # Get unique combinations of grouping columns seen in real data.
248
- unique(x [, group_vars(x )]),
249
- before_time_values_df
250
- )
251
- }
252
- # Automatically fill in all other columns from `x` with `NA`s, and carry
253
- # attributes over to new df.
254
- before_time_values_df <- bind_rows(x [0 , ], before_time_values_df )
255
- before_time_values_df $ .real <- FALSE
256
-
257
- x <- bind_rows(before_time_values_df , x )
258
-
259
237
# Arrange by increasing time_value
260
238
x <- arrange(x , time_value )
261
239
262
240
# Now set up starts and stops for sliding/hopping
263
- time_range <- range(unique(x $ time_value ))
241
+ time_range <- range(unique(c( x $ time_value , min_ref_time_values_not_in_x ) ))
264
242
starts <- in_range(ref_time_values - before , time_range )
265
243
stops <- in_range(ref_time_values + after , time_range )
266
244
@@ -273,7 +251,7 @@ epi_slide <- function(x, f, ..., before, after, ref_time_values,
273
251
274
252
# Computation for one group, all time values
275
253
slide_one_grp <- function (.data_group ,
276
- f , ... ,
254
+ f_factory , ... ,
277
255
starts ,
278
256
stops ,
279
257
time_values ,
@@ -288,6 +266,8 @@ epi_slide <- function(x, f, ..., before, after, ref_time_values,
288
266
stops <- stops [o ]
289
267
time_values <- time_values [o ]
290
268
269
+ f <- f_factory(starts )
270
+
291
271
# Compute the slide values
292
272
slide_values_list <- slider :: hop_index(
293
273
.x = .data_group ,
@@ -349,7 +329,6 @@ epi_slide <- function(x, f, ..., before, after, ref_time_values,
349
329
# fills with NA equivalent.
350
330
vctrs :: vec_slice(slide_values , o ) <- orig_values
351
331
} else {
352
- # This implicitly removes phony (`.real` == FALSE) observations.
353
332
.data_group <- filter(.data_group , o )
354
333
}
355
334
return (mutate(.data_group , !! new_col : = slide_values ))
@@ -372,15 +351,20 @@ epi_slide <- function(x, f, ..., before, after, ref_time_values,
372
351
373
352
f <- as_slide_computation(f , ... )
374
353
# Create a wrapper that calculates and passes `.ref_time_value` to the
375
- # computation.
376
- f_wrapper <- function (.x , .group_key , ... ) {
377
- .ref_time_value <- min(.x $ time_value ) + before
378
- .x <- .x [.x $ .real , ]
379
- .x $ .real <- NULL
380
- f(.x , .group_key , .ref_time_value , ... )
354
+ # computation. `i` is contained in the `f_wrapper_factory` environment such
355
+ # that when called within `slide_one_grp` `i` is reset for every group.
356
+ f_wrapper_factory <- function (starts ) {
357
+ # Use `i` to advance through list of start dates.
358
+ i <- 1L
359
+ f_wrapper <- function (.x , .group_key , ... ) {
360
+ .ref_time_value <- starts [[i ]] + before
361
+ i <<- i + 1L
362
+ f(.x , .group_key , .ref_time_value , ... )
363
+ }
364
+ return (f_wrapper )
381
365
}
382
366
x <- group_modify(x , slide_one_grp ,
383
- f = f_wrapper , ... ,
367
+ f_factory = f_wrapper_factory , ... ,
384
368
starts = starts ,
385
369
stops = stops ,
386
370
time_values = ref_time_values ,
@@ -394,14 +378,5 @@ epi_slide <- function(x, f, ..., before, after, ref_time_values,
394
378
x <- unnest(x , !! new_col , names_sep = names_sep )
395
379
}
396
380
397
- # Remove any remaining phony observations. When `all_rows` is TRUE, phony
398
- # observations aren't necessarily removed in `slide_one_grp`.
399
- if (all_rows ) {
400
- x <- x [x $ .real , ]
401
- }
402
-
403
- # Drop helper column `.real`.
404
- x $ .real <- NULL
405
-
406
381
return (x )
407
382
}
0 commit comments