Skip to content

aggregate <epichains> object by time per chain #303

Description

@avallecam

Hi @jamesmbaazam, I found that it is possible to aggregate() multiple chains within one simulation. However, Is it possible to have time aggregates for each chain in that same simulation?

From the example at https://epiverse-trace.github.io/epichains/reference/aggregate.epichains.html, I generated two alternatives, but I am wondering if epichains already has an optimal way to do this without using any data wrangling (neither tidy nor base).

My goal is to get a similar output as in the tutorial episode introduction figure: https://epiverse-trace.github.io/tutorials-middle/superspreading-simulate.html and minimize as much as possible the data wrangling steps in the tutorial

Reprex:

library(epichains)
library(tidyverse)

set.seed(32)

chains <- simulate_chains(
  n_chains = 10,
  statistic = "size",
  offspring_dist = rpois,
  stat_threshold = 10,
  generation_time = function(n) rep(3, n),
  lambda = 2
)

# aggregate all chains
aggregate(chains, by = "time")
#>   time cases
#> 1    0    10
#> 2    3    25
#> 3    6    61
#> 4    9    33
# chains %>% filter(chain == 1) # filter keeps the <epichain> class object

# alternative 1: aggregate per chain
alt_1 <- expand_grid(
  chain_seq = 1:10,
  epichains_input = list(chains)
) %>% 
  rowwise() %>% 
  mutate(epichains_filter = list(filter(epichains_input, chain == chain_seq))) %>% 
  mutate(epichains_aggregate = list(aggregate(epichains_filter, by = "time"))) %>% 
  mutate(epichains_cumsum = list(mutate(epichains_aggregate, cases_cumsum = cumsum(cases)))) %>% 
  unnest(epichains_cumsum)

# alternative 2: aggregate per chain
alt_2 <- chains %>% 
  as_tibble() %>%
  mutate(day = ceiling(time)) %>%
  count(chain, day, name = "cases") %>%
  group_by(chain) %>%
  mutate(cases_cumsum = cumsum(cases)) %>%
  ungroup()

# compare
waldo::compare(
  alt_1 %>% dplyr::select(chain = chain_seq, time:cases_cumsum),
  alt_2 %>% dplyr::rename(time = day)
)
#> ✔ No differences

# output of alternative 1
alt_1 %>% dplyr::select(chain = chain_seq, time:cases_cumsum)
#> # A tibble: 34 × 4
#>    chain  time cases cases_cumsum
#>    <int> <dbl> <int>        <int>
#>  1     1     0     1            1
#>  2     1     3     2            3
#>  3     1     6     3            6
#>  4     1     9     6           12
#>  5     2     0     1            1
#>  6     2     3     2            3
#>  7     2     6     5            8
#>  8     2     9    14           22
#>  9     3     0     1            1
#> 10     3     3     3            4
#> # ℹ 24 more rows

Created on 2025-04-04 with reprex v2.1.1

Desired output, that was not able to render in the same reprex:

# goal: visualize grouped chain trajectories
alt_1 %>%
ggplot(aes(
  x = time,
  y = cases_cumsum,
  group = chain_seq
)) +
geom_line() +
labs(
  x = "Day",
  y = "Cumulative cases"
)

Image

Metadata

Metadata

Assignees

Labels

short-termasap and before august 2025 ends

Type

No type

Projects

Status
No status

Relationships

None yet

Development

No branches or pull requests

Issue actions