@@ -452,7 +452,7 @@ epi_archive =
452
452
# ' @description Generates a snapshot in `epi_df` format as of a given version.
453
453
# ' See the documentation for the wrapper function [`epix_as_of()`] for details.
454
454
# ' @importFrom data.table between key
455
- as_of = function (max_version , min_time_value = - Inf ) {
455
+ as_of = function (max_version , min_time_value = - Inf , all_versions = FALSE ) {
456
456
# Self max version and other keys
457
457
other_keys = setdiff(key(self $ DT ),
458
458
c(" geo_value" , " time_value" , " version" ))
@@ -472,12 +472,23 @@ epi_archive =
472
472
if (max_version > self $ versions_end ) {
473
473
Abort(" `max_version` must be at most `self$versions_end`." )
474
474
}
475
+ if (! rlang :: is_bool(all_versions )) {
476
+ Abort(" `all_versions` must be TRUE or FALSE." )
477
+ }
475
478
if (! is.na(self $ clobberable_versions_start ) && max_version > = self $ clobberable_versions_start ) {
476
479
Warn(' Getting data as of some recent version which could still be overwritten (under routine circumstances) without assigning a new version number (a.k.a. "clobbered"). Thus, the snapshot that we produce here should not be expected to be reproducible later. See `?epi_archive` for more info and `?epix_as_of` on how to muffle.' ,
477
480
class = " epiprocess__snapshot_as_of_clobberable_version" )
478
481
}
479
482
480
483
# Filter by version and return
484
+ if (all_versions ) {
485
+ result = epix_truncate_versions_after(self , max_version )
486
+ # `self` has already been `clone`d in `epix_truncate_versions_after`
487
+ # so we can modify the new archive's DT directly.
488
+ result $ DT = result $ DT [time_value > = min_time_value , ]
489
+ return (result )
490
+ }
491
+
481
492
return (
482
493
# Make sure to use data.table ways of filtering and selecting
483
494
self $ DT [time_value > = min_time_value &
@@ -559,6 +570,38 @@ epi_archive =
559
570
return (invisible (self ))
560
571
},
561
572
# ####
573
+ # ' @description Filter to keep only older versions, mutating the archive by
574
+ # ' potentially reseating but not mutating some fields. `DT` is likely, but not
575
+ # ' guaranteed, to be copied. Returns the mutated archive
576
+ # ' [invisibly][base::invisible].
577
+ # ' @param x as in [`epix_truncate_versions_after`]
578
+ # ' @param max_version as in [`epix_truncate_versions_after`]
579
+ truncate_versions_after = function (max_version ) {
580
+ if (length(max_version ) != 1 ) {
581
+ Abort(" `max_version` cannot be a vector." )
582
+ }
583
+ if (is.na(max_version )) {
584
+ Abort(" `max_version` must not be NA." )
585
+ }
586
+ if (! identical(class(max_version ), class(self $ DT $ version )) ||
587
+ ! identical(typeof(max_version ), typeof(self $ DT $ version ))) {
588
+ Abort(" `max_version` and `DT$version` must have same `class` and `typeof`." )
589
+ }
590
+ if (max_version > self $ versions_end ) {
591
+ Abort(" `max_version` must be at most `self$versions_end`." )
592
+ }
593
+ self $ DT <- self $ DT [self $ DT $ version < = max_version , colnames(self $ DT ), with = FALSE ]
594
+ # (^ this filter operation seems to always copy the DT, even if it
595
+ # keeps every entry; we don't guarantee this behavior in
596
+ # documentation, though, so we could change to alias in this case)
597
+ if (! is.na(self $ clobberable_versions_start ) &&
598
+ self $ clobberable_versions_start > max_version ) {
599
+ self $ clobberable_versions_start <- NA
600
+ }
601
+ self $ versions_end <- max_version
602
+ return (invisible (self ))
603
+ },
604
+ # ####
562
605
# ' @description Merges another `epi_archive` with the current one, mutating the
563
606
# ' current one by reseating its `DT` and several other fields, but avoiding
564
607
# ' mutation of the old `DT`; returns the current archive
@@ -597,7 +640,7 @@ epi_archive =
597
640
slide = function (f , ... , before , ref_time_values ,
598
641
time_step , new_col_name = " slide_value" ,
599
642
as_list_col = FALSE , names_sep = " _" ,
600
- all_rows = FALSE ) {
643
+ all_rows = FALSE , all_versions = FALSE ) {
601
644
# For an "ungrouped" slide, treat all rows as belonging to one big
602
645
# group (group by 0 vars), like `dplyr::summarize`, and let the
603
646
# resulting `grouped_epi_archive` handle the slide:
@@ -606,7 +649,7 @@ epi_archive =
606
649
before = before , ref_time_values = ref_time_values ,
607
650
time_step = time_step , new_col_name = new_col_name ,
608
651
as_list_col = as_list_col , names_sep = names_sep ,
609
- all_rows = all_rows
652
+ all_rows = all_rows , all_versions = all_versions
610
653
) %> %
611
654
# We want a slide on ungrouped archives to output something
612
655
# ungrouped, rather than retaining the trivial (0-variable)
0 commit comments