5858# ' epix_as_of(archive_cases_dv_subset2, max(archive_cases_dv_subset$DT$version))
5959# '
6060# ' @importFrom data.table between key
61+ # ' @importFrom checkmate assert_scalar assert_logical assert_class
6162# ' @export
6263epix_as_of <- function (x , version , min_time_value = - Inf , all_versions = FALSE ,
6364 max_version = deprecated()) {
@@ -88,6 +89,14 @@ epix_as_of <- function(x, version, min_time_value = -Inf, all_versions = FALSE,
8889 if (version > x $ versions_end ) {
8990 cli_abort(" `version` must be at most `epi_archive$versions_end`." )
9091 }
92+ assert_scalar(min_time_value , na.ok = FALSE )
93+ min_time_value_inf <- is.infinite(min_time_value ) && min_time_value < 0
94+ min_time_value_same_type <- typeof(min_time_value ) == typeof(x $ DT $ time_value ) &
95+ class(min_time_value ) == class(x $ DT $ time_value )
96+ if (! min_time_value_inf && ! min_time_value_same_type ) {
97+ cli_abort(" `min_time_value` must be either -Inf or a time_value of the same type and
98+ class as `epi_archive$time_value`." )
99+ }
91100 assert_logical(all_versions , len = 1 )
92101 if (! is.na(x $ clobberable_versions_start ) && version > = x $ clobberable_versions_start ) {
93102 cli_warn(
@@ -100,39 +109,63 @@ epix_as_of <- function(x, version, min_time_value = -Inf, all_versions = FALSE,
100109 )
101110 }
102111
103- # We can't disable nonstandard evaluation nor use the `..` feature in the `i`
104- # argument of `[.data.table` below; try to avoid problematic names and abort
105- # if we fail to do so:
106- .min_time_value <- min_time_value
107- .version <- version
108- if (any(c(" .min_time_value" , " .version" ) %in% names(x $ DT ))) {
109- cli_abort(" epi_archives can't contain a `.min_time_value` or `.version` column" )
110- }
111-
112112 # Filter by version and return
113113 if (all_versions ) {
114114 # epi_archive is copied into result, so we can modify result directly
115115 result <- epix_truncate_versions_after(x , version )
116- result $ DT <- result $ DT [time_value > = .min_time_value , ] # nolint: object_usage_linter
116+ if (! min_time_value_inf ) {
117+ # See below for why we need this branch.
118+ filter_mask <- result $ DT $ time_value > = min_time_value
119+ result $ DT <- result $ DT [filter_mask , ] # nolint: object_usage_linter
120+ }
117121 return (result )
118122 }
119123
120124 # Make sure to use data.table ways of filtering and selecting
121- as_of_epi_df <- x $ DT [time_value > = .min_time_value & version < = .version , ] %> % # nolint: object_usage_linter
122- unique(
123- by = c(" geo_value" , " time_value" , other_keys ),
124- fromLast = TRUE
125- ) %> %
125+ if (min_time_value_inf ) {
126+ # This branch is needed for `epix_as_of` to work with `yearmonth` time type
127+ # to avoid time_value > .min_time_value, which is NA for `yearmonth`.
128+ filter_mask <- x $ DT $ version < = version
129+ } else {
130+ filter_mask <- x $ DT $ time_value > = min_time_value & x $ DT $ version < = version
131+ }
132+ as_of_epi_df <- x $ DT [filter_mask , ] %> %
133+ unique(by = c(" geo_value" , " time_value" , other_keys ), fromLast = TRUE ) %> %
134+ as.data.frame() %> %
126135 tibble :: as_tibble() %> %
127136 dplyr :: select(- " version" ) %> %
128- as_epi_df(
129- as_of = version ,
130- other_keys = other_keys
131- )
137+ as_epi_df(as_of = version , other_keys = other_keys )
132138
133139 return (as_of_epi_df )
134140}
135141
142+ # ' Get the latest snapshot from an `epi_archive` object.
143+ # '
144+ # ' The latest snapshot is the snapshot of the last known version.
145+ # '
146+ # ' @param x An `epi_archive` object
147+ # ' @return The latest snapshot from an `epi_archive` object
148+ # ' @export
149+ epix_as_of_current <- function (x ) {
150+ assert_class(x , " epi_archive" )
151+ x %> % epix_as_of(. $ versions_end )
152+ }
153+
154+ # ' Set the `versions_end` attribute of an `epi_archive` object
155+ # '
156+ # ' An escape hatch for epix_as_of, which does not allow version >
157+ # ' `$versions_end`.
158+ # '
159+ # ' @param x An `epi_archive` object
160+ # ' @param versions_end The new `versions_end` value
161+ # ' @return An `epi_archive` object with the updated `versions_end` attribute
162+ # ' @export
163+ set_versions_end <- function (x , versions_end ) {
164+ assert_class(x , " epi_archive" )
165+ validate_version_bound(versions_end , x $ DT , na_ok = FALSE )
166+ x $ versions_end <- versions_end
167+ x
168+ }
136169
137170# ' Fill `epi_archive` unobserved history
138171# '
@@ -880,10 +913,13 @@ epix_slide.epi_archive <- function(
880913# ' @noRd
881914epix_slide_versions_default <- function (ea ) {
882915 versions_with_updates <- c(ea $ DT $ version , ea $ versions_end )
883- tidyr :: full_seq(versions_with_updates , guess_period(versions_with_updates ))
916+ if (ea $ time_type == " yearmonth" ) {
917+ min(versions_with_updates ) + seq(0 , max(versions_with_updates ) - min(versions_with_updates ), by = 1 )
918+ } else {
919+ tidyr :: full_seq(versions_with_updates , guess_period(versions_with_updates ))
920+ }
884921}
885922
886-
887923# ' Filter an `epi_archive` object to keep only older versions
888924# '
889925# ' Generates a filtered `epi_archive` from an `epi_archive` object, keeping
0 commit comments