58
58
# ' epix_as_of(archive_cases_dv_subset2, max(archive_cases_dv_subset$DT$version))
59
59
# '
60
60
# ' @importFrom data.table between key
61
+ # ' @importFrom checkmate assert_scalar assert_logical assert_class
61
62
# ' @export
62
63
epix_as_of <- function (x , version , min_time_value = - Inf , all_versions = FALSE ,
63
64
max_version = deprecated()) {
@@ -88,6 +89,14 @@ epix_as_of <- function(x, version, min_time_value = -Inf, all_versions = FALSE,
88
89
if (version > x $ versions_end ) {
89
90
cli_abort(" `version` must be at most `epi_archive$versions_end`." )
90
91
}
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
+ }
91
100
assert_logical(all_versions , len = 1 )
92
101
if (! is.na(x $ clobberable_versions_start ) && version > = x $ clobberable_versions_start ) {
93
102
cli_warn(
@@ -100,39 +109,63 @@ epix_as_of <- function(x, version, min_time_value = -Inf, all_versions = FALSE,
100
109
)
101
110
}
102
111
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
-
112
112
# Filter by version and return
113
113
if (all_versions ) {
114
114
# epi_archive is copied into result, so we can modify result directly
115
115
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
+ }
117
121
return (result )
118
122
}
119
123
120
124
# 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() %> %
126
135
tibble :: as_tibble() %> %
127
136
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 )
132
138
133
139
return (as_of_epi_df )
134
140
}
135
141
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
+ }
136
169
137
170
# ' Fill `epi_archive` unobserved history
138
171
# '
@@ -880,10 +913,13 @@ epix_slide.epi_archive <- function(
880
913
# ' @noRd
881
914
epix_slide_versions_default <- function (ea ) {
882
915
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
+ }
884
921
}
885
922
886
-
887
923
# ' Filter an `epi_archive` object to keep only older versions
888
924
# '
889
925
# ' Generates a filtered `epi_archive` from an `epi_archive` object, keeping
0 commit comments