Skip to content

Commit

Permalink
refactor estimators and create tests for boot_bw; fix #32; fix #36
Browse files Browse the repository at this point in the history
  • Loading branch information
ernestguevarra committed Jan 6, 2025
1 parent 9673fa1 commit 4ea5c13
Show file tree
Hide file tree
Showing 13 changed files with 181 additions and 26 deletions.
1 change: 1 addition & 0 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ License: GPL-3
Depends: R (>= 3.0.1)
Imports:
car,
cli,
doParallel,
foreach,
parallel,
Expand Down
3 changes: 3 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ export(boot_bw_weight)
export(recode)
importFrom(car,bcPower)
importFrom(car,powerTransform)
importFrom(cli,cli_abort)
importFrom(cli,cli_alert_success)
importFrom(cli,cli_bullets)
importFrom(doParallel,registerDoParallel)
importFrom(foreach,"%dopar%")
importFrom(foreach,foreach)
Expand Down
1 change: 1 addition & 0 deletions R/bbw.R
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
#' @importFrom parallel makeCluster
#' @importFrom foreach foreach %dopar%
#' @importFrom doParallel registerDoParallel
#' @importFrom cli cli_abort cli_bullets cli_alert_success
#'
"_PACKAGE"

Expand Down
19 changes: 16 additions & 3 deletions R/bootClassic.R
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,29 @@
#'
#' @examples
#' # Example call to bootClassic function
#'
#' meanResults <- bootClassic(x = indicatorsHH, params = "anc1")
#' sampled_clusters <- boot_bw_sample_clusters(
#' x = indicatorsHH, w = boot_bw_weight(villageData)
#' )
#'
#' boot <- boot_bw_sample_within_clusters(sampled_clusters)
#'
#' bootClassic(boot, "anc1")
#'
#' @export
#'

bootClassic <- function(x, params) {
## Check params ----
params <- check_params(x = x, params = params)

## Create concatenating vector ----
result <- vector(mode = "numeric", length = length(params))

## Apply mean to each param ----
for(i in seq_len(length(params))) {
result[i] <- mean(x[[params[i]]], na.rm = TRUE)
}
return(result)

## Return result ----
result
}
29 changes: 17 additions & 12 deletions R/bootProbit.R
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
################################################################################
#
#'
#' PROBIT statistics function for bootstrap estimation
#'
#' @param x A data frame with **primary sampling unit (PSU)** in column named
Expand All @@ -14,39 +13,45 @@
#' of interest with length equal to `length(params)`
#'
#' @examples
#'
#' # Example call to bootBW function:
#'
#' bootPROBIT(x = indicatorsCH1,
#' sampled_clusters <- boot_bw_sample_clusters(
#' x = indicatorsCH1, w = boot_bw_weight(villageData)
#' )
#'
#' boot <- boot_bw_sample_within_clusters(sampled_clusters)
#'
#' bootPROBIT(x = boot,
#' params = "muac1",
#' threshold = 115)
#'
#' @export
#'
#
################################################################################

bootPROBIT <- function(x, params, threshold = THRESHOLD) {
## Check params ----
params <- check_params(x = x, params = params)

## Get data
d <- x[[params[1]]]

## Shift data to the left to avoid "commutation instability" when :
## Shift data to the left to avoid "commutation instability" when : ----
## max(x) / min(x)
## is small (i.e. close to unity).
shift <- min(min(d, na.rm = TRUE), threshold) - 1
d <- d - shift
threshold <- threshold - shift

## Box-cox transformation
## Box-cox transformation ----
lambda <- car::powerTransform(d)$lambda
d <- car::bcPower(d, lambda)
threshold <- car::bcPower(threshold, lambda)
m <- mean(d, na.rm = TRUE)
s <- stats::sd(d, na.rm = T)

## PROBIT estimate
## PROBIT estimate ----
x <- stats::pnorm(q = threshold, mean = m, sd = s)
names(x) <- NULL

## Return x
return(x)
## Return x ----
x
}
62 changes: 62 additions & 0 deletions R/utils.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
#'
#' Check variables
#'
#' @keywords internal
#'

