# Test ability to calculate specific rates ---------------------------
# define necessary arguments
counts <- c(1, 2, 3, 4, 5)
popn <- c(10, 50, 100, 500, 1000)
df <- data.frame(counts, popn)
test_that("rates can be calculated when all arguments are valid", {
expect_equal(get_spec_rt(counts, popn, scale = 1000), c(100, 40, 30, 8, 5))
expect_equal(get_spec_rt(counts, popn, power = 3), c(100, 40, 30, 8, 5))
})
test_that("rates can be calculated when neither `scale` nor `power` is provided", {
expect_equal(get_spec_rt(counts, popn), c(0.1, 0.04, 0.03, 0.008, 0.005))
})
test_that("rates can be calculated when vectors are extracted from a data frame", {
expect_equal(get_spec_rt(df$counts, df$popn, scale = 1000), c(100, 40, 30, 8, 5))
})
test_that("function works with dplyr::mutate()", {
df <- df %>%
dplyr::mutate(spec_rate = get_spec_rt(counts, popn, power = 5))
expect_equal(df$spec_rate, c(10000, 4000, 3000, 800, 500))
})
# define a problematic vector
char_vec <- c("apple", "banana", "carrot", "dragonfruit", "eggplant")
test_that("function throws an error when `counts` isn't valid", {
expect_error(
get_spec_rt(char_vec, popn),
"`counts` must be a numeric vector of non-negative integers"
)
expect_error(
get_spec_rt(c(-1, 2, 3, 4, 5), popn),
"`counts` must be a numeric vector of non-negative integers"
)
})
test_that("function throws an error when `popn` isn't valid", {
expect_error(
get_spec_rt(counts, char_vec),
"`popn` must be a numeric vector of non-negative integers"
)
expect_error(
get_spec_rt(counts, c(-10, 50, 100, 500, 1000)),
"`popn` must be a numeric vector of non-negative integers"
)
})
test_that("function throws an error when vectors aren't the same length", {
expect_error(
get_spec_rt(counts, popn[1:4]),
"`counts` and `popn` must be the same length"
)
})
test_that("function throws an error when both `scale` and `power` are supplied", {
expect_error(
get_spec_rt(counts, popn, scale = 100000, power = 5),
"must supply exactly one of `scale` and `power`"
)
})
test_that("function throws an error when `scale` isn't valid", {
expect_error(
get_spec_rt(counts, popn, scale = "hello"),
"`scale` must be a positive integer of length 1"
)
expect_error(
get_spec_rt(counts, popn, scale = c(1, 1000)),
"`scale` must be a positive integer of length 1"
)
expect_error(
get_spec_rt(counts, popn, scale = 0),
"`scale` must be a positive integer of length 1"
)
expect_error(
get_spec_rt(counts, popn, scale = -1),
"`scale` must be a positive integer of length 1"
)
expect_error(
get_spec_rt(counts, popn, scale = 0.1),
"`scale` must be a positive integer of length 1"
)
})
test_that("function throws an error when `power` isn't valid", {
expect_error(
get_spec_rt(counts, popn, power = "hello"),
"`power` must be a non-negative integer of length 1"
)
expect_error(
get_spec_rt(counts, popn, power = c(1, 2, 3)),
"`power` must be a non-negative integer of length 1"
)
expect_error(
get_spec_rt(counts, popn, power = -1),
"`power` must be a non-negative integer of length 1"
)
expect_error(
get_spec_rt(counts, popn, power = 0.1),
"`power` must be a non-negative integer of length 1"
)
})
# define vectors with NA
counts_na <- c(NA, 2, 3, 4, 5)
popn_na <- c(NA, 50, 100, 500, 1000)
test_that("function raises a warning when one or more elements in the inputs are NA", {
expect_warning(
get_spec_rt(counts_na, popn),
"one or more elements in `counts` and/or `popn` are NA, pass `output_status = TRUE` to check"
)
expect_warning(
get_spec_rt(counts, popn_na),
"one or more elements in `counts` and/or `popn` are NA, pass `output_status = TRUE` to check"
)
expect_warning(
get_spec_rt(counts_na, popn_na),
"one or more elements in `counts` and/or `popn` are NA, pass `output_status = TRUE` to check"
)
})
# define vectors with 0
popn_0 <- c(0, 50, 100, 500, 1000)
popn_0s <- c(0, 0, 0, 0, 0)
test_that("function raises a warning when one or more elements in `popn` are 0", {
expect_warning(
get_spec_rt(counts, popn_0),
"one or more elements in `popn` are 0, pass `output_status = TRUE` to check"
)
expect_warning(
get_spec_rt(counts, popn_0s),
"one or more elements in `popn` are 0, pass `output_status = TRUE` to check"
)
})
test_that("function raises both warnings, if necessary", {
warnings <- capture_warnings(get_spec_rt(counts_na, popn_0s))
expect_equal(2, length(warnings))
expect_equal(
warnings[1],
"one or more elements in `counts` and/or `popn` are NA, pass `output_status = TRUE` to check"
)
expect_equal(
warnings[2],
"one or more elements in `popn` are 0, pass `output_status = TRUE` to check"
)
})
test_that("function outputs expected statuses", {
expect_equal(
get_spec_rt(counts, popn, output_status = TRUE)$status,
c("success", "success", "success", "success", "success")
)
expect_equal(
get_spec_rt(c(0, 0, 0, NA), c(0, NA, 10, 0), output_status = TRUE)$status,
c("denom_0", "has_NA", "success", "has_NA")
)
expect_equal(
get_spec_rt(c(NA, 10, 100, 1000), c(10, 0, NA, 10000), output_status = TRUE)$status,
c("has_NA", "denom_0", "has_NA", "success")
)
})
# Test ability to calculate confidence intervals ---------------------------
test_that("function throws an error when `dist` is supplied, but not `interval`, and vice versa", {
expect_error(
get_spec_rt(counts, popn, power = 3, interval = 0.95),
"both `dist` and `interval` must be supplied to construct confidence intervals"
)
expect_error(
get_spec_rt(counts, popn, power = 3, dist = "normal"),
"both `dist` and `interval` must be supplied to construct confidence intervals"
)
})
test_that("function throws an error when user provides unsupported distribution name", {
expect_error(
get_spec_rt(counts = counts, popn = popn, power = 5, dist = "gamma", interval = 0.9),
"`dist` should be one of 'normal', 'log normal', or 'poisson'"
)
})
test_that("limits are NA when specific rates evaluate to 0", {
counts_0 <- c(0, 50, 55, 60, 65)
# using the normal distribution
# suppressing warning saying this distribution should be avoided
suppressWarnings(get_spec_rt(counts_0, popn, power = 3, dist = "normal", interval = 0.95)) %>%
dplyr::mutate(is_expected = dplyr::if_else(
rate == 0,
is.na(lower) & is.na(upper), # if rate is 0, check that limits are NA
is.finite(lower) & is.finite(upper)
)) %>%
# otherwise, check that limits are finite
dplyr::pull(is_expected) %>%
all() %>%
# should be all TRUE
expect_true()
# using the log normal distribution
get_spec_rt(counts_0, popn, scale = 100000, dist = "lognormal", interval = 0.9) %>%
dplyr::mutate(is_expected = dplyr::if_else(
rate == 0,
is.na(lower) & is.na(upper), # if rate is 0, check that limits are NA
is.finite(lower) & is.finite(upper)
)) %>%
# otherwise, check that limits are finite
dplyr::pull(is_expected) %>%
all() %>%
# should be all TRUE
expect_true()
})
test_that("limits are NA when specific rates evaluate to NA", {
# using the normal distribution
suppressWarnings(get_spec_rt(c(1, NA, NA, 4, 5), popn, power = 3, dist = "normal", interval = 0.9)) %>%
dplyr::mutate(is_expected = dplyr::if_else(
is.na(rate),
is.na(lower) & is.na(upper), # if rate is NA, check that limits are also NA
is.finite(lower) & is.finite(upper)
)) %>%
# otherwise, limits should be finite numbers
dplyr::pull(is_expected) %>%
# expect all strata to evaluate to TRUE
all() %>%
expect_true()
# using the Poisson distribution
suppressWarnings(get_spec_rt(c(1, NA, NA, 4, 5), popn, power = 3, dist = "poisson", interval = 0.99)) %>%
dplyr::mutate(is_expected = dplyr::if_else(
is.na(rate),
is.na(lower) & is.na(upper),
is.finite(lower) & is.finite(upper)
)) %>%
dplyr::pull(is_expected) %>%
all() %>%
expect_true()
})
test_that("multipliers are applied correctly", {
expect_equal(
get_spec_rt(counts, popn, power = 3, dist = "lognormal", interval = 0.95),
get_spec_rt(counts, popn, dist = "lognormal", interval = 0.95) %>%
dplyr::mutate(dplyr::across(-interval, .fns = ~ .x * 1000))
)
expect_equal(
get_spec_rt(counts, popn, scale = 100000, dist = "poisson", interval = 0.9),
get_spec_rt(counts, popn, dist = "poisson", interval = 0.9) %>%
dplyr::mutate(dplyr::across(-interval, .fns = ~ .x * 100000))
)
})
test_that("type and shape of output data are as expected based on input", {
# Option A: no confidence intervals, no output status
output_a <- get_spec_rt(counts, popn, scale = 1000)
expect_true(is.double(output_a))
expect_false(is.data.frame(output_a))
# Option B: no confidence intervals, include output status
output_b <- get_spec_rt(counts, popn, scale = 1000, output_status = TRUE)
expect_true(is.data.frame(output_b))
expect_equal(ncol(output_b), 2)
expect_true(setequal(c("rate", "status"), colnames(output_b)))
# Option C: confidence intervals, no output status
output_c <- get_spec_rt(c(30, 40, 50, 60, 70), c(1000, 1200, 1400, 1600, 1800), scale = 1000, dist = "normal", interval = 0.99)
expect_true(is.data.frame(output_c))
expect_equal(ncol(output_c), 4)
expect_true(setequal(c("rate", "interval", "lower", "upper"), colnames(output_c)))
# Option D: confidence intervals, include output status
output_d <- get_spec_rt(c(30, 40, 50, 60, 70), c(1000, 1200, 1400, 1600, 1800), scale = 1000, dist = "normal", interval = 0.99, output_status = TRUE)
expect_true(is.data.frame(output_d))
expect_equal(ncol(output_d), 5)
expect_true(setequal(c("rate", "interval", "lower", "upper", "status"), colnames(output_d)))
})
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.