## This file is part of SimInf, a framework for stochastic ## disease spread simulations. ## ## Copyright (C) 2022 Ivana Rodriguez Ewerlöf ## Copyright (C) 2015 -- 2024 Stefan Widgren ## ## SimInf is free software: you can redistribute it and/or modify ## it under the terms of the GNU General Public License as published by ## the Free Software Foundation, either version 3 of the License, or ## (at your option) any later version. ## ## SimInf is distributed in the hope that it will be useful, ## but WITHOUT ANY WARRANTY; without even the implied warranty of ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ## GNU General Public License for more details. ## ## You should have received a copy of the GNU General Public License ## along with this program. If not, see . library(SimInf) library(tools) source("util/check.R") ## Specify the number of threads to use. set_num_threads(1) ## For debugging sessionInfo() ## Check to pass vectors of different lengths. res <- assertError(.Call( SimInf:::SimInf_clean_indiv_events, integer(0), c(0L, 3L), c(1L, 2L), c(1L, 1L), c(0L, 2L))) check_error(res, "'event' must be an integer vector with length 0.") res <- assertError(.Call( SimInf:::SimInf_clean_indiv_events, c(1L, 1L), c(0L), c(1L, 2L), c(1L, 1L), c(0L, 2L))) check_error(res, "'event' must be an integer vector with length 2.") res <- assertError(.Call( SimInf:::SimInf_clean_indiv_events, c(1L, 1L), c(0L, 3L), c(1L), c(1L, 1L), c(0L, 2L))) check_error(res, "'time' must be an integer vector with length 2.") res <- assertError(.Call( SimInf:::SimInf_clean_indiv_events, c(1L, 1L), c(0L, 3L), c(1L, 2L), c(1L), c(0L, 2L))) check_error(res, "'node' must be an integer vector with length 2.") res <- assertError(.Call( SimInf:::SimInf_clean_indiv_events, c(1L, 1L), c(0L, 3L), c(1L, 2L), c(1L, 1L), c(0L))) check_error(res, "'dest' must be an integer vector with length 2.") res <- assertError(.Call( SimInf:::SimInf_clean_indiv_events, c(1L, 1L), c(0L, 2L), c(1L, 2L), c(1L, 1L), c(0L, 2L))) check_error(res, "'event[2]' is invalid.") ## Check various errors in event data. res <- assertError(individual_events(1L)) check_error(res, "Missing columns in 'events'.") events <- data.frame( id = c(1L, 1L, 1L, 1L), event = c(1L, NA_integer_, 3L, 0L), time = c(1L, 2L, 3L, 4L), node = c(1L, 1L, 2L, 2L), dest = c(0L, 2L, 2L, 1L)) res <- assertError(individual_events(events)) check_error( res, "'event' must be an integer or character vector with non-NA values.") events <- data.frame( id = c(1L, 1L, 1L, 1L), event = c(1, 3.1, 3, 0), time = c(1L, 2L, 3L, 4L), node = c(1L, 1L, 2L, 2L), dest = c(0L, 2L, 2L, 1L)) res <- assertError(individual_events(events)) check_error( res, "'event' must be an integer or character vector with non-NA values.") events <- data.frame( id = c(1L, 1L, 1L, 1L), event = c(1L, 4L, 3L, 0L), time = c(1L, 2L, 3L, 4L), node = c(1L, 1L, 2L, 2L), dest = c(0L, 2L, 2L, 1L)) res <- assertError(individual_events(events)) check_error( res, "'event' must be an integer or character vector with non-NA values.") events <- data.frame( id = c(1L, 1L, 1L, 1L), event = c("enter", "unknown", "extTrans", "exit"), time = c(1L, 2L, 3L, 4L), node = c(1L, 1L, 2L, 2L), dest = c(0L, 2L, 2L, 1L)) res <- assertError(individual_events(events)) check_error( res, "'event' type must be 'enter', 'exit', or 'extTrans'.") events <- data.frame( id = c(1L, 1L, 1L, 1L), event = c(TRUE, TRUE, TRUE, TRUE), time = c(1L, 2L, 3L, 4L), node = c(1L, 1L, 2L, 2L), dest = c(0L, 2L, 2L, 1L)) res <- assertError(individual_events(events)) check_error( res, "'event' must be an integer or character vector with non-NA values.") events <- data.frame( id = c(1L, 1L, 1L, 1L), event = c(1L, 3L, 3L, 0L), time = c(1L, NA_integer_, 3L, 4L), node = c(1L, 1L, 2L, 2L), dest = c(0L, 2L, 2L, 1L)) res <- assertError(individual_events(events)) check_error( res, "'time' must be an integer or character vector with non-NA values.") events <- data.frame( id = c(1L, 1L, 1L, 1L), event = c(1L, 3L, 3L, 0L), time = c(1, 2.1, 3, 4), node = c(1L, 1L, 2L, 2L), dest = c(0L, 2L, 2L, 1L)) res <- assertError(individual_events(events)) check_error( res, "'time' must be an integer or character vector with non-NA values.") events <- data.frame( id = c(1L, 1L, 1L, 1L), event = c(1L, 3L, 3L, 0L), time = c(TRUE, TRUE, TRUE, TRUE), node = c(1L, 1L, 2L, 2L), dest = c(0L, 2L, 2L, 1L)) res <- assertError(individual_events(events)) check_error( res, "'time' must be an integer or character vector with non-NA values.") events <- data.frame( id = c(1L, 1L, 1L, 1L), event = c(1L, 3L, 3L, 0L), time = c(1L, 2L, 3L, 4L), node = c(NA_integer_, 1L, 2L, 2L), dest = c(0L, 2L, 2L, 1L)) res <- assertError(individual_events(events)) check_error( res, "'node' or 'dest' contain NA values.") events <- data.frame( id = c(1L, 1L, 1L, 1L), event = c(1L, 3L, 3L, 0L), time = c(1L, 2L, 3L, 4L), node = c(1L, 1L, 2L, 2L), dest = c(0L, NA_integer_, 2L, 1L)) res <- assertError(individual_events(events)) check_error( res, "'node' or 'dest' contain NA values.") ## Check individual events. events <- data.frame( id = c(1L, 1L, 1L, 1L), event = c(1L, 3L, 3L, 0L), time = c(1L, 2L, 3L, 4L), node = c(1L, 1L, 2L, 2L), dest = c(0L, 2L, 2L, 1L)) events_obs <- as.data.frame(individual_events(events)) events_exp <- data.frame( id = c(1L, 1L, 1L), event = c(1L, 3L, 0L), time = c(1L, 2L, 4L), node = c(1L, 1L, 2L), dest = c(NA_integer_, 2L, NA_integer_)) stopifnot(identical(events_obs, events_exp)) events <- data.frame( id = c(1L, 1L, 1L, 1L), event = c(1L, 3L, 3L, 0L), time = c(1L, 2L, 3L, 4L), node = c("1", "1", "2", "2"), dest = c("0", "2", "2", "1")) events_obs <- as.data.frame(individual_events(events)) events_exp <- data.frame( id = c(1L, 1L, 1L), event = c(1L, 3L, 0L), time = c(1L, 2L, 4L), node = c("1", "1", "2"), dest = c(NA_character_, "2", NA_character_)) stopifnot(identical(events_obs, events_exp)) events <- data.frame( id = c(1L, 1L, 1L, 1L), event = c(1L, 3L, 3L, 0L), time = c(1L, 2L, 3L, 4L), node = c(1L, 1L, 2L, 2L), dest = c(0L, 2L, 2L, 0L)) events_obs <- as.data.frame(individual_events(events)) events_exp <- data.frame( id = c(1L, 1L, 1L), event = c(1L, 3L, 0L), time = c(1L, 2L, 4L), node = c(1L, 1L, 2L), dest = c(NA_integer_, 2L, NA_integer_)) stopifnot(identical(events_obs, events_exp)) events <- data.frame( id = c(1L, 1L, 1L, 1L), event = c(1L, 3L, 3L, 0L), time = c(1L, 2L, 3L, 4L), node = c("A", "A", "B", "B"), dest = c("0", "B", "B", "0")) events_obs <- as.data.frame(individual_events(events)) events_exp <- data.frame( id = c(1L, 1L, 1L), event = c(1L, 3L, 0L), time = c(1L, 2L, 4L), node = c("A", "A", "B"), dest = c(NA_character_, "B", NA_character_)) stopifnot(identical(events_obs, events_exp)) events <- data.frame( id = c("A", "A", "A", "A"), event = c("enter", "extTrans", "extTrans", "exit"), time = c("2019-02-02", "2020-03-07", "2021-04-14", "2022-05-11"), node = c(1L, 1L, 2L, 2L), dest = c(0L, 2L, 2L, 0L)) events_obs <- as.data.frame(individual_events(events)) events_exp <- data.frame( id = c("A", "A", "A"), event = c("enter", "extTrans", "exit"), time = as.Date(c("2019-02-02", "2020-03-07", "2022-05-11")), node = c(1L, 1L, 2L), dest = c(NA_integer_, 2L, NA_integer_)) stopifnot(identical(events_obs, events_exp)) events$id[2] <- NA_integer_ res <- assertError(individual_events(events)) check_error( res, "'id' must be an integer or character vector with non-NA values.") events$id[2] <- 1L events$node[2] <- 1.1 res <- assertError(individual_events(events)) check_error( res, "'node' and 'dest' must both be integer or character.") events$node <- c(1L, 1L, 2L, 2L) events$dest <- as.Date(events$dest, origin = "1970-01-01") res <- assertError(individual_events(events)) check_error( res, "'node' and 'dest' must both be integer or character.") events$dest <- c(0L, 2L, 2L, 0L) events <- data.frame( id = c("A", "A", "A", "A"), event = c("enter", "extTrans", "extTrans", "exit"), time = c("2001-02-01", 2L, 3L, 4L), node = c(1L, 1L, 2L, 2L), dest = c(0L, 2L, 2L, 0L)) res <- assertError(individual_events(events)) check_error( res, "'time' must be an integer or character vector with non-NA values.") ## Testing animal with only one enter event, keep events <- data.frame( id = 1L, event = 1L, time = 1L, node = 1L, dest = 0L) events_obs <- as.data.frame(individual_events(events)) events_exp <- data.frame( id = 1L, event = 1L, time = 1L, node = 1L, dest = NA_integer_) stopifnot(identical(events_obs, events_exp)) ## Testing animal with only one exit event, keep events <- data.frame( id = 1L, event = 0L, time = 1L, node = 1L, dest = 0L) events_obs <- as.data.frame(individual_events(events)) events_exp <- data.frame( id = 1L, event = 0L, time = 1L, node = 1L, dest = NA_integer_) stopifnot(identical(events_obs, events_exp)) ## Testing animal with only one external transfer event, keep events <- data.frame( id = 1L, event = 3L, time = 1L, node = 1L, dest = 2L) stopifnot(identical(events, as.data.frame(individual_events(events)))) ## Testing animal with two enter events, keep first events <- data.frame( id = c(1L, 1L), event = c(1L, 1L), time = c(1L, 2L), node = c(1L, 1L), dest = c(0L, 0L)) events_obs <- as.data.frame(individual_events(events)) events_exp <- data.frame( id = 1L, event = 1L, time = 1L, node = 1L, dest = NA_integer_) stopifnot(identical(events_obs, events_exp)) ## Testing animal with two exit events, keep first events <- data.frame( id = c(1L, 1L), event = c(0L, 0L), time = c(1L, 2L), node = c(1L, 1L), dest = c(0L, 0L)) events_obs <- as.data.frame(individual_events(events)) events_exp <- data.frame( id = 1L, event = 0L, time = 1L, node = 1L, dest = NA_integer_) stopifnot(identical(events_obs, events_exp)) ## Testing animal with two enter events and exit, keep path events <- data.frame( id = c(1L, 1L, 1L), event = c(1L, 1L, 0L), time = c(1L, 2L, 3L), node = c(1L, 2L, 2L), dest = c(0L, 0L, 0L)) events_obs <- as.data.frame(individual_events(events)) events_exp <- data.frame( id = c(1L, 1L), event = c(1L, 0L), time = c(2L, 3L), node = c(2L, 2L), dest = c(NA_integer_, NA_integer_)) stopifnot(identical(events_obs, events_exp)) ## Testing animal with two enter events, a movement and an exit, keep ## path events <- data.frame( id = c(1L, 1L, 1L, 1L), event = c(1L, 1L, 3L, 0L), time = c(1L, 2L, 3L, 4L), node = c(1L, 2L, 1L, 3L), dest = c(0L, 0L, 3L, 0L)) events_obs <- as.data.frame(individual_events(events)) events_exp <- data.frame( id = c(1L, 1L, 1L), event = c(1L, 3L, 0L), time = c(1L, 3L, 4L), node = c(1L, 1L, 3L), dest = c(NA_integer_, 3L, NA_integer_)) stopifnot(identical(events_obs, events_exp)) ## Testing animal with one enter event and two exit events, keep path events <- data.frame( id = c(1L, 1L, 1L), event = c(1L, 0L, 0L), time = c(1L, 2L, 3L), node = c(1L, 2L, 1L), dest = c(0L, 0L, 0L)) events_obs <- as.data.frame(individual_events(events)) events_exp <- data.frame( id = c(1L, 1L), event = c(1L, 0L), time = c(1L, 3L), node = c(1L, 1L), dest = c(NA_integer_, NA_integer_)) stopifnot(identical(events_obs, events_exp)) ## Testing animal with one enter event and two exit events, keep path events <- data.frame( id = c(1L, 1L, 1L), event = c(1L, 0L, 0L), time = c(1L, 2L, 3L), node = c(1L, 1L, 2L), dest = c(0L, 0L, 0L)) events_obs <- as.data.frame(individual_events(events)) events_exp <- data.frame( id = c(1L, 1L), event = c(1L, 0L), time = c(1L, 2L), node = c(1L, 1L), dest = c(NA_integer_, NA_integer_)) stopifnot(identical(events_obs, events_exp)) ## Testing animal with another event after exit event, exit event ## should be last events <- data.frame( id = c(1L, 1L, 1L, 1L), event = c(1L, 3L, 0L, 3L), time = c(1L, 2L, 3L, 4L), node = c(1L, 1L, 2L, 2L), dest = c(0L, 2L, 0L, 3L)) events_obs <- as.data.frame(individual_events(events)) events_exp <- data.frame( id = c(1L, 1L, 1L), event = c(1L, 3L, 0L), time = c(1L, 2L, 3L), node = c(1L, 1L, 2L), dest = c(NA_integer_, 2L, NA_integer_)) stopifnot(identical(events_obs, events_exp)) ## Testing animal with another event after exit event, ## no path to exit, don't keep events <- data.frame( id = c(1L, 1L, 1L, 1L), event = c(1L, 3L, 0L, 3L), time = c(1L, 2L, 3L, 4L), node = c(1L, 1L, 3L, 2L), dest = c(0L, 2L, 0L, 3L)) events_obs <- as.data.frame(individual_events(events)) events_exp <- data.frame( id = integer(0), event = integer(0), time = integer(0), node = integer(0), dest = integer(0)) stopifnot(identical(events_obs, events_exp)) ## Testing animal with another event before enter event, enter event ## should be first events <- data.frame( id = c(1L, 1L, 1L, 1L), event = c(3L, 1L, 3L, 0L), time = c(1L, 2L, 3L, 4L), node = c(1L, 1L, 1L, 2L), dest = c(2L, 0L, 2L, 0L)) events_obs <- as.data.frame(individual_events(events)) events_exp <- data.frame( id = c(1L, 1L, 1L), event = c(1L, 3L, 0L), time = c(2L, 3L, 4L), node = c(1L, 1L, 2L), dest = c(NA_integer_, 2L, NA_integer_)) stopifnot(identical(events_obs, events_exp)) pdf_file <- tempfile(fileext = ".pdf") pdf(pdf_file) plot(individual_events(events)) dev.off() stopifnot(file.exists(pdf_file)) unlink(pdf_file) ## Testing animal with another event before enter event, keep path if ## starting on enter event and ending with exit events <- data.frame( id = c(1L, 1L, 1L, 1L), event = c(3L, 1L, 3L, 0L), time = c(1L, 2L, 3L, 4L), node = c(1L, 2L, 1L, 2L), dest = c(2L, 0L, 2L, 0L)) events_obs <- as.data.frame(individual_events(events)) events_exp <- data.frame( id = c(1L, 1L), event = c(1L, 0L), time = c(2L, 4L), node = c(2L, 2L), dest = c(NA_integer_, NA_integer_)) stopifnot(identical(events_obs, events_exp)) ## Testing animal with no path from enter to exit event, don't keep events <- data.frame( id = c(1L, 1L, 1L, 1L), event = c(3L, 1L, 3L, 0L), time = c(1L, 2L, 3L, 4L), node = c(1L, 2L, 2L, 3L), dest = c(2L, 0L, 1L, 0L)) events_obs <- as.data.frame(individual_events(events)) events_exp <- data.frame( id = integer(0), event = integer(0), time = integer(0), node = integer(0), dest = integer(0)) stopifnot(identical(events_obs, events_exp)) ## Testing animal with no enter event, keep path events <- data.frame( id = c(1L, 1L, 1L), event = c(3L, 3L, 0L), time = c(1L, 2L, 3L), node = c(1L, 2L, 1L), dest = c(2L, 1L, 0L)) events_obs <- as.data.frame(individual_events(events)) events_exp <- data.frame( id = c(1L, 1L, 1L), event = c(3L, 3L, 0L), time = c(1L, 2L, 3L), node = c(1L, 2L, 1L), dest = c(2L, 1L, NA_integer_)) stopifnot(identical(events_obs, events_exp)) ## Testing animal with no enter or exit event, keep path events <- data.frame( id = c(1L, 1L), event = c(3L, 3L), time = c(1L, 2L), node = c(1L, 2L), dest = c(2L, 3L)) events_obs <- as.data.frame(individual_events(events)) stopifnot(identical(events_obs, events)) ## Testing animal with no exit event, keep path events <- data.frame( id = c(1L, 1L), event = c(1L, 3L), time = c(1L, 2L), node = c(1L, 1L), dest = c(0L, 2L)) events_obs <- as.data.frame(individual_events(events)) events_exp <- data.frame( id = c(1L, 1L), event = c(1L, 3L), time = c(1L, 2L), node = c(1L, 1L), dest = c(NA_integer_, 2L)) stopifnot(identical(events_obs, events_exp)) ## Testing animal with only enter and exit event, keep path events <- data.frame( id = c(1L, 1L), event = c(1L, 0L), time = c(1L, 2L), node = c(1L, 1L), dest = c(0L, 0L)) events_obs <- as.data.frame(individual_events(events)) events_exp <- data.frame( id = c(1L, 1L), event = c(1L, 0L), time = c(1L, 2L), node = c(1L, 1L), dest = c(NA_integer_, NA_integer_)) stopifnot(identical(events_obs, events_obs)) ## Testing animal with enter and exit event in wrong order, don't keep events <- data.frame( id = c(1L, 1L), event = c(0L, 1L), time = c(1L, 2L), node = c(1L, 1L), dest = c(0L, 0L)) events_obs <- as.data.frame(individual_events(events)) events_exp <- data.frame( id = integer(0), event = integer(0), time = integer(0), node = integer(0), dest = integer(0)) stopifnot(identical(events_obs, events_exp)) ## Check converting individual events to u0 events <- data.frame( id = c(1, 1, 1, 1, 2, 2, 2, 2), event = c(1, 3, 3, 0, 1, 3, 3, 0), time = c(1, 2, 3, 4, 2, 3, 4, 5), node = c(10, 10, 20, 20, 10, 10, 20, 20), dest = c(NA, 20, 20, NA, NA, 20, 20, NA)) stopifnot(identical( u0(individual_events(events), time = 0), data.frame(key = c(10, 20), node = c(1L, 2L), S_1 = c(0L, 0L)))) stopifnot(identical( u0(individual_events(events), time = 1), data.frame(key = c(10, 20), node = c(1L, 2L), S_1 = c(1L, 0L)))) stopifnot(identical( u0(individual_events(events), time = 2), data.frame(key = c(10, 20), node = c(1L, 2L), S_1 = c(1L, 1L)))) stopifnot(identical( u0(individual_events(events), time = 2, target = "SIS"), data.frame(key = c(10, 20), node = c(1L, 2L), S = c(1L, 1L), I = c(0L, 0L)))) stopifnot(identical( u0(individual_events(events), time = 2, target = "SISe"), data.frame(key = c(10, 20), node = c(1L, 2L), S = c(1L, 1L), I = c(0L, 0L)))) stopifnot(identical( u0(individual_events(events), time = 2, target = "SISe_sp"), data.frame(key = c(10, 20), node = c(1L, 2L), S = c(1L, 1L), I = c(0L, 0L)))) stopifnot(identical( u0(individual_events(events), time = 2, target = "SIR"), data.frame(key = c(10, 20), node = c(1L, 2L), S = c(1L, 1L), I = c(0L, 0L), R = c(0L, 0L)))) stopifnot(identical( u0(individual_events(events), time = 2, target = "SEIR"), data.frame(key = c(10, 20), node = c(1L, 2L), S = c(1L, 1L), E = c(0L, 0L), I = c(0L, 0L), R = c(0L, 0L)))) stopifnot(identical( u0(individual_events(events), time = 2, age = c(1, 2), target = "SISe3"), data.frame(key = c(10, 20), node = c(1L, 2L), S_1 = c(1L, 0L), S_2 = c(0L, 1L), S_3 = c(0L, 0L), I_1 = c(0L, 0L), I_2 = c(0L, 0L), I_3 = c(0L, 0L)))) stopifnot(identical( u0(individual_events(events), time = 2, age = c(1, 2), target = "SISe3_sp"), data.frame(key = c(10, 20), node = c(1L, 2L), S_1 = c(1L, 0L), S_2 = c(0L, 1L), S_3 = c(0L, 0L), I_1 = c(0L, 0L), I_2 = c(0L, 0L), I_3 = c(0L, 0L)))) stopifnot(identical( u0(individual_events(events), time = 3), data.frame(key = c(10, 20), node = c(1L, 2L), S_1 = c(0L, 2L)))) stopifnot(identical( u0(individual_events(events), time = 4), data.frame(key = c(10, 20), node = c(1L, 2L), S_1 = c(0L, 1L)))) stopifnot(identical( u0(individual_events(events), time = 5), data.frame(key = c(10, 20), node = c(1L, 2L), S_1 = c(0L, 0L)))) stopifnot(identical( u0(individual_events(events), time = 3, age = 2), data.frame(key = c(10, 20), node = c(1L, 2L), S_1 = c(0L, 1L), S_2 = c(0L, 1L)))) stopifnot(identical( u0(individual_events(events), time = 3, age = 5), data.frame(key = c(10, 20), node = c(1L, 2L), S_1 = c(0L, 2L), S_2 = c(0L, 0L)))) stopifnot(identical( u0(individual_events(events), time = 3, age = 1), data.frame(key = c(10, 20), node = c(1L, 2L), S_1 = c(0L, 0L), S_2 = c(0L, 2L)))) res <- assertError(u0(individual_events(events), time = 3, age = 1, target = "SIR")) check_error( res, "Invalid 'age' for 'target' model.") res <- assertError(u0(individual_events(events), time = 4.3)) check_error( res, "'time' must be an integer or date.") res <- assertError(u0(individual_events(events), time = c("2021-01-01", "2022-01-01"))) check_error( res, "'time' must be an integer or date.") res <- assertError(u0(individual_events(events), time = "2021-01-01")) check_error( res, "'time' must be an integer.") res <- assertError(u0(individual_events(events), time = list())) check_error( res, "'time' must be an integer or date.") res <- assertError(u0(individual_events(events), time = 3, age = -1)) check_error( res, "'age' must be an integer vector with values > 0.") res <- assertError(SimInf:::u0_target(u0(individual_events(events), time = 2), target = "Unknown")) check_error( res, "Invalid 'target' for 'u0'.") events <- data.frame( id = c("individual-1", "individual-1", "individual-1", "individual-1", "individual-2", "individual-2", "individual-2", "individual-2"), event = c("enter", "extTrans", "extTrans", "exit", "enter", "extTrans", "extTrans", "exit"), time = c("2019-02-02", "2020-03-07", "2021-04-14", "2022-05-11", "2019-02-02", "2020-03-07", "2021-04-14", "2022-05-11"), node = c("node-1", "node-1", "node-2", "node-2", "node-1", "node-1", "node-2", "node-2"), dest = c(NA, "node-2", "node-2", NA, NA, "node-2", "node-2", NA)) u0_obs <- u0(individual_events(events)) u0_exp <- data.frame( key = c("node-1", "node-2"), node = c(1L, 2L), S_1 = c(2L, 0L)) stopifnot(identical(u0_obs, u0_exp)) u0_obs <- u0(individual_events(events[rev(seq_len(nrow(events))), ])) stopifnot(identical(u0_obs, u0_exp)) stopifnot(identical( get_individuals(individual_events(events), "2019-02-02"), data.frame( id = c("individual-1", "individual-2"), node = c("node-1", "node-1"), age = c(0L, 0L)))) stopifnot(identical( get_individuals(individual_events(events), "2019-02-04"), data.frame( id = c("individual-1", "individual-2"), node = c("node-1", "node-1"), age = c(2L, 2L)))) stopifnot(identical( get_individuals(individual_events(events), "2019-02-01"), data.frame( id = character(0), node = logical(0), age = integer(0)))) show_expected <- c( "Number of individuals: 2", "Number of events: 6") show_observed <- capture.output(show(individual_events(events))) stopifnot(identical(show_observed, show_expected)) summary_expected <- c( "Number of individuals: 2", "Number of events: 6", " - Exit: 2", " - Enter: 2", " - Internal transfer: 0", " - External transfer: 2") summary_observed <- capture.output(summary(individual_events(events))) stopifnot(identical(summary_observed, summary_expected)) events <- data.frame( id = c(1, 1), event = c("extTrans", "exit"), time = c(2, 3), node = c(1, 2), dest = c(2, 0)) res <- assertError(get_individuals(individual_events(events))) check_error( res, "All individuals must have an 'enter' event.") res <- assertError(node_events(individual_events(events))) check_error( res, "All individuals must have an 'enter' event.") res <- assertError(SimInf:::check_indiv_events_id(3.2)) check_error( res, "'id' must be an integer or character vector with non-NA values.") res <- assertError(SimInf:::check_indiv_events_id(NULL)) check_error( res, "'id' must be an integer or character vector with non-NA values.") ## Test to generate events and u0 events <- data.frame( id = c("animal-06", "animal-03", "animal-03", "animal-03", "animal-08", "animal-03", "animal-03", "animal-06", "animal-08", "animal-08", "animal-06", "animal-08", "animal-08", "animal-06", "animal-06", "animal-05", "animal-07", "animal-05", "animal-05", "animal-05", "animal-05", "animal-10", "animal-01", "animal-04", "animal-04", "animal-04", "animal-01", "animal-01", "animal-05", "animal-05", "animal-08", "animal-08", "animal-01", "animal-01", "animal-09", "animal-10", "animal-09", "animal-09", "animal-02", "animal-11", "animal-11", "animal-11", "animal-11", "animal-11", "animal-11", "animal-11"), event = c("enter", "enter", "extTrans", "extTrans", "enter", "exit", "exit", "extTrans", "extTrans", "extTrans", "extTrans", "extTrans", "extTrans", "exit", "exit", "enter", "enter", "extTrans", "extTrans", "extTrans", "extTrans", "enter", "enter", "enter", "exit", "exit", "extTrans", "extTrans", "exit", "exit", "exit", "exit", "exit", "exit", "enter", "exit", "extTrans", "extTrans", "enter", "enter", "extTrans", "extTrans", "extTrans", "extTrans", "exit", "exit"), time = c("2015-01-31", "2015-04-01", "2015-05-27", "2015-05-27", "2015-10-14", "2015-12-25", "2015-12-26", "2016-05-23", "2016-06-01", "2016-10-12", "2016-10-28", "2017-03-01", "2017-03-01", "2017-03-09", "2017-03-09", "2017-04-25", "2017-08-30", "2017-12-21", "2017-12-21", "2017-12-22", "2017-12-22", "2018-03-30", "2019-05-30", "2019-07-06", "2019-07-16", "2019-07-17", "2019-08-14", "2019-08-14", "2020-03-31", "2020-04-01", "2020-07-13", "2020-07-14", "2021-02-09", "2021-02-09", "2022-02-01", "2022-04-10", "2022-07-25", "2022-07-25", "2022-12-09", "2017-04-25", "2017-12-21", "2017-12-21", "2017-12-22", "2017-12-22", "2020-03-31", "2020-04-01"), node = c("node-08", "node-03", "node-03", "node-03", "node-12", "node-05", "node-05", "node-08", "node-12", "node-13", "node-07", "node-12", "node-12", "node-08", "node-08", "node-06", "node-11", "node-06", "node-06", "node-09", "node-09", "node-17", "node-01", "node-04", "node-04", "node-04", "node-01", "node-01", "node-16", "node-16", "node-18", "node-18", "node-10", "node-10", "node-14", "node-17", "node-14", "node-14", "node-02", "node-06", "node-06", "node-06", "node-09", "node-09", "node-16", "node-16"), dest = c(NA, NA, "node-05", "node-05", NA, NA, NA, "node-07", "node-13", "node-12", "node-08", "node-18", "node-18", NA, NA, NA, NA, "node-09", "node-09", "node-16", "node-16", NA, NA, NA, NA, NA, "node-10", "node-10", NA, NA, NA, NA, NA, NA, NA, NA, "node-15", "node-15", NA, NA, "node-09", "node-09", "node-16", "node-16", NA, NA)) events_expected <- data.frame( event = c("enter", "extTrans", "enter", "exit", "extTrans", "extTrans", "extTrans", "extTrans", "extTrans", "exit", "enter", "enter", "extTrans", "extTrans", "enter", "enter", "enter", "exit", "extTrans", "exit", "exit", "exit", "enter", "exit", "extTrans", "enter"), time = c("2015-04-01", "2015-05-27", "2015-10-14", "2015-12-25", "2016-05-23", "2016-06-01", "2016-10-12", "2016-10-28", "2017-03-01", "2017-03-09", "2017-04-25", "2017-08-30", "2017-12-21", "2017-12-22", "2018-03-30", "2019-05-30", "2019-07-06", "2019-07-16", "2019-08-14", "2020-03-31", "2020-07-13", "2021-02-09", "2022-02-01", "2022-04-10", "2022-07-25", "2022-12-09"), node = c(3L, 3L, 12L, 5L, 8L, 12L, 13L, 7L, 12L, 8L, 6L, 11L, 6L, 9L, 17L, 1L, 4L, 4L, 1L, 16L, 18L, 10L, 14L, 17L, 14L, 2L), dest = c(0L, 5L, 0L, 0L, 7L, 13L, 12L, 8L, 18L, 0L, 0L, 0L, 9L, 16L, 0L, 0L, 0L, 0L, 10L, 0L, 0L, 0L, 0L, 0L, 15L, 0L), n = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 2L, 2L, 1L, 1L, 1L, 1L, 1L, 2L, 1L, 1L, 1L, 1L, 1L, 1L), proportion = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), select = c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), shift = c(0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L, 0L)) events_observed <- node_events(individual_events(events)) stopifnot(identical(events_observed, events_expected)) ## Check that an intTrans event is added. events <- data.frame( id = c(1, 1, 1, 1, 2, 2), event = c("enter", "extTrans", "extTrans", "exit", "enter", "exit"), time = c(1, 3, 5, 7, 1, 3), node = c(1, 1, 2, 3, 1, 1), dest = c(NA, 2, 3, NA, NA, NA)) events_expected <- data.frame( event = c("enter", "exit", "extTrans", "extTrans", "intTrans", "exit"), time = c(1, 3, 3, 5, 6, 7), node = c(1L, 1L, 1L, 2L, 3L, 3L), dest = c(0L, 0L, 2L, 3L, 0L, 0L), n = c(2L, 1L, 1L, 1L, 1L, 1L), proportion = c(0, 0, 0, 0, 0, 0), select = c(1L, 3L, 3L, 3L, 3L, 4L), shift = c(0L, 0L, 0L, 0L, 1L, 0L)) events_observed <- node_events(individual_events(events), time = 0, age = 5) stopifnot(identical(events_observed, events_expected)) ## Check that target works for 'SEIR', 'SIS', 'SISe', and ## 'SISe_sp'. events <- data.frame( id = c(1, 1, 1, 1, 2, 2), event = c("enter", "extTrans", "extTrans", "exit", "enter", "exit"), time = c(1, 3, 5, 7, 1, 3), node = c(1, 1, 2, 3, 1, 1), dest = c(NA, 2, 3, NA, NA, NA)) events_expected <- data.frame( event = c("enter", "exit", "extTrans", "extTrans", "exit"), time = c(1, 3, 3, 5, 7), node = c(1L, 1L, 1L, 2L, 3L), dest = c(0L, 0L, 2L, 3L, 0L), n = c(2L, 1L, 1L, 1L, 1L), proportion = c(0, 0, 0, 0, 0), select = c(1L, 2L, 2L, 2L, 2L), shift = c(0L, 0L, 0L, 0L, 0L)) events_observed <- node_events(individual_events(events), time = 0, target = "SEIR") stopifnot(identical(events_observed, events_expected)) events_observed <- node_events(individual_events(events), time = 0, target = "SIS") stopifnot(identical(events_observed, events_expected)) events_observed <- node_events(individual_events(events), time = 0, target = "SISe") stopifnot(identical(events_observed, events_expected)) events_observed <- node_events(individual_events(events), time = 0, target = "SISe_sp") stopifnot(identical(events_observed, events_expected)) ## Check that target works for 'SIR'. events <- data.frame( id = c(1, 1, 1, 1, 2, 2), event = c("enter", "extTrans", "extTrans", "exit", "enter", "exit"), time = c(1, 3, 5, 7, 1, 3), node = c(1, 1, 2, 3, 1, 1), dest = c(NA, 2, 3, NA, NA, NA)) events_expected <- data.frame( event = c("enter", "exit", "extTrans", "extTrans", "exit"), time = c(1, 3, 3, 5, 7), node = c(1L, 1L, 1L, 2L, 3L), dest = c(0L, 0L, 2L, 3L, 0L), n = c(2L, 1L, 1L, 1L, 1L), proportion = c(0, 0, 0, 0, 0), select = c(1L, 4L, 4L, 4L, 4L), shift = c(0L, 0L, 0L, 0L, 0L)) events_observed <- node_events(individual_events(events), time = 0, target = "SIR") stopifnot(identical(events_observed, events_expected)) ## Check that target works for 'NULL', 'SISe3', and 'SISe3_sp'. events <- data.frame( id = c(1, 1, 1, 1, 2, 2), event = c("enter", "extTrans", "extTrans", "exit", "enter", "exit"), time = c(1, 3, 5, 7, 1, 3), node = c(1, 1, 2, 3, 1, 1), dest = c(NA, 2, 3, NA, NA, NA)) events_expected <- data.frame( event = c("enter", "exit", "extTrans", "intTrans", "extTrans", "intTrans", "exit"), time = c(1, 3, 3, 4, 5, 6, 7), node = c(1L, 1L, 1L, 2L, 2L, 3L, 3L), dest = c(0L, 0L, 2L, 0L, 3L, 0L, 0L), n = c(2L, 1L, 1L, 1L, 1L, 1L, 1L), proportion = c(0, 0, 0, 0, 0, 0, 0), select = c(1L, 4L, 4L, 4L, 5L, 5L, 6L), shift = c(0L, 0L, 0L, 1L, 0L, 2L, 0L)) events_observed <- node_events(individual_events(events), time = 0, age = c(3, 5), target = NULL) stopifnot(identical(events_observed, events_expected)) events_observed <- node_events(individual_events(events), time = 0, age = c(3L, 5L), target = "SISe3") stopifnot(identical(events_observed, events_expected)) events_observed <- node_events(individual_events(events), time = 0, age = c(3, 5), target = "SISe3_sp") stopifnot(identical(events_observed, events_expected)) ## Check generating tex-code from events events <- data.frame( id = c(1, 1, 1, 1, 1, 1, 1, 1), event = c(1, 1, 3, 3, 3, 0, 0, 3), time = c(1, 1, 2, 2, 3, 4, 4, 5), node = c(1, 2, 1, 1, 2, 2, 1, 3), dest = c(0, 0, 2, 3, 2, 0, 0, 2)) tex_expected <- c( "\\documentclass[tikz]{standalone}", "\\usepackage{tikz}", "\\begin{document}", "\\begin{tikzpicture}", " \\sffamily", "", " \\draw[>=stealth,->] (0,0.5) -- (6,0.5);", " \\node at (3,0) {\\tiny Time};", "", " \\draw[>=stealth, gray!40] (0.5,1) -- (5.5,1);", " \\node at (0,1) {\\tiny Node 1};", "", " \\draw[>=stealth, gray!40] (0.5,2) -- (5.5,2);", " \\node at (0,2) {\\tiny Node 2};", "", " \\draw[>=stealth, gray!40] (0.5,3) -- (5.5,3);", " \\node at (0,3) {\\tiny Node 3};", "", " \\node at (1,0.3) {\\tiny $t_{1}$};", " \\draw (1,0.55) -- (1,0.45);", " \\node at (2,0.3) {\\tiny $t_{2}$};", " \\draw (2,0.55) -- (2,0.45);", " \\node at (3,0.3) {\\tiny $t_{3}$};", " \\draw (3,0.55) -- (3,0.45);", " \\node at (4,0.3) {\\tiny $t_{4}$};", " \\draw (4,0.55) -- (4,0.45);", " \\node at (5,0.3) {\\tiny $t_{5}$};", " \\draw (5,0.55) -- (5,0.45);", "", " \\node at (1,1.1) {\\textborn};", " \\node at (1,2.1) {\\textcolor{gray!60}\\textborn};", " \\path[>=stealth,->] (2,1) edge [out=135, in=225] (2,2);", " \\path[>=stealth,gray!60,->] (2,1) edge [out=135, in=225] (2,3);", " \\path[>=stealth,gray!60,->] (3,2) edge [out=135, in=45, loop] (3,2);", " \\node at (4,2.2) {\\textdagger};", " \\node at (4,1.2) {\\textcolor{gray!60}\\textdagger};", " \\path[>=stealth,gray!60,->] (5,3) edge [out=315, in=45] (5,2);", "", "\\end{tikzpicture}", "\\end{document}") tex_observed <- SimInf:::events_to_tex(events) stopifnot(identical(tex_observed, tex_expected)) events <- data.frame( id = c(1, 1, 1, 1, 1, 1, 1, 1), event = c(1, 1, 3, 3, 3, 0, 0, 3), time = c(1, 1, 2, 2, 3, 4, 4, 5), node = c(1, 2, 1, 1, 3, 2, 1, 2), dest = c(0, 0, 2, 3, 2, 0, 0, 2)) events_expected <- data.frame( id = c(1, 1, 1, 1), event = c(1L, 3L, 3L, 0L), time = c(1L, 2L, 3L, 4L), node = c(1, 1, 3, 2), dest = c(NA, 3, 2, NA)) events_observed <- as.data.frame(individual_events(events)) stopifnot(identical(events_observed, events_expected)) events <- data.frame( id = c(1, 1, 1, 1, 1, 1), event = c(1, 3, 3, 3, 3, 0), time = c(1, 2, 2, 3, 3, 4), node = c(1, 1, 1, 3, 3, 2), dest = c(0, 2, 3, 1, 2, 0)) events_expected <- data.frame( id = c(1, 1, 1, 1), event = c(1L, 3L, 3L, 0L), time = c(1L, 2L, 3L, 4L), node = c(1, 1, 3, 2), dest = c(NA, 3, 2, NA)) events_observed <- as.data.frame(individual_events(events)) stopifnot(identical(events_observed, events_expected))