Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

jidea-157 Support ISO codes as country parameter to daedalus #38

Merged
merged 8 commits into from
Oct 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: daedalus
Title: Model health, social, and economic costs of a pandemic using
_DAEDALUS_
Version: 0.0.18
Version: 0.0.19
Authors@R: c(
person("Pratik", "Gupte", , "p.gupte24@imperial.ac.uk", role = c("aut", "cre"),
comment = c(ORCID = "0000-0001-5294-7819")),
Expand Down
9 changes: 5 additions & 4 deletions R/class_country.R
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,9 @@ new_daedalus_country <- function(name, parameters) {
#' parameter access and editing, as well as processing raw country
#' characteristics for the DAEDALUS model.
#'
#' @param name A string giving the country or territory name; must be from among
#' [daedalus::country_names].
#' @param country A string giving the country or territory name, or ISO2 or
#' ISO3 code; must be from among [daedalus::country_codes_iso2c] or
#' [daedalus::country_codes_iso3c] or [daedalus::country_names].
#'
#' @param parameters An optional named list of country parameters that are
#' allowed to be modified. Currently, users may only pass their own contact
Expand Down Expand Up @@ -72,14 +73,14 @@ new_daedalus_country <- function(name, parameters) {
#' # using assignment operators
#' x$contact_matrix <- matrix(99, 4, 4)
#' x
daedalus_country <- function(name,
daedalus_country <- function(country,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"name" didn't seem right for this parameter any more

parameters = list(
contact_matrix = NULL,
contacts_workplace = NULL,
contacts_consumer_worker = NULL
)) {
# input checking
name <- rlang::arg_match(name, daedalus::country_names)
name <- country_name_from_arg(country)
# check list but allow missing and NULL
checkmate::assert_list(
parameters, c("numeric", "matrix", "NULL")
Expand Down
32 changes: 32 additions & 0 deletions R/country_helpers.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#' Get country name from arg
#' @description Function to get a supported country name given an arg which
#' may be a country name or may be an ISO2 or ISO3 code. In all cases,
#' the function checks if the country identifier is supported.
#'
#' @param country A string which could be a country name, or an ISO2 or ISO3
#' code.
#'
#' @return A supported country name
#' @keywords internal
country_name_from_arg <- function(country) {
lookup_country_name_from_code <- function(code, code_list) {
# check code is known, and lookup country name from idx
code <- rlang::arg_match(code, code_list)
idx <- match(code, code_list)
daedalus::country_names[[idx]]
}

if (any(grep("^[A-Z]{2}$", country))) { # regex check for ISO2
country <- lookup_country_name_from_code(
country, daedalus::country_codes_iso2c
)
} else if (any(grep("^[A-Z]{3}$", country))) { # regex check for ISO3
country <- lookup_country_name_from_code(
country, daedalus::country_codes_iso3c
)
} else {
# check country name is known
country <- rlang::arg_match(country, daedalus::country_names)
}
country
}
4 changes: 2 additions & 2 deletions R/daedalus.R
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
#'
#' @param country A country or territory object of class `<daedalus_country>`,
#' **or** a country or territory name from those included in the package;
#' see [daedalus::country_names].
#' see [daedalus::country_names], **or** a country ISO2 or ISO3 code; see
#' [daedalus::country_codes_iso2c] and [daedalus::country_codes_iso3c] .
#' Country-specific data such as the community and workplace contacts, the
#' demography, and the distribution of the workforce into economic sectors is
#' automatically accessed from package data for the relevant country name if it
Expand Down Expand Up @@ -122,7 +123,6 @@ daedalus <- function(country,
# NOTE: names are case sensitive
checkmate::assert_multi_class(country, c("daedalus_country", "character"))
if (is.character(country)) {
country <- rlang::arg_match(country, daedalus::country_names)
country <- daedalus_country(country)
}
checkmate::assert_multi_class(infection, c("daedalus_infection", "character"))
Expand Down
2 changes: 1 addition & 1 deletion inst/WORDLIST
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ Pianella
SARS
SEIR
Sumali
arg
asymp
doi
econ
Expand All @@ -24,6 +25,5 @@ rootfinding
started’
symp
th
timeframe
timeseries
timesteps
7 changes: 4 additions & 3 deletions man/class_country.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 21 additions & 0 deletions man/country_name_from_arg.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion man/daedalus.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion man/make_initial_state.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

30 changes: 28 additions & 2 deletions tests/testthat/test-class_daedalus_country.R
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,27 @@ test_that("class <daedalus_country>: basic expectations", {
)
})

test_that("class <daedalus_country>`: works for all countries", {
test_that("class <daedalus_country>`: works for all country names", {
expect_no_condition({
countries <- lapply(daedalus::country_names, daedalus_country) # nolint
})
checkmate::expect_list(countries, "daedalus_country")
})

test_that("class <daedalus_country>`: works for all country ISO2 codes", {
expect_no_condition({
countries <- lapply(daedalus::country_codes_iso2c, daedalus_country) # nolint
})
checkmate::expect_list(countries, "daedalus_country")
})

test_that("class <daedalus_country>`: works for all country ISO3 codes", {
expect_no_condition({
countries <- lapply(daedalus::country_codes_iso3c, daedalus_country) # nolint
})
checkmate::expect_list(countries, "daedalus_country")
})

Comment on lines +30 to +43
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this is overkill, but it's following the pattern!

test_that("class <daedalus_country>: access and assignment", {
name <- "Canada"
country_x <- daedalus_country(name)
Expand Down Expand Up @@ -121,7 +135,19 @@ test_that("class <daedalus_country>`: errors", {
# invalid name
expect_error(
daedalus_country("dummy"),
regexp = "`name` must be one of"
regexp = "`country` must be one of"
)

# invalid ISO2
expect_error(
daedalus_country("ZZ"),
regexp = "`code` must be one of"
)

# invalid ISO3
expect_error(
daedalus_country("ZZZ"),
regexp = "`code` must be one of"
)

# invalid `parameter` type
Expand Down
16 changes: 16 additions & 0 deletions tests/testthat/test-daedalus.R
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,22 @@ test_that("daedalus: basic expectations", {
)
})

test_that("Can run with ISO2 country parameter", {
expect_no_condition({
output <- daedalus("CA", "influenza_1918")
})
data <- get_data(output)
expect_length(data, N_OUTPUT_COLS)
})

test_that("Can run with ISO3 country parameter", {
expect_no_condition({
output <- daedalus("CAN", "influenza_1918")
})
data <- get_data(output)
expect_length(data, N_OUTPUT_COLS)
})

# test that daedalus runs for all epidemic infection parameter sets
test_that("daedalus: Runs for all country x infection x response", {
country_infection_combos <- data.table::CJ(
Expand Down
32 changes: 32 additions & 0 deletions tests/testthat/test_country_helpers.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
test_that("country_name_from_arg looks up name from iso2", {
expect_identical(country_name_from_arg("CA"), "Canada")
})

test_that("country_name_from_arg looks up name from iso3", {
expect_identical(country_name_from_arg("CAN"), "Canada")
})

test_that("country_name_from_arg passes through supported country name", {
expect_identical(country_name_from_arg("Canada"), "Canada")
})

test_that("country_name_from_arg errors on unsupported iso2", {
expect_error(
country_name_from_arg("ZZ"),
regexp = "must be one of"
)
})

test_that("country_name_from_arg errors on unsupported iso3", {
expect_error(
country_name_from_arg("ZZZ"),
regexp = "must be one of"
)
})

test_that("country_name_from_arg errors on unsupported country name", {
expect_error(
country_name_from_arg("Narnia"),
regexp = "must be one of"
)
})
Loading