check_params <- function(x, params) {
params_in <- params[which(params %in% names(x))]
params_out <- params[which(!params %in% names(x))]

if (length(params_in) == 0) {
if (length(params) > 1) {
cli::cli_abort(
"{.val {params}} are not variables in {.arg x}"
)
} else {
cli::cli_abort(
"{.val {params}} is not a variable in {.arg x}"
)
}
} else {
if (length(params_in) == length(params)) {
if (length(params) == 1) {
cli::cli_alert_success(
"{.val {params}} is a variable in {.arg x}"
)
} else {
cli::cli_alert_success(
"{.val {params}} are variables in {.arg x}"
)
}
} else {
if (length(params_in) == 1) {
cli::cli_bullets(
c(
"v" = "{.val {params_in}} is a variable in {.arg x}",
"!" = ifelse(
length(params_out) > 1,
"{.val {params_out}} are not variables in {.arg x}",
"{.val {params_out}} is not a variable in {.arg x}"
),
"i" = "Returning {.val {params_in}}"
)
)
} else {
cli::cli_bullets(
c(
"v" = "{.val {params_in}} are variables in {.arg x}",
"!" = ifelse(
length(params_out) > 1,
"{.val {params_out}} are not variables in {.arg x}",
"{.val {params_out}} is not a variable in {.arg x}"
),
"i" = "Returning {.val {params_in}}"
)
)
}
}
}

params_in
}
1 change: 1 addition & 0 deletions inst/WORDLIST
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ PSU
PSUs
RapidSurveys
Ruel
codecov
doi
ncol
nrow
Expand Down
7 changes: 6 additions & 1 deletion man/bootClassic.Rd

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

8 changes: 6 additions & 2 deletions man/bootPROBIT.Rd

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

12 changes: 12 additions & 0 deletions man/check_params.Rd

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

27 changes: 27 additions & 0 deletions tests/testthat/test-boot_bw.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# Tests for boot_bw functions --------------------------------------------------

test_that("boot_bw_weight works as expected", {
expect_s3_class(boot_bw_weight(villageData), "data.frame")
expect_true(
all(
c("psu", "pop", "weight", "cumWeight") %in%
names(boot_bw_weight(villageData))
)
)
expect_type(
boot_bw_sample_clusters(
indicatorsHH, w = boot_bw_weight(villageData), index = TRUE
),
"integer"
)
})

mean_boot <- boot_bw(
x = indicatorsHH, w = boot_bw_weight(villageData),
statistic = bootClassic, params = "anc1", replicates = 9
)

test_that("boot_bw works as expected", {
expect_s3_class(mean_boot, "data.frame")
})

24 changes: 19 additions & 5 deletions tests/testthat/test_bootClassic.R
Original file line number Diff line number Diff line change
@@ -1,13 +1,27 @@
library(bbw)
context("Bootstrap function for means/proportions")
# Tests for bootClassic --------------------------------------------------------

xMean <- bootClassic(x = indicatorsHH,
params = c("anc1", "anc2", "anc3", "anc4"))
boot <- boot_bw_sample_clusters(
indicatorsHH, boot_bw_weight(villageData)
) |>
boot_bw_sample_within_clusters()

xMean <- bootClassic(
x = boot, params = c("anc1", "anc2", "anc3", "anc4")
)

test_that("xMean is a numeric vector", {
expect_is(xMean, "numeric")
expect_type(xMean, "double")
})

test_that("xMean length is length of params", {
expect_equal(length(xMean), 4)
})

test_that("bootClassic errors and messages as expected", {
expect_error(bootClassic(boot, c("anc")))
expect_message(bootClassic(boot, c("anc", "anc1")))
expect_message(bootClassic(boot, c("anc", "anc1", "anc2")))
expect_message(bootClassic(boot, c("anc", "test", "anc1", "anc2")))
})


13 changes: 10 additions & 3 deletions tests/testthat/test_bootProbit.R
Original file line number Diff line number Diff line change
@@ -1,10 +1,17 @@
library(bbw)
context("Bootstrap function for PROBIT")
# Tests for bootPROBIT ---------------------------------------------------------

xProbit <- bootPROBIT(x = indicatorsCH1,
boot <- boot_bw_sample_clusters(indicatorsCH1, boot_bw_weight(villageData)) |>
boot_bw_sample_within_clusters()

xProbit <- bootPROBIT(x = boot,
params = "muac1",
threshold = 115)

test_that("xProbit is a numeric vector", {
expect_is(xProbit, "numeric")
})

test_that("bootPROBIT errors and messages work as expected", {
expect_error(bootPROBIT(boot, "test"))
expect_error(bootPROBIT(boot, c("test", "not")))
})

0 comments on commit 4ea5c13

Please sign in to comment.