From 084ae692a1caa78447b254fc7f91dfe2bbc22897 Mon Sep 17 00:00:00 2001 From: rtesra <70330391+rtesra@users.noreply.github.com> Date: Tue, 19 Nov 2024 09:04:45 +0000 Subject: [PATCH 1/5] Update population warning on model fitting --- DESCRIPTION | 2 +- NEWS.md | 4 ++++ R/model.R | 6 ++++++ tests/testthat/test-04-model-frame.R | 29 +++++++++++++++++++++++----- 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 3bc85910..987746be 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: naomi Title: Naomi Model for Subnational HIV Estimates -Version: 2.9.29 +Version: 2.9.30 Authors@R: person(given = "Jeff", family = "Eaton", diff --git a/NEWS.md b/NEWS.md index bc8343f3..57c7db28 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,7 @@ +# naomi 2.9.30 + +* Improve warning generated when user fits model at admin level where no population data exists. + # naomi 2.9.29 * Add function to format data for Naomi-Spectrum comparison table. diff --git a/R/model.R b/R/model.R index fe55d6ef..85a6da85 100644 --- a/R/model.R +++ b/R/model.R @@ -329,6 +329,12 @@ naomi_model_frame <- function(area_merged, ## of a Spectrum file and then calibrated. Currently no way to know if areas ## comparise only part of a Spectrum file, so can't address. + if(any( mf_areas[["area_id"]] %in% unique(population_agesex$area_id) == FALSE)){ + stop( + "Population data not available for admin level selected for model projections. + Please review model options selection to ensure that area level selection is correct.") + } + pop_subset <- dplyr::filter(population_agesex, area_id %in% mf_areas[["area_id"]]) pop_t1 <- interpolate_population_agesex(pop_subset, calendar_quarter1) pop_t2 <- interpolate_population_agesex(pop_subset, calendar_quarter2) diff --git a/tests/testthat/test-04-model-frame.R b/tests/testthat/test-04-model-frame.R index 591312e3..74bca9d4 100644 --- a/tests/testthat/test-04-model-frame.R +++ b/tests/testthat/test-04-model-frame.R @@ -53,7 +53,26 @@ test_that("artnum_mf() works with single quarter ART data", { }) +test_that("Informative error displayed when model run to admin level higher/lower than population data supplied", { + x <- expect_error( + naomi_model_frame(a_area_merged, + demo_population_agesex, + a_spec, + scope = "MWI", + level = 3, + calendar_quarter1 = "CY2016Q1", + calendar_quarter2 = "CY2018Q4", + calendar_quarter3 = "CY2019Q2", + calendar_quarter4 = "CY2022Q3", + calendar_quarter5 = "CY2023Q3")) + + + expect_equal(x$message, + "Population data not available for admin level selected for model projections.\n Please review model options selection to ensure that area level selection is correct." + ) + +}) test_that("population calibration options", { @@ -85,7 +104,7 @@ test_that("population calibration options", { mf_none$mf_model$population_t2 + mf_none$mf_model$population_t3 + mf_none$mf_model$population_t4 + - mf_none$mf_model$population_t5 + mf_none$mf_model$population_t5 ), sum(mf_none$spectrum_calibration$population_raw)) @@ -102,7 +121,7 @@ test_that("population calibration options", { calendar_quarter2 = "CY2018Q4", calendar_quarter3 = "CY2019Q2", calendar_quarter4 = "CY2022Q3", - calendar_quarter5 = "CY2023Q3", + calendar_quarter5 = "CY2023Q3", spectrum_population_calibration = "national") expect_false(sum(mf_nat$spectrum_calibration$population_raw) == @@ -132,7 +151,7 @@ test_that("population calibration options", { calendar_quarter2 = "CY2018Q4", calendar_quarter3 = "CY2019Q2", calendar_quarter4 = "CY2022Q3", - calendar_quarter5 = "CY2023Q3", + calendar_quarter5 = "CY2023Q3", spectrum_population_calibration = "subnational") expect_false(sum(mf_subnat$spectrum_calibration$population_raw) == @@ -162,7 +181,7 @@ test_that("population calibration options", { calendar_quarter2 = "CY2018Q4", calendar_quarter3 = "CY2019Q2", calendar_quarter4 = "CY2022Q3", - calendar_quarter5 = "CY2023Q3", + calendar_quarter5 = "CY2023Q3", spectrum_population_calibration = "jibberish"), "spectrum_calibration_option \"jibberish\" not found." ) @@ -319,7 +338,7 @@ test_that("naomi_model_frame() interpolated population depends on quarter specif calendar_quarter2 = "CY2018Q4", calendar_quarter3 = "CY2019Q2", calendar_quarter4 = "CY2022Q3", - calendar_quarter5 = "CY2023Q3", + calendar_quarter5 = "CY2023Q3", spectrum_population_calibration = "subnational") From 879bbaa8b5f53bb74c73fcb7c81b6d36a65f1dbe Mon Sep 17 00:00:00 2001 From: Rob Ashton Date: Wed, 20 Nov 2024 10:35:34 +0000 Subject: [PATCH 2/5] Update error message to make it more understandable --- inst/traduire/en-translation.json | 2 +- tests/testthat/test-04-model-frame.R | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/inst/traduire/en-translation.json b/inst/traduire/en-translation.json index 3a87cc38..4b66a289 100644 --- a/inst/traduire/en-translation.json +++ b/inst/traduire/en-translation.json @@ -43,7 +43,7 @@ "PROGRESS_CALIBRATE": "Calibrating outputs - {{elapsed}} elapsed", "PROGRESS_CALIBRATE_SAVE_OUTPUT": "Saving outputs - {{elapsed}} elapsed", "PROGRESS_CALIBRATE_GENERATE_REPORT": "Generating report - {{elapsed}} elapsed", - "NO_ART_DATA_FOR_QUARTER": "No ART data found for quarter {{calendar_quarter}}.\nSet 'Include ART data' to 'No' if you intend to include no ART data.", + "NO_ART_DATA_FOR_QUARTER": "No ART data found for quarter {{calendar_quarter}}.\nIf you do not intend to include ART data set 'Include ART data' to 'No'.", "ANC_ON_ART_GREATER_THAN_TOTAL_POSITIVE": "ANC testing on ART greater than ANC testing total positive.", "ANC_DATA_MISSING_FOR_YEAR": "ANC testing data not found for year {{missing_year}}.", "ANC_DATA_MISSING_FOR_YEAR_PLURAL": "ANC testing data not found for years {{missing_year}}.", diff --git a/tests/testthat/test-04-model-frame.R b/tests/testthat/test-04-model-frame.R index 74bca9d4..9ee5fbd4 100644 --- a/tests/testthat/test-04-model-frame.R +++ b/tests/testthat/test-04-model-frame.R @@ -41,7 +41,7 @@ test_that("artnum_mf() returns expected number of records", { test_that("artnum_mf() throws errors for invalid inputs", { expect_error(artnum_mf("CY1924Q4", demo_art_number, a_naomi_mf), - "No ART data found for quarter CY1924Q4.\nSet 'Include ART data' to 'No' if you intend to include no ART data.") + "No ART data found for quarter CY1924Q4.\nIf you do not intend to include ART data set 'Include ART data' to 'No'.") expect_error(artnum_mf("CY2016Q1", demo_art_number, "jibberish")) expect_error(artnum_mf(c("CY2016Q1", "CY2016Q2"), demo_art_number, "jibberish")) }) From cd1b5664450c3cd537d9e8ac246c8ab448ab0f8c Mon Sep 17 00:00:00 2001 From: Rob Ashton Date: Thu, 21 Nov 2024 09:46:50 +0000 Subject: [PATCH 3/5] Translate the error messages --- NEWS.md | 2 +- R/model.R | 6 ++---- inst/traduire/en-translation.json | 3 ++- inst/traduire/fr-translation.json | 3 ++- inst/traduire/pt-translation.json | 3 ++- tests/testthat/test-04-model-frame.R | 10 +++++----- 6 files changed, 14 insertions(+), 13 deletions(-) diff --git a/NEWS.md b/NEWS.md index 1ccaa0cd..3501a9d0 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,6 +1,6 @@ # naomi 2.10.2 -* Improve warning generated when user fits model at admin level where no population data exists. +* Improve error generated when user fits model at admin level where no population data exists. # naomi 2.10.1 diff --git a/R/model.R b/R/model.R index 85a6da85..7476025c 100644 --- a/R/model.R +++ b/R/model.R @@ -329,10 +329,8 @@ naomi_model_frame <- function(area_merged, ## of a Spectrum file and then calibrated. Currently no way to know if areas ## comparise only part of a Spectrum file, so can't address. - if(any( mf_areas[["area_id"]] %in% unique(population_agesex$area_id) == FALSE)){ - stop( - "Population data not available for admin level selected for model projections. - Please review model options selection to ensure that area level selection is correct.") + if (!all(mf_areas[["area_id"]] %in% unique(population_agesex$area_id))) { + stop(t_("MISSING_POPULATION_LEVEL")) } pop_subset <- dplyr::filter(population_agesex, area_id %in% mf_areas[["area_id"]]) diff --git a/inst/traduire/en-translation.json b/inst/traduire/en-translation.json index 4b66a289..5544b96c 100644 --- a/inst/traduire/en-translation.json +++ b/inst/traduire/en-translation.json @@ -275,5 +275,6 @@ "DOWNLOAD_COMPARISON_DESCRIPTION": "Naomi comparison report uploaded from Naomi web app", "DOWNLOAD_AGYW_DESCRIPTION": "Naomi AGYW tool uploaded from Naomi web app", "NUMBER_ON_ART": "Number on ART", - "NUMBER_ON_ART_DESC": "Number on ART description" + "NUMBER_ON_ART_DESC": "Number on ART description", + "MISSING_POPULATION_LEVEL": "Population data not available for admin level selected for model projections. Please review model options selection to ensure that area level selection is correct." } diff --git a/inst/traduire/fr-translation.json b/inst/traduire/fr-translation.json index 845a1539..1f307723 100644 --- a/inst/traduire/fr-translation.json +++ b/inst/traduire/fr-translation.json @@ -274,5 +274,6 @@ "DOWNLOAD_SUMMARY_DESCRIPTION": "Rapport de synthèse Naomi téléchargé depuis l'application web Naomi", "DOWNLOAD_COMPARISON_DESCRIPTION": "Rapport de comparaison Naomi téléchargé à partir de l'application web Naomi", "NUMBER_ON_ART": "Nombre de personnes sous TARV", - "NUMBER_ON_ART_DESC": "Number on ART description" + "NUMBER_ON_ART_DESC": "Number on ART description", + "MISSING_POPULATION_LEVEL": "Les données de population ne sont pas disponibles pour le niveau admin sélectionné pour les projections du modèle. Veuillez revoir la sélection des options du modèle pour vous assurer que la sélection du niveau de la zone est correcte." } diff --git a/inst/traduire/pt-translation.json b/inst/traduire/pt-translation.json index add5e8a0..a6f7768c 100644 --- a/inst/traduire/pt-translation.json +++ b/inst/traduire/pt-translation.json @@ -274,5 +274,6 @@ "DOWNLOAD_SUMMARY_DESCRIPTION": "Relatório de síntese da Naomi carregado da aplicação web Naomi", "DOWNLOAD_COMPARISON_DESCRIPTION": "Relatório de comparação Naomi carregado a partir da aplicação web Naomi", "NUMBER_ON_ART": "Nombre de personnes sous TARV", - "NUMBER_ON_ART_DESC": "Number on ART description" + "NUMBER_ON_ART_DESC": "Number on ART description", + "MISSING_POPULATION_LEVEL": "Os dados da população não estão disponíveis para o nível administrativo selecionado para as projecções do modelo. Rever a seleção das opções do modelo para garantir que a seleção do nível de área está correta." } diff --git a/tests/testthat/test-04-model-frame.R b/tests/testthat/test-04-model-frame.R index 9ee5fbd4..bdfe451e 100644 --- a/tests/testthat/test-04-model-frame.R +++ b/tests/testthat/test-04-model-frame.R @@ -54,7 +54,6 @@ test_that("artnum_mf() works with single quarter ART data", { test_that("Informative error displayed when model run to admin level higher/lower than population data supplied", { - x <- expect_error( naomi_model_frame(a_area_merged, demo_population_agesex, @@ -67,11 +66,12 @@ test_that("Informative error displayed when model run to admin level higher/lowe calendar_quarter4 = "CY2022Q3", calendar_quarter5 = "CY2023Q3")) - - expect_equal(x$message, - "Population data not available for admin level selected for model projections.\n Please review model options selection to ensure that area level selection is correct." + expect_equal( + x$message, + paste("Population data not available for admin level selected", + "for model projections. Please review model options", + "selection to ensure that area level selection is correct.") ) - }) test_that("population calibration options", { From d11c86ebf841350e44907fad28d8451eaa3fa16b Mon Sep 17 00:00:00 2001 From: rtesra <70330391+rtesra@users.noreply.github.com> Date: Fri, 29 Nov 2024 17:01:26 +0200 Subject: [PATCH 4/5] make error more infromative --- R/model.R | 16 +++++++++++++++- inst/traduire/en-translation.json | 2 +- inst/traduire/fr-translation.json | 3 ++- inst/traduire/pt-translation.json | 3 ++- tests/testthat/test-02-model-options.R | 22 ++++++++++++++++++++++ 5 files changed, 42 insertions(+), 4 deletions(-) diff --git a/R/model.R b/R/model.R index 7476025c..c016a441 100644 --- a/R/model.R +++ b/R/model.R @@ -330,7 +330,21 @@ naomi_model_frame <- function(area_merged, ## comparise only part of a Spectrum file, so can't address. if (!all(mf_areas[["area_id"]] %in% unique(population_agesex$area_id))) { - stop(t_("MISSING_POPULATION_LEVEL")) + + area_label <- area_merged |> sf::st_drop_geometry() |> + dplyr::select(area_level_label, area_level, area_id) + + # Get level label for pop data + pop_label <- population_agesex |> + dplyr::left_join(area_label, by = dplyr::join_by(area_id)) + pop_level <- unique(pop_label$area_level_label) + + # Get area level label for model estimates + model_level <- unique(area_label[area_label$area_level== level,]$area_level_label) + + stop(t_("MISSING_POP_LEVEL", + list(pop_level = paste(pop_level, collapse = ", "), + model_level = model_level))) } pop_subset <- dplyr::filter(population_agesex, area_id %in% mf_areas[["area_id"]]) diff --git a/inst/traduire/en-translation.json b/inst/traduire/en-translation.json index 5544b96c..c64d1763 100644 --- a/inst/traduire/en-translation.json +++ b/inst/traduire/en-translation.json @@ -276,5 +276,5 @@ "DOWNLOAD_AGYW_DESCRIPTION": "Naomi AGYW tool uploaded from Naomi web app", "NUMBER_ON_ART": "Number on ART", "NUMBER_ON_ART_DESC": "Number on ART description", - "MISSING_POPULATION_LEVEL": "Population data not available for admin level selected for model projections. Please review model options selection to ensure that area level selection is correct." + "MISSING_POP_LEVEL": "Unable to generate model estimates at the {{model_level}} level because population data only available at the {{pop_level}} level/s. Please review model options or population data inputs." } diff --git a/inst/traduire/fr-translation.json b/inst/traduire/fr-translation.json index 1f307723..444d7512 100644 --- a/inst/traduire/fr-translation.json +++ b/inst/traduire/fr-translation.json @@ -275,5 +275,6 @@ "DOWNLOAD_COMPARISON_DESCRIPTION": "Rapport de comparaison Naomi téléchargé à partir de l'application web Naomi", "NUMBER_ON_ART": "Nombre de personnes sous TARV", "NUMBER_ON_ART_DESC": "Number on ART description", - "MISSING_POPULATION_LEVEL": "Les données de population ne sont pas disponibles pour le niveau admin sélectionné pour les projections du modèle. Veuillez revoir la sélection des options du modèle pour vous assurer que la sélection du niveau de la zone est correcte." + "MISSING_POPULATION_LEVEL": "Les données de population ne sont pas disponibles pour le niveau admin sélectionné pour les projections du modèle. Veuillez revoir la sélection des options du modèle pour vous assurer que la sélection du niveau de la zone est correcte.", + "MISSING_POP_LEVEL": "Unable to generate model estimates at the {{model_level}} level because population data only available at the {{pop_level}} level/s. Please review model options or population data inputs." } diff --git a/inst/traduire/pt-translation.json b/inst/traduire/pt-translation.json index a6f7768c..131e0833 100644 --- a/inst/traduire/pt-translation.json +++ b/inst/traduire/pt-translation.json @@ -275,5 +275,6 @@ "DOWNLOAD_COMPARISON_DESCRIPTION": "Relatório de comparação Naomi carregado a partir da aplicação web Naomi", "NUMBER_ON_ART": "Nombre de personnes sous TARV", "NUMBER_ON_ART_DESC": "Number on ART description", - "MISSING_POPULATION_LEVEL": "Os dados da população não estão disponíveis para o nível administrativo selecionado para as projecções do modelo. Rever a seleção das opções do modelo para garantir que a seleção do nível de área está correta." + "MISSING_POPULATION_LEVEL": "Os dados da população não estão disponíveis para o nível administrativo selecionado para as projecções do modelo. Rever a seleção das opções do modelo para garantir que a seleção do nível de área está correta.", + "MISSING_POP_LEVEL": "Unable to generate model estimates at the {{model_level}} level because population data only available at the {{pop_level}} level/s. Please review model options or population data inputs." } diff --git a/tests/testthat/test-02-model-options.R b/tests/testthat/test-02-model-options.R index e96f421c..18f67690 100644 --- a/tests/testthat/test-02-model-options.R +++ b/tests/testthat/test-02-model-options.R @@ -298,3 +298,25 @@ test_that("Handle backwards regression when T4 and T5 options are missing", { expect_equal(t5 - t3, 9) }) + +test_that("Population data available for area level set in model options", { + + expect_error(naomi_model_frame(a_area_merged, + demo_population_agesex, + a_spec, + scope = "MWI_1_1_demo", + level = 3, + calendar_quarter1 = "CY2016Q1", + calendar_quarter2 = "CY2018Q4", + calendar_quarter3 = "CY2019Q2", + calendar_quarter4 = "CY2022Q3", + calendar_quarter5 = "CY2023Q3", + artattend = FALSE, + spectrum_population_calibration = "none", + psnu_level = NULL), + paste("Unable to generate model estimates at the District level because", + "population data only available at the District + Metro level/s.", + "Please review model options or population data inputs.")) + + +}) From 82fbc90829a893bfed3682a03e91975449fc5a4b Mon Sep 17 00:00:00 2001 From: rtesra <70330391+rtesra@users.noreply.github.com> Date: Fri, 29 Nov 2024 18:14:08 +0200 Subject: [PATCH 5/5] fix failing test --- tests/testthat/test-02-model-options.R | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/testthat/test-02-model-options.R b/tests/testthat/test-02-model-options.R index 18f67690..47b057fe 100644 --- a/tests/testthat/test-02-model-options.R +++ b/tests/testthat/test-02-model-options.R @@ -316,7 +316,8 @@ test_that("Population data available for area level set in model options", { psnu_level = NULL), paste("Unable to generate model estimates at the District level because", "population data only available at the District + Metro level/s.", - "Please review model options or population data inputs.")) + "Please review model options or population data inputs."), + fixed = TRUE) })