This vignette shows how to model time-limited economic closures,
including sequential closures, using the
<daedalus_npi> class.
<daedalus_npi> objects are created using
daedalus_npi(), and the class documentation explains more
about the allowed parameters.
An economic closure or NPI class object is created by passing
arguments to daedalus_npi(). The daedalus model
currently only supports economic closures as part of NPIs, so these
terms are used interchangeably.
The minimum number of arguments required are name,
country, and infection. The openness
coefficient vector, start and end time, and maximum duration are
optional.
The different use cases for each argument are explained below.
Note that the following rules apply to all NPIs:
NPIs are broadly independent of each other, and trigger when their condition is met.
daedalus::events::response) check for whether they would be
redundant, i.e., whether they would actually make a change to the NPI
flag. So events that would switch the flag to on do not
occur if they flag is already on (the same applies to
off). This allows accurate calculation of the duration for
which an NPI has been active.The country argument controls the hospital capacity,
the breaching of which triggers the NPI. This trigger overrides the
start time trigger, so a NPI may trigger earlier than expected.
The infection argument allows the NPI to end when
the epidemic stops growing. This trigger overrides the end time trigger,
so an NPI may end sooner than expected.
All NPIs end after a maximum default duration of 365 days. This
can be changed using the max_duration argument. This
argument overrides the end_time argument: if the NPI
end_time is specified as more than
max_duration days after the start_time,
the response will end at start_time + max_duration,
not at end_time.
max_duration, and then to end on end_time if
it has been relaunched at a time-point in between. We advise users to
await further developments in which state-dependent and time-dependent
NPIs are separated.Public-concern social distancing, when set to be NPI-linked, follows the rules for NPI launching and ending laid out above.
When a response is activated upon hitting its start time, the same response will not be logged as activating due to the hospital capacity trigger, even if that condition is met, as long as the response is active (that is, model time \(<\) end time, or epidemic is still growing).
When a response ends due to time conditions being met, it may launch again if the hospital capacity condition is met. Future versions of daedalus may allow this to be prevented.
A time-limited economic closure or NPI is created by passing values
to the start_time and end_time arguments of
daedalus_npi().
For instance, to specify school closures for the U.K. that are active between days 30 and 90 after a pandemic use this code.
npi <- daedalus_npi(
"school_closures", "GBR", "sars_cov_1",
start_time = 30, end_time = 90
)
# see NPI information
npi
#> <daedalus_npi/daedalus_response>
#> NPI strategy: school_closures
#> • Start time (days): 30
#> • End time (days): 90
#> • Openness (mean prop.): 0.93
#> • Maximum duration (days): 365
# run a scenario with the npi
daedalus(
"GBR", "sars_cov_1", npi,
time_end = 100
)
#> <daedalus_output>
#> • Country: United Kingdom
#> • Epidemic: sars_cov_1
#> • NPI response: school_closures
#> • Vaccination: no vaccination
#> • Behaviour: no behaviourCreating a time-limited NPI with a single active duration using
daedalus_npi() requires:
Passing NA as the name rather than one
of the pre-canned NPI strategies found in
daedalus.data::closure_strategy_data, and
Passing a numeric \(M \times N\)
matrix, with $M = $ number of age-and-economic strata (49), and $N = $
number of contact settings (2 by default) to the openness
argument.
A country and infection are still required as before.
All other rules and requirements are the same as for a pre-canned response; the pre-canned element is the openness coefficients.
Passing a bespoke NPI to [daedalus()] leads to the resulting
<daedalus_output> object identifying the
response_strategy as "custom".
See the next section for how to specify time-limited NPIs that are active over multiple intervals.
openness <- cbind(
rep(1, 49),
rep(0.3, 49)
)
npi <- daedalus_npi(
NA, "GBR", "sars_cov_1",
openness,
30, 90
)
# see NPI information
npi
#> <daedalus_npi/daedalus_response>
#> NPI strategy: custom
#> • Start time (days): 30
#> • End time (days): 90
#> • Openness (mean prop.): 0.3
#> • Maximum duration (days): 365
# run a scenario with the npi
daedalus(
"GBR", "sars_cov_1", npi,
time_end = 100
)
#> <daedalus_output>
#> • Country: United Kingdom
#> • Epidemic: sars_cov_1
#> • NPI response: custom
#> • Vaccination: no vaccination
#> • Behaviour: no behaviourA time-limited response can be set to trigger and end at multiple time points. This is of most use in real-time pandemic response use-cases where users are seeking to model policy-makers’ options or decisions about imposing and lifting restrictions.
daedalus offers the daedalus_timed_npi()
function to specify time-limited NPIs that are not responsive to model
state, and which allow multiple closure periods.
daedalus_timed_npi() also allows specifying a different
openness coefficient vector (i.e., stringency of economic closures) for
each closure period, which allows responses to be ramped up and down —
an expected use-case in real-time modelling.
Repeated time-limited NPIs are created by passing vectors to
start_time and end_time in
daedalus_timed_npi(). The \(i\)-th element of each vector gives the
start and end time of a each closure period.
Note that:
daedalus_timed_npi() creates a
<daedalus_npi> object, just with different event
triggers;
These objects do not trigger or end on model state;
These objects do not specify a maximum closure duration, but do require all closure periods to be time-limited;
All closure periods must be non-overlapping, so only one closure regime can be active at any time;
Sequential time-limited responses cannot be created by tweaking
pre-canned responses, but the openness coefficients may be used by
accessing them manually from
daedalus.data::closure_strategy_data.
The example below show ramping responses up and down by switching from school closures to an elimination strategy and back again.
school_closures <- daedalus.data::closure_strategy_data[["school_closures"]]
elimination <- daedalus.data::closure_strategy_data[["elimination"]]
school_closures <- cbind(
rep(1, 49),
c(rep(1, 4), school_closures)
)
elimination <- cbind(
rep(1, 49),
c(rep(1, 4), elimination)
)
# start at day 30, 60, 90, 30 days each
npi <- daedalus_timed_npi(
start_time = c(30, 60, 90),
end_time = c(59, 89, 120),
openness = list(
school_closures, elimination, school_closures
),
"GBR"
)
# see NPI information
npi
#> <daedalus_npi/daedalus_response>
#> NPI strategy: custom_timed
#> • Start time (days): 30, 60, and 90
#> • End time (days): 59, 89, and 120
#> • Openness (mean prop.): 0.93, 0.713, and 0.93
#> • Maximum duration (days): NA
# run a scenario with the npi
output <- daedalus(
"GBR", "sars_cov_1", npi,
time_end = 150
)
# examine event times
output$response_data$npi_info
#> $npi_times_start
#> [1] 30 60 90
#>
#> $npi_times_end
#> [1] 59 89 120
#>
#> $npi_durations
#> [1] 29 29 30
#>
#> $npi_periods
#> [1] 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
#> [20] 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
#> [39] 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
#> [58] 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
#> [77] 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120