Skip to content

Commit 516c7bb

Browse files
Merge pull request #5 from WorldHealthOrganization/chore/warning-improvements
Improve small details
2 parents 09ad04f + 01d572e commit 516c7bb

8 files changed

Lines changed: 112 additions & 30 deletions

R/classifications.R

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,8 @@
88
#' . If missing, prevalence will not be calculated for any biomarker because micronutrient status cut offs are sex-specific.
99
#' @param age A vector of ages in years for the individuals in the dataset. It can also be a \code{lubridate::duration} object which is then converted to years. For example: if you have age in months, you can create a lubridate duration object like this \code{lubridate::duration(age_in_months, units = "months")}.
1010
#' @param pregnancy_status (Optional) A vector indicating pregnancy status. Accepted values: For Yes ("Y", "y", or "1"), No ("N", "n", or "2"), Unknown ("unk" or "3" or blank).
11-
#' When Unknown ("unk" or "3" or blank), it will be categorized as "not pregnant"
11+
#' When Unknown ("unk" or "3" or blank), it will be categorized as "not pregnant".
12+
#' Note that 'pregnancy_status' should not be missing when 'pregnancyweeks' or 'pregnancymonths' contain valid, non-missing values. Missing 'pregnancy_status' in these cases will be considered as 'not pregnant'.
1213
#' @param lactating_status (Optional) A vector indicating lactation status. Accepted values: For Yes ("Y", "y", or "1"), No ("N", "n", or "2").
1314
#' @param pregnancyweeks (Optional) A numeric vector indicating the number of weeks of pregnancy.
1415
#' @param pregnancymonths (Optional) A numeric vector indicating the number of months of pregnancy.
@@ -136,7 +137,7 @@ classify_data_internal <- function(
136137
malaria = malaria
137138
)
138139
cols <- names(concept_list$values)
139-
140+
validate_concepts(concept_list)
140141
values <- lapply(indicators, function(x) {
141142
value_concept <- indicator_value_concept(x)
142143
if (is.null(value_concept)) {
@@ -153,10 +154,49 @@ classify_data_internal <- function(
153154
}
154155
colnames(df) <- paste0("indicator_", colnames(df))
155156
concept_df <- dplyr::bind_cols(concept_list$values[concept_list$non_nulls])
157+
# age is part of the output in years and months
158+
concept_df$age_years <- as.numeric(concept_df$age, "years")
159+
concept_df$age_months <- as.numeric(concept_df$age, "months")
160+
concept_df$age <- NULL
161+
concept_df <- concept_df[, c(
162+
c("age_years", "age_months"),
163+
setdiff(colnames(concept_df), c("age_years", "age_months"))
164+
)]
156165
colnames(concept_df) <- paste0("input_", colnames(concept_df))
157166
dplyr::bind_cols(concept_df, df)
158167
}
159168

169+
# validate_concepts does some general prechecks independent of
170+
# the actual indicators being used.
171+
validate_concepts <- function(concepts) {
172+
is_smoker <- concepts$values$is_smoker
173+
smokes_cigarettes_per_day <- concepts$values$smokes_cigarettes_per_day
174+
if (!is.null(is_smoker) && !is.null(smokes_cigarettes_per_day)) {
175+
if (any(is.na(is_smoker) & !is.na(smokes_cigarettes_per_day))) {
176+
warning(
177+
"Missing `is_smoker`: a non NA value for `is_smoker` is required when `smokes_cigarettes_per_day` is not NA."
178+
)
179+
}
180+
}
181+
pregnancy_status <- concepts$values$pregnancy_status
182+
pregnancyweeks <- concepts$values$pregnancyweeks
183+
pregnancymonths <- concepts$values$pregnancymonths
184+
if (!is.null(pregnancy_status) && !is.null(pregnancyweeks)) {
185+
if (any(is.na(pregnancy_status) & !is.na(pregnancyweeks))) {
186+
warning(
187+
"Missing `pregnancy_status`: a non NA value for `pregnancy_status` is required when `pregnancyweeks` is not NA."
188+
)
189+
}
190+
}
191+
if (!is.null(pregnancy_status) && !is.null(pregnancymonths)) {
192+
if (any(is.na(pregnancy_status) & !is.na(pregnancymonths))) {
193+
warning(
194+
"Missing `pregnancy_status`: a non NA value for `pregnancy_status` is required when `pregnancymonths` is not NA."
195+
)
196+
}
197+
}
198+
}
199+
160200
validate_indicators <- function(indicators) {
161201
stopifnot(is.list(indicators))
162202
stopifnot(all(vapply(

R/indicators-anaemia.R

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ anaemia_adjustment <- function(
2020
length(altitude) == length(is_smoker),
2121
length(is_smoker) == length(smokes_cigarettes_per_day)
2222
)
23-
2423
altitude <- as.numeric(altitude)
2524
altitude[is.na(altitude)] <- 0
2625
altitude_adjustments <- (0.0056384 * altitude) + (0.0000003 * altitude^2)
@@ -275,10 +274,5 @@ anaemia_indicator <- indicator(
275274
reorder_columns = list(
276275
short = NULL,
277276
long = NULL
278-
),
279-
plot_settings = list(
280-
dot_plot = list(
281-
show_ci = TRUE
282-
)
283277
)
284278
)

R/indicators-iodine.R

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,5 @@ iodine_indicator <- indicator(
131131
prevalence_reports = list(
132132
long = FALSE,
133133
short = TRUE
134-
),
135-
plot_settings = list(
136-
dot_plot = list(
137-
show_ci = FALSE
138-
)
139134
)
140135
)

R/indicators.R

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ indicator <- function(
1515
drop_columns = NULL,
1616
rename_columns = NULL,
1717
reorder_columns = NULL,
18-
plot_settings = NULL,
1918
prevalence_reports = list(
2019
long = TRUE,
2120
short = TRUE
@@ -52,7 +51,6 @@ indicator <- function(
5251
drop_columns = drop_columns,
5352
rename_columns = rename_columns,
5453
reorder_columns = reorder_columns,
55-
plot_settings = plot_settings,
5654
parent_env = envir
5755
),
5856
class = "indicator"
@@ -105,12 +103,6 @@ indicator_prevalence_names <- function(indicator) {
105103
indicator$prevalence_category_names
106104
}
107105

108-
109-
indicator_plot_settings <- function(indicator) {
110-
stopifnot(is_indicator(indicator))
111-
indicator$plot_settings
112-
}
113-
114106
prevalence_report_long <- function(indicator) {
115107
isTRUE(indicator$prevalence_report$long)
116108
}

man/individual_classification.Rd

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/micronutrients_stats.Rd

Lines changed: 2 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

tests/testthat/helper.R

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ random_datset <- function(n) {
66
age_years = pmax(0, rnorm(n, mean = 20, sd = 10)),
77
sex = sample(c(1, 2), size = n, replace = TRUE, prob = c(0.1, 0.9)),
88
pregnancy_status = sample(
9-
c(1L, 2L, NA_integer_),
9+
c(1L, 2L),
1010
size = n,
1111
replace = TRUE,
12-
prob = c(0.1, 0.89, 0.01)
12+
prob = c(0.1, 0.9)
1313
),
1414
pregnancyweeks = sample(1:(9 * 4), size = n, replace = TRUE),
1515
pregnancymonths = sample(1:9, size = n, replace = TRUE),
@@ -25,10 +25,10 @@ random_datset <- function(n) {
2525
agp_measurement = pmax(0.1, rnorm(n, mean = 0.5, sd = 0.5)),
2626
haemoglobin_measurement = pmax(0.1, rnorm(n, mean = 100, sd = 50)),
2727
is_smoker = sample(
28-
c(1L, 2L, NA_integer_),
28+
c(1L, 2L),
2929
size = n,
3030
replace = TRUE,
31-
prob = c(0.1, 0.89, 0.01)
31+
prob = c(0.1, 0.90)
3232
),
3333
smokes_cigarettes_per_day = rpois(n, 3),
3434
altitude = pmax(0, rnorm(n, mean = 500, sd = 1000)),

tests/testthat/test-classification.R

Lines changed: 62 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ test_that("row level classification works", {
3131
expect_equal(
3232
colnames(res),
3333
c(
34-
"input_age",
34+
"input_age_years",
35+
"input_age_months",
3536
"input_sex",
3637
"input_pregnancy_status",
3738
"input_pregnancyweeks",
@@ -82,7 +83,6 @@ test_that("optional values have their prototype values", {
8283
)))
8384
expect_true(all(
8485
c(
85-
"input_age",
8686
"input_sex",
8787
"input_ferritin",
8888
"input_iodine",
@@ -185,5 +185,64 @@ test_that("you can use lubridate to define the age", {
185185
AGP = testdata$agp_measurement
186186
)
187187
expect_true(is.data.frame(res))
188-
expect_true(is.duration(res$input_age))
188+
expect_equal(res$input_age_years, as.numeric(age, "years"))
189+
expect_equal(res$input_age_months, as.numeric(age, "months"))
190+
})
191+
192+
test_that("it warns if `is_smoker` is NULL but `smokes_cigarattes_per_day` is not", {
193+
testdata <- random_datset(100)
194+
expect_warning(
195+
individual_classification(
196+
indicators = list(
197+
indicator_anaemia()
198+
),
199+
age = testdata$age_years,
200+
sex = testdata$sex,
201+
iodine = testdata$iodine,
202+
haemoglobin = testdata$haemoglobin_measurement,
203+
altitude = testdata$altitude,
204+
smokes_cigarettes_per_day = testdata$smokes_cigarettes_per_day
205+
),
206+
regexp = "is_smoker"
207+
)
208+
})
209+
210+
test_that("it warns if `pregnancy_status` is NULL but other preganancy related variables have values", {
211+
testdata <- random_datset(100)
212+
expect_warning(
213+
expect_warning(
214+
individual_classification(
215+
indicators = list(
216+
indicator_anaemia()
217+
),
218+
age = testdata$age_years,
219+
sex = testdata$sex,
220+
iodine = testdata$iodine,
221+
haemoglobin = testdata$haemoglobin_measurement,
222+
altitude = testdata$altitude,
223+
pregnancyweeks = testdata$pregnancyweeks,
224+
pregnancymonths = testdata$pregnancymonths
225+
),
226+
regexp = "pregnancyweeks"
227+
),
228+
regexp = "pregnancymonths"
229+
)
230+
})
231+
232+
test_that("age is in years and months in the output", {
233+
testdata <- random_datset(100)
234+
res <- individual_classification(
235+
indicators = list(
236+
indicator_anaemia()
237+
),
238+
age = testdata$age_years,
239+
sex = testdata$sex,
240+
ferritin = testdata$ferritin_measurement,
241+
haemoglobin = testdata$haemoglobin_measurement,
242+
iodine = testdata$iodine,
243+
altitude = testdata$altitude
244+
)
245+
expect_contains(colnames(res), c("input_age_years", "input_age_months"))
246+
expect_null(res[["input_age"]])
247+
expect_true(all(res$input_age_months >= res$input_age_years))
189248
})

0 commit comments

Comments
 (0)