Explore scenarios using gridding with sampling for parameters not in the grid. Parameters that are included in the grid are currently hard coded. Use the future package to control parallisation outside of the function.

parameter_sweep(scenarios, sim_fn, samples = 1)

Arguments

scenarios

a data.frame: containing all gridded scenarios - see the examples for the required structure.

sim_fn

a function: The vectorised model simulation function - see the examples for usage.

samples

a positive integer scalar: the number of samples to take. Defaults to 1.

Value

A nested data.table containing the parameters for each scenario and a nested list of output from scenario_sim().

Examples

library(data.table)
# Put parameters that are grouped by disease into this data.table
scenarios <- data.table(
  expand.grid(
    delay_group = list(data.table(
      delay = c("SARS", "Wuhan"),
      onset_to_isolation = c(
        \(x) rweibull(n = x, shape = 1.651524, scale = 4.287786),
        \(x) rweibull(n = x, shape = 2.305172, scale = 9.483875)
      )
    )),
    r0_community = c(1.1, 1.5),
    prop_presymptomatic = c(0.01, 0.15),
    prop_asymptomatic = c(0, 0.1),
    prop_ascertain = seq(0, 1, 0.25),
    initial_cases = c(5, 10),
    quarantine = FALSE
  )
)

list_cols <- grep("_group", colnames(scenarios), value = TRUE)
non_list_cols <- setdiff(colnames(scenarios), list_cols)

scenarios <- scenarios[, rbindlist(delay_group), by = c(non_list_cols)]
scenarios[, scenario :=  1:.N]
#>      r0_community prop_presymptomatic prop_asymptomatic prop_ascertain
#>             <num>               <num>             <num>          <num>
#>   1:          1.1                0.01               0.0              0
#>   2:          1.1                0.01               0.0              0
#>   3:          1.5                0.01               0.0              0
#>   4:          1.5                0.01               0.0              0
#>   5:          1.1                0.15               0.0              0
#>  ---                                                                  
#> 156:          1.5                0.01               0.1              1
#> 157:          1.1                0.15               0.1              1
#> 158:          1.1                0.15               0.1              1
#> 159:          1.5                0.15               0.1              1
#> 160:          1.5                0.15               0.1              1
#>      initial_cases quarantine  delay onset_to_isolation scenario
#>              <num>     <lgcl> <char>             <list>    <int>
#>   1:             5      FALSE   SARS      <function[1]>        1
#>   2:             5      FALSE  Wuhan      <function[1]>        2
#>   3:             5      FALSE   SARS      <function[1]>        3
#>   4:             5      FALSE  Wuhan      <function[1]>        4
#>   5:             5      FALSE   SARS      <function[1]>        5
#>  ---                                                            
#> 156:            10      FALSE  Wuhan      <function[1]>      156
#> 157:            10      FALSE   SARS      <function[1]>      157
#> 158:            10      FALSE  Wuhan      <function[1]>      158
#> 159:            10      FALSE   SARS      <function[1]>      159
#> 160:            10      FALSE  Wuhan      <function[1]>      160

incub <- \(x) rweibull(n = x, shape = 1.65, scale = 4.28)
scenarios[, incubation_period := rep(list(incub), .N)]
#>      r0_community prop_presymptomatic prop_asymptomatic prop_ascertain
#>             <num>               <num>             <num>          <num>
#>   1:          1.1                0.01               0.0              0
#>   2:          1.1                0.01               0.0              0
#>   3:          1.5                0.01               0.0              0
#>   4:          1.5                0.01               0.0              0
#>   5:          1.1                0.15               0.0              0
#>  ---                                                                  
#> 156:          1.5                0.01               0.1              1
#> 157:          1.1                0.15               0.1              1
#> 158:          1.1                0.15               0.1              1
#> 159:          1.5                0.15               0.1              1
#> 160:          1.5                0.15               0.1              1
#>      initial_cases quarantine  delay onset_to_isolation scenario
#>              <num>     <lgcl> <char>             <list>    <int>
#>   1:             5      FALSE   SARS      <function[1]>        1
#>   2:             5      FALSE  Wuhan      <function[1]>        2
#>   3:             5      FALSE   SARS      <function[1]>        3
#>   4:             5      FALSE  Wuhan      <function[1]>        4
#>   5:             5      FALSE   SARS      <function[1]>        5
#>  ---                                                            
#> 156:            10      FALSE  Wuhan      <function[1]>      156
#> 157:            10      FALSE   SARS      <function[1]>      157
#> 158:            10      FALSE  Wuhan      <function[1]>      158
#> 159:            10      FALSE   SARS      <function[1]>      159
#> 160:            10      FALSE  Wuhan      <function[1]>      160
#>      incubation_period
#>                 <list>
#>   1:     <function[1]>
#>   2:     <function[1]>
#>   3:     <function[1]>
#>   4:     <function[1]>
#>   5:     <function[1]>
#>  ---                  
#> 156:     <function[1]>
#> 157:     <function[1]>
#> 158:     <function[1]>
#> 159:     <function[1]>
#> 160:     <function[1]>

## Parameterise fixed paramters
sim_with_params <- purrr::partial(
  ringbp::scenario_sim,
  cap_max_days = 365,
  cap_cases = 5000,
  r0_isolated = 0,
  disp_isolated = 1,
  disp_asymptomatic = 0.16,
  disp_community = 0.16
)

## parameter_sweep uses the future_lapply() function
## Default is to run sequntially on a single core
# future::plan("sequential")
## Set up multicore if using see ?future::plan for details
## Use the workers argument to control the number of cores used.
# future::plan("multiprocess")

## Run parameter sweep
sweep_results <- parameter_sweep(
  scenarios,
  sim_fn = sim_with_params,
  samples = 1
)

sweep_results
#>      scenario              data   sims
#>         <int>            <list> <list>
#>   1:        1 <data.table[1x9]> [NULL]
#>   2:       50 <data.table[1x9]> [NULL]
#>   3:       88 <data.table[1x9]> [NULL]
#>   4:       66 <data.table[1x9]> [NULL]
#>   5:      145 <data.table[1x9]> [NULL]
#>  ---                                  
#> 156:       38 <data.table[1x9]> [NULL]
#> 157:      157 <data.table[1x9]> [NULL]
#> 158:       11 <data.table[1x9]> [NULL]
#> 159:      110 <data.table[1x9]> [NULL]
#> 160:      118 <data.table[1x9]> [NULL]