diff --git a/NEWS.md b/NEWS.md index ee60e7806f..09d96bc3db 100644 --- a/NEWS.md +++ b/NEWS.md @@ -97,6 +97,9 @@ default. To enable it the new admiral option `save_memory` has to be set to - Adopted `data-raw/data` R Package Convention (#2427, #2584) - `compute_bsa()` now uses the more common (but equivalent) version of the DuBois-DuBois formula for BSA. The results have not changed. (#2532) - Removed `.devcontainer` file (codespace) (#2524) +- Restructured `derive_adeg_parms.R` and `derive_advs_parms.R` and related test files for easier reference (#2551) + + diff --git a/R/derive_advs_params.R b/R/derive_advs_params.R deleted file mode 100644 index 6a516e0ab0..0000000000 --- a/R/derive_advs_params.R +++ /dev/null @@ -1,814 +0,0 @@ -#' Adds a Parameter for Mean Arterial Pressure -#' -#' @description Adds a record for mean arterial pressure (MAP) for each by group -#' (e.g., subject and visit) where the source parameters are available. -#' -#' **Note:** This is a wrapper function for the more generic `derive_param_computed()`. -#' -#' @param dataset -#' `r roxygen_param_dataset(expected_vars = c("by_vars"))` -#' `PARAMCD`, and `AVAL` are expected as well. -#' -#' The variable specified by `by_vars` and `PARAMCD` must be a unique key of -#' the input dataset after restricting it by the filter condition (`filter` -#' parameter) and to the parameters specified by `sysbp_code`, `diabp_code` -#' and `hr_code`. -#' -#' @param sysbp_code Systolic blood pressure parameter code -#' -#' The observations where `PARAMCD` equals the specified value are considered -#' as the systolic blood pressure assessments. -#' -#' *Permitted Values:* character value -#' -#' @param diabp_code Diastolic blood pressure parameter code -#' -#' The observations where `PARAMCD` equals the specified value are considered -#' as the diastolic blood pressure assessments. -#' -#' *Permitted Values:* character value -#' -#' @param hr_code Heart rate parameter code -#' -#' The observations where `PARAMCD` equals the specified value are considered -#' as the heart rate assessments. -#' -#' *Permitted Values:* character value -#' -#' @param set_values_to Variables to be set -#' -#' The specified variables are set to the specified values for the new -#' observations. For example `exprs(PARAMCD = "MAP")` defines the parameter code -#' for the new parameter. -#' -#' *Permitted Values*: List of variable-value pairs -#' -#' @inheritParams derive_param_computed -#' -#' @inheritParams derive_param_qtc -#' -#' @details -#' The analysis value of the new parameter is derived as -#' \deqn{\frac{2DIABP + SYSBP}{3}}{(2DIABP + SYSBP) / 3} -#' if it is based on diastolic and systolic blood pressure and -#' \deqn{DIABP + 0.01 e^{4.14 - \frac{40.74}{HR}} (SYSBP - DIABP)}{ -#' DIABP + 0.01 exp(4.14 - 40.74 / HR) (SYSBP - DIABP)} -#' if it is based on diastolic, systolic blood pressure, and heart rate. -#' -#' -#' @return The input dataset with the new parameter added. Note, a variable will only -#' be populated in the new parameter rows if it is specified in `by_vars`. -#' -#' @family der_prm_bds_findings -#' -#' @keywords der_prm_bds_findings -#' -#' @export -#' -#' @seealso [compute_map()] -#' -#' @examples -#' library(tibble) -#' library(dplyr, warn.conflicts = FALSE) -#' -#' advs <- tibble::tribble( -#' ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~VISIT, -#' "01-701-1015", "PULSE", "Pulse (beats/min)", 59, "BASELINE", -#' "01-701-1015", "PULSE", "Pulse (beats/min)", 61, "WEEK 2", -#' "01-701-1015", "DIABP", "Diastolic Blood Pressure (mmHg)", 51, "BASELINE", -#' "01-701-1015", "DIABP", "Diastolic Blood Pressure (mmHg)", 50, "WEEK 2", -#' "01-701-1015", "SYSBP", "Systolic Blood Pressure (mmHg)", 121, "BASELINE", -#' "01-701-1015", "SYSBP", "Systolic Blood Pressure (mmHg)", 121, "WEEK 2", -#' "01-701-1028", "PULSE", "Pulse (beats/min)", 62, "BASELINE", -#' "01-701-1028", "PULSE", "Pulse (beats/min)", 77, "WEEK 2", -#' "01-701-1028", "DIABP", "Diastolic Blood Pressure (mmHg)", 79, "BASELINE", -#' "01-701-1028", "DIABP", "Diastolic Blood Pressure (mmHg)", 80, "WEEK 2", -#' "01-701-1028", "SYSBP", "Systolic Blood Pressure (mmHg)", 130, "BASELINE", -#' "01-701-1028", "SYSBP", "Systolic Blood Pressure (mmHg)", 132, "WEEK 2" -#' ) -#' -#' # Derive MAP based on diastolic and systolic blood pressure -#' advs %>% -#' derive_param_map( -#' by_vars = exprs(USUBJID, VISIT), -#' set_values_to = exprs( -#' PARAMCD = "MAP", -#' PARAM = "Mean Arterial Pressure (mmHg)" -#' ), -#' get_unit_expr = extract_unit(PARAM) -#' ) %>% -#' filter(PARAMCD != "PULSE") -#' -#' # Derive MAP based on diastolic and systolic blood pressure and heart rate -#' derive_param_map( -#' advs, -#' by_vars = exprs(USUBJID, VISIT), -#' hr_code = "PULSE", -#' set_values_to = exprs( -#' PARAMCD = "MAP", -#' PARAM = "Mean Arterial Pressure (mmHg)" -#' ), -#' get_unit_expr = extract_unit(PARAM) -#' ) -derive_param_map <- function(dataset, - by_vars, - set_values_to = exprs(PARAMCD = "MAP"), - sysbp_code = "SYSBP", - diabp_code = "DIABP", - hr_code = NULL, - get_unit_expr, - filter = NULL) { - assert_vars(by_vars) - assert_data_frame(dataset, required_vars = exprs(!!!by_vars, PARAMCD, AVAL)) - assert_varval_list(set_values_to, required_elements = "PARAMCD") - assert_param_does_not_exist(dataset, set_values_to$PARAMCD) - assert_character_scalar(sysbp_code) - assert_character_scalar(diabp_code) - assert_character_scalar(hr_code, optional = TRUE) - get_unit_expr <- assert_expr(enexpr(get_unit_expr)) - filter <- assert_filter_cond(enexpr(filter), optional = TRUE) - - assert_unit(dataset, sysbp_code, required_unit = "mmHg", get_unit_expr = !!get_unit_expr) - assert_unit(dataset, diabp_code, required_unit = "mmHg", get_unit_expr = !!get_unit_expr) - - if (is.null(hr_code)) { - analysis_value <- expr( - compute_map( - diabp = !!sym(paste0("AVAL.", diabp_code)), - sysbp = !!sym(paste0("AVAL.", sysbp_code)) - ) - ) - } else { - assert_unit(dataset, hr_code, required_unit = "beats/min", get_unit_expr = !!get_unit_expr) - - analysis_value <- expr( - compute_map( - diabp = !!sym(paste0("AVAL.", diabp_code)), - sysbp = !!sym(paste0("AVAL.", sysbp_code)), - hr = !!sym(paste0("AVAL.", hr_code)) - ) - ) - } - - withCallingHandlers( - derive_param_computed( - dataset, - filter = !!filter, - parameters = c(sysbp_code, diabp_code, hr_code), - by_vars = by_vars, - set_values_to = exprs( - AVAL = !!analysis_value, - !!!set_values_to - ) - ), - derive_param_computed_all_na = function(cnd) { - cli_inform( - c( - paste( - "No computed records were added because for all potential computed", - "records at least one of the contributing values was {.val {NA}}." - ), - "If this is not expected, please check the input data." - ), - class = class(cnd) - ) - cnd_muffle(cnd) - } - ) -} - -#' Compute Mean Arterial Pressure (MAP) -#' -#' Computes mean arterial pressure (MAP) based on diastolic and systolic blood -#' pressure. Optionally heart rate can be used as well. -#' -#' @param diabp Diastolic blood pressure -#' -#' A numeric vector is expected. -#' -#' @param sysbp Systolic blood pressure -#' -#' A numeric vector is expected. -#' -#' @param hr Heart rate -#' -#' A numeric vector or `NULL` is expected. -#' -#' -#' @details -#' \deqn{\frac{2DIABP + SYSBP}{3}}{(2DIABP + SYSBP) / 3} -#' if it is based on diastolic and systolic blood pressure and -#' \deqn{DIABP + 0.01 e^{4.14 - \frac{40.74}{HR}} (SYSBP - DIABP)}{ -#' DIABP + 0.01 exp(4.14 - 40.74 / HR) (SYSBP - DIABP)} -#' if it is based on diastolic, systolic blood pressure, and heart rate. -#' -#' Usually this computation function can not be used with `%>%`. -#' -#' @return A numeric vector of MAP values -#' -#' @family com_bds_findings -#' -#' @keywords com_bds_findings -#' -#' @export -#' -#' @seealso [derive_param_map()] -#' -#' @examples -#' # Compute MAP based on diastolic and systolic blood pressure -#' compute_map(diabp = 51, sysbp = 121) -#' -#' # Compute MAP based on diastolic and systolic blood pressure and heart rate -#' compute_map(diabp = 51, sysbp = 121, hr = 59) -compute_map <- function(diabp, sysbp, hr = NULL) { - assert_numeric_vector(diabp) - assert_numeric_vector(sysbp) - assert_numeric_vector(hr, optional = TRUE) - - if (is.null(hr)) { - (2 * diabp + sysbp) / 3 - } else { - diabp + 0.01 * exp(4.14 - 40.74 / hr) * (sysbp - diabp) - } -} - -#' Adds a Parameter for BSA (Body Surface Area) Using the Specified Method -#' -#' @description Adds a record for BSA (Body Surface Area) using the specified derivation -#' method for each by group (e.g., subject and visit) where the source parameters are -#' available. -#' -#' **Note:** This is a wrapper function for the more generic `derive_param_computed()`. -#' -#' @param dataset -#' `r roxygen_param_dataset(expected_vars = c("by_vars"))` -#' `PARAMCD`, and `AVAL` are expected as well. -#' -#' The variable specified by `by_vars` and `PARAMCD` must be a unique key of -#' the input dataset after restricting it by the filter condition (`filter` -#' parameter) and to the parameters specified by `HEIGHT` and `WEIGHT`. -#' -#' @param method Derivation method to use. Note that `HEIGHT` is expected -#' in cm and `WEIGHT` is expected in kg: -#' -#' Mosteller: `sqrt(height * weight / 3600)` -#' -#' DuBois-DuBois: `0.20247 * (height/100) ^ 0.725 * weight ^ 0.425` -#' -#' Haycock: `0.024265 * height ^ 0.3964 * weight ^ 0.5378` -#' -#' Gehan-George: `0.0235 * height ^ 0.42246 * weight ^ 0.51456` -#' -#' Boyd: `0.0003207 * (height ^ 0.3) * (1000 * weight) ^ -#' (0.7285 - (0.0188 * log10(1000 * weight)))` -#' -#' Fujimoto: `0.008883 * height ^ 0.663 * weight ^ 0.444` -#' -#' Takahira: `0.007241 * height ^ 0.725 * weight ^ 0.425` -#' -#' *Permitted Values:* character value -#' -#' @param height_code HEIGHT parameter code -#' -#' The observations where `PARAMCD` equals the specified value are considered -#' as the HEIGHT assessments. It is expected that HEIGHT is measured in cm. -#' -#' *Permitted Values:* character value -#' -#' @param weight_code WEIGHT parameter code -#' -#' The observations where `PARAMCD` equals the specified value are considered -#' as the WEIGHT assessments. It is expected that WEIGHT is measured in kg. -#' -#' *Permitted Values:* character value -#' -#' @param constant_by_vars By variables for when HEIGHT is constant -#' -#' When HEIGHT is constant, the HEIGHT parameters (measured only once) are merged -#' to the other parameters using the specified variables. -#' -#' If height is constant (e.g. only measured once at screening or baseline) then -#' use `constant_by_vars` to select the subject-level variable to merge on (e.g. `USUBJID`). -#' This will produce BSA at all visits where weight is measured. Otherwise -#' it will only be calculated at visits with both height and weight collected. -#' -#' `r roxygen_param_by_vars()` -#' -#' @inheritParams derive_param_map -#' -#' @inheritParams derive_param_computed -#' -#' @inheritParams derive_param_qtc -#' -#' -#' @return The input dataset with the new parameter added. Note, a variable will only -#' be populated in the new parameter rows if it is specified in `by_vars`. -#' -#' @family der_prm_bds_findings -#' -#' @keywords der_prm_bds_findings -#' -#' @export -#' -#' @seealso [compute_bsa()] -#' -#' @examples -#' library(tibble) -#' -#' # Example 1: Derive BSA where height is measured only once using constant_by_vars -#' advs <- tibble::tribble( -#' ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~VISIT, -#' "01-701-1015", "HEIGHT", "Height (cm)", 170, "BASELINE", -#' "01-701-1015", "WEIGHT", "Weight (kg)", 75, "BASELINE", -#' "01-701-1015", "WEIGHT", "Weight (kg)", 78, "MONTH 1", -#' "01-701-1015", "WEIGHT", "Weight (kg)", 80, "MONTH 2", -#' "01-701-1028", "HEIGHT", "Height (cm)", 185, "BASELINE", -#' "01-701-1028", "WEIGHT", "Weight (kg)", 90, "BASELINE", -#' "01-701-1028", "WEIGHT", "Weight (kg)", 88, "MONTH 1", -#' "01-701-1028", "WEIGHT", "Weight (kg)", 85, "MONTH 2", -#' ) -#' -#' derive_param_bsa( -#' advs, -#' by_vars = exprs(USUBJID, VISIT), -#' method = "Mosteller", -#' set_values_to = exprs( -#' PARAMCD = "BSA", -#' PARAM = "Body Surface Area (m^2)" -#' ), -#' get_unit_expr = extract_unit(PARAM), -#' constant_by_vars = exprs(USUBJID) -#' ) -#' -#' derive_param_bsa( -#' advs, -#' by_vars = exprs(USUBJID, VISIT), -#' method = "Fujimoto", -#' set_values_to = exprs( -#' PARAMCD = "BSA", -#' PARAM = "Body Surface Area (m^2)" -#' ), -#' get_unit_expr = extract_unit(PARAM), -#' constant_by_vars = exprs(USUBJID) -#' ) -#' -#' # Example 2: Derive BSA where height is measured only once and keep only one record -#' # where both height and weight are measured. -#' -#' derive_param_bsa( -#' advs, -#' by_vars = exprs(USUBJID, VISIT), -#' method = "Mosteller", -#' set_values_to = exprs( -#' PARAMCD = "BSA", -#' PARAM = "Body Surface Area (m^2)" -#' ), -#' get_unit_expr = extract_unit(PARAM) -#' ) -#' -#' # Example 3: Pediatric study where height and weight are measured multiple times -#' advs <- tibble::tribble( -#' ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~VISIT, -#' "01-101-1001", "HEIGHT", "Height (cm)", 47.1, "BASELINE", -#' "01-101-1001", "HEIGHT", "Height (cm)", 59.1, "WEEK 12", -#' "01-101-1001", "HEIGHT", "Height (cm)", 64.7, "WEEK 24", -#' "01-101-1001", "HEIGHT", "Height (cm)", 68.2, "WEEK 48", -#' "01-101-1001", "WEIGHT", "Weight (kg)", 2.6, "BASELINE", -#' "01-101-1001", "WEIGHT", "Weight (kg)", 5.3, "WEEK 12", -#' "01-101-1001", "WEIGHT", "Weight (kg)", 6.7, "WEEK 24", -#' "01-101-1001", "WEIGHT", "Weight (kg)", 7.4, "WEEK 48", -#' ) -#' derive_param_bsa( -#' advs, -#' by_vars = exprs(USUBJID, VISIT), -#' method = "Mosteller", -#' set_values_to = exprs( -#' PARAMCD = "BSA", -#' PARAM = "Body Surface Area (m^2)" -#' ), -#' get_unit_expr = extract_unit(PARAM) -#' ) -derive_param_bsa <- function(dataset, - by_vars, - method, - set_values_to = exprs(PARAMCD = "BSA"), - height_code = "HEIGHT", - weight_code = "WEIGHT", - get_unit_expr, - filter = NULL, - constant_by_vars = NULL) { - assert_vars(by_vars) - assert_data_frame(dataset, required_vars = exprs(!!!by_vars, PARAMCD, AVAL)) - assert_character_scalar( - method, - values = c( - "Mosteller", "DuBois-DuBois", "Haycock", "Gehan-George", - "Boyd", "Fujimoto", "Takahira" - ) - ) - assert_varval_list(set_values_to, required_elements = "PARAMCD") - assert_param_does_not_exist(dataset, set_values_to$PARAMCD) - assert_character_scalar(height_code) - assert_character_scalar(weight_code) - get_unit_expr <- assert_expr(enexpr(get_unit_expr)) - filter <- assert_filter_cond(enexpr(filter), optional = TRUE) - assert_vars(constant_by_vars, optional = TRUE) - - assert_unit( - dataset, - param = height_code, - required_unit = "cm", - get_unit_expr = !!get_unit_expr - ) - assert_unit( - dataset, - param = weight_code, - required_unit = "kg", - get_unit_expr = !!get_unit_expr - ) - - bsa_formula <- expr( - compute_bsa( - height = !!sym(paste0("AVAL.", height_code)), - weight = !!sym(paste0("AVAL.", weight_code)), - method = !!method - ) - ) - - if (is.null(constant_by_vars)) { - parameters <- c(weight_code, height_code) - constant_parameters <- NULL - } else { - parameters <- c(weight_code) - constant_parameters <- c(height_code) - } - - withCallingHandlers( - derive_param_computed( - dataset, - filter = !!filter, - parameters = parameters, - by_vars = by_vars, - set_values_to = exprs( - AVAL = !!bsa_formula, - !!!set_values_to - ), - constant_parameters = constant_parameters, - constant_by_vars = constant_by_vars - ), - derive_param_computed_all_na = function(cnd) { - cli_inform( - c( - paste( - "No computed records were added because for all potential computed", - "records at least one of the contributing values was {.val {NA}}." - ), - "If this is not expected, please check the input data." - ), - class = class(cnd) - ) - cnd_muffle(cnd) - } - ) -} - -#' Compute Body Surface Area (BSA) -#' -#' Computes BSA from height and weight making use of the specified derivation method -#' -#' @param height HEIGHT value -#' -#' It is expected that HEIGHT is in cm. -#' -#' *Permitted Values:* numeric vector -#' -#' @param weight WEIGHT value -#' -#' It is expected that WEIGHT is in kg. -#' -#' *Permitted Values:* numeric vector -#' -#' @param method Derivation method to use: -#' -#' Mosteller: sqrt(height * weight / 3600) -#' -#' DuBois-DuBois: 0.007184 * height ^ 0.725 * weight ^ 0.425 -#' -#' Haycock: 0.024265 * height ^ 0.3964 * weight ^ 0.5378 -#' -#' Gehan-George: 0.0235 * height ^ 0.42246 * weight ^ 0.51456 -#' -#' Boyd: 0.0003207 * (height ^ 0.3) * (1000 * weight) ^ (0.7285 - (0.0188 * log10(1000 * weight))) -#' -#' Fujimoto: 0.008883 * height ^ 0.663 * weight ^ 0.444 -#' -#' Takahira: 0.007241 * height ^ 0.725 * weight ^ 0.425 -#' -#' *Permitted Values:* character value -#' -#' -#' @details Usually this computation function can not be used with `%>%`. -#' -#' @return The BSA (Body Surface Area) in m^2. -#' -#' @family com_bds_findings -#' -#' @keywords com_bds_findings -#' -#' @export -#' -#' @seealso [derive_param_bsa()] -#' -#' @examples -#' # Derive BSA by the Mosteller method -#' compute_bsa( -#' height = 170, -#' weight = 75, -#' method = "Mosteller" -#' ) -#' -#' # Derive BSA by the DuBois & DuBois method -#' compute_bsa( -#' height = c(170, 185), -#' weight = c(75, 90), -#' method = "DuBois-DuBois" -#' ) -compute_bsa <- function(height = height, - weight = weight, - method) { - assert_numeric_vector(height) - assert_numeric_vector(weight) - assert_character_scalar( - method, - values = c( - "Mosteller", "DuBois-DuBois", "Haycock", "Gehan-George", - "Boyd", "Fujimoto", "Takahira" - ) - ) - - if (method == "Mosteller") { - bsa <- sqrt(height * weight / 3600) - } else if (method == "DuBois-DuBois") { - bsa <- 0.007184 * height^0.725 * weight^0.425 - } else if (method == "Haycock") { - bsa <- 0.024265 * height^0.3964 * weight^0.5378 - } else if (method == "Gehan-George") { - bsa <- 0.0235 * height^0.42246 * weight^0.51456 - } else if (method == "Boyd") { - # The Boyd formula expects the value of weight in grams - # we need to convert from kg - bsa <- 0.0003207 * (height^0.3) * - (1000 * weight)^(0.7285 - (0.0188 * log10(1000 * weight))) # nolint - } else if (method == "Fujimoto") { - bsa <- 0.008883 * height^0.663 * weight^0.444 - } else if (method == "Takahira") { - bsa <- 0.007241 * height^0.725 * weight^0.425 - } - - bsa -} - -#' Adds a Parameter for BMI -#' -#' @description Adds a record for BMI/Body Mass Index using Weight and Height each by group -#' (e.g., subject and visit) where the source parameters are available. -#' -#' **Note:** This is a wrapper function for the more generic `derive_param_computed()`. -#' -#' @param dataset -#' `r roxygen_param_dataset(expected_vars = c("by_vars"))` -#' `PARAMCD`, and `AVAL` are expected as well. -#' -#' The variable specified by `by_vars` and `PARAMCD` must be a unique key of -#' the input dataset after restricting it by the filter condition (`filter` -#' parameter) and to the parameters specified by `weight_code` and `height_code`. -#' -#' @param weight_code WEIGHT parameter code -#' -#' The observations where `PARAMCD` equals the specified value are considered -#' as the WEIGHT. It is expected that WEIGHT is measured in kg -#' -#' *Permitted Values:* character value -#' -#' @param height_code HEIGHT parameter code -#' -#' The observations where `PARAMCD` equals the specified value are considered -#' as the HEIGHT. It is expected that HEIGHT is measured in cm -#' -#' *Permitted Values:* character value -#' -#' *Permitted Values:* logical scalar -#' -#' @param constant_by_vars By variables for when HEIGHT is constant -#' -#' When HEIGHT is constant, the HEIGHT parameters (measured only once) are merged -#' to the other parameters using the specified variables. -#' -#' If height is constant (e.g. only measured once at screening or baseline) then -#' use `constant_by_vars` to select the subject-level variable to merge on (e.g. `USUBJID`). -#' This will produce BMI at all visits where weight is measured. Otherwise -#' it will only be calculated at visits with both height and weight collected. -#' -#' `r roxygen_param_by_vars()` -#' -#' @inheritParams derive_param_map -#' -#' @inheritParams derive_param_computed -#' -#' @inheritParams derive_param_qtc -#' -#' @details -#' The analysis value of the new parameter is derived as -#' \deqn{BMI = \frac{WEIGHT}{HEIGHT^2}} -#' -#' -#' @return The input dataset with the new parameter added. Note, a variable will only -#' be populated in the new parameter rows if it is specified in `by_vars`. -#' -#' @family der_prm_bds_findings -#' -#' @keywords der_prm_bds_findings -#' -#' @export -#' -#' @seealso [compute_bmi()] -#' -#' @examples -#' -#' # Example 1: Derive BMI where height is measured only once using constant_by_vars -#' advs <- tibble::tribble( -#' ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~AVISIT, -#' "01-701-1015", "HEIGHT", "Height (cm)", 147, "SCREENING", -#' "01-701-1015", "WEIGHT", "Weight (kg)", 54.0, "SCREENING", -#' "01-701-1015", "WEIGHT", "Weight (kg)", 54.4, "BASELINE", -#' "01-701-1015", "WEIGHT", "Weight (kg)", 53.1, "WEEK 2", -#' "01-701-1028", "HEIGHT", "Height (cm)", 163, "SCREENING", -#' "01-701-1028", "WEIGHT", "Weight (kg)", 78.5, "SCREENING", -#' "01-701-1028", "WEIGHT", "Weight (kg)", 80.3, "BASELINE", -#' "01-701-1028", "WEIGHT", "Weight (kg)", 80.7, "WEEK 2" -#' ) -#' -#' derive_param_bmi( -#' advs, -#' by_vars = exprs(USUBJID, AVISIT), -#' weight_code = "WEIGHT", -#' height_code = "HEIGHT", -#' set_values_to = exprs( -#' PARAMCD = "BMI", -#' PARAM = "Body Mass Index (kg/m^2)" -#' ), -#' get_unit_expr = extract_unit(PARAM), -#' constant_by_vars = exprs(USUBJID) -#' ) -#' -#' # Example 2: Derive BMI where height is measured only once and keep only one record -#' # where both height and weight are measured. -#' derive_param_bmi( -#' advs, -#' by_vars = exprs(USUBJID, AVISIT), -#' weight_code = "WEIGHT", -#' height_code = "HEIGHT", -#' set_values_to = exprs( -#' PARAMCD = "BMI", -#' PARAM = "Body Mass Index (kg/m^2)" -#' ), -#' get_unit_expr = extract_unit(PARAM) -#' ) -#' -#' # Example 3: Pediatric study where height and weight are measured multiple times -#' advs <- tibble::tribble( -#' ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~VISIT, -#' "01-101-1001", "HEIGHT", "Height (cm)", 47.1, "BASELINE", -#' "01-101-1001", "HEIGHT", "Height (cm)", 59.1, "WEEK 12", -#' "01-101-1001", "HEIGHT", "Height (cm)", 64.7, "WEEK 24", -#' "01-101-1001", "HEIGHT", "Height (cm)", 68.2, "WEEK 48", -#' "01-101-1001", "WEIGHT", "Weight (kg)", 2.6, "BASELINE", -#' "01-101-1001", "WEIGHT", "Weight (kg)", 5.3, "WEEK 12", -#' "01-101-1001", "WEIGHT", "Weight (kg)", 6.7, "WEEK 24", -#' "01-101-1001", "WEIGHT", "Weight (kg)", 7.4, "WEEK 48", -#' ) -#' -#' derive_param_bmi( -#' advs, -#' by_vars = exprs(USUBJID, VISIT), -#' weight_code = "WEIGHT", -#' height_code = "HEIGHT", -#' set_values_to = exprs( -#' PARAMCD = "BMI", -#' PARAM = "Body Mass Index (kg/m^2)" -#' ), -#' get_unit_expr = extract_unit(PARAM) -#' ) -derive_param_bmi <- function(dataset, - by_vars, - set_values_to = exprs(PARAMCD = "BMI"), - weight_code = "WEIGHT", - height_code = "HEIGHT", - get_unit_expr, - filter = NULL, - constant_by_vars = NULL) { - assert_vars(by_vars) - assert_data_frame(dataset, required_vars = exprs(!!!by_vars, PARAMCD, AVAL)) - assert_varval_list(set_values_to, required_elements = "PARAMCD") - assert_param_does_not_exist(dataset, set_values_to$PARAMCD) - assert_character_scalar(weight_code) - assert_character_scalar(height_code) - get_unit_expr <- assert_expr(enexpr(get_unit_expr)) - filter <- assert_filter_cond(enexpr(filter), optional = TRUE) - assert_vars(constant_by_vars, optional = TRUE) - - - assert_unit( - dataset, - param = weight_code, - required_unit = "kg", - get_unit_expr = !!get_unit_expr - ) - assert_unit( - dataset, - param = height_code, - required_unit = "cm", - get_unit_expr = !!get_unit_expr - ) - - bmi_formula <- expr( - compute_bmi( - height = !!sym(paste0("AVAL.", height_code)), - weight = !!sym(paste0("AVAL.", weight_code)) - ) - ) - - if (is.null(constant_by_vars)) { - parameters <- c(weight_code, height_code) - constant_parameters <- NULL - } else { - parameters <- c(weight_code) - constant_parameters <- c(height_code) - } - - withCallingHandlers( - derive_param_computed( - dataset, - filter = !!filter, - parameters = parameters, - by_vars = by_vars, - set_values_to = exprs( - AVAL = !!bmi_formula, - !!!set_values_to - ), - constant_parameters = constant_parameters, - constant_by_vars = constant_by_vars - ), - derive_param_computed_all_na = function(cnd) { - cli_inform( - c( - paste( - "No computed records were added because for all potential computed", - "records at least one of the contributing values was {.val {NA}}." - ), - "If this is not expected, please check the input data." - ), - class = class(cnd) - ) - cnd_muffle(cnd) - } - ) -} - -#' Compute Body Mass Index (BMI) -#' -#' Computes BMI from height and weight -#' -#' @param height HEIGHT value -#' -#' It is expected that HEIGHT is in cm. -#' -#' *Permitted Values:* numeric vector -#' -#' @param weight WEIGHT value -#' -#' It is expected that WEIGHT is in kg. -#' -#' *Permitted Values:* numeric vector -#' -#' -#' @details Usually this computation function can not be used with `%>%`. -#' -#' @return The BMI (Body Mass Index Area) in kg/m^2. -#' -#' @family com_bds_findings -#' -#' @keywords com_bds_findings -#' -#' @export -#' -#' @seealso [derive_param_bmi()] -#' -#' @examples -#' compute_bmi(height = 170, weight = 75) -compute_bmi <- function(height, weight) { - assert_numeric_vector(height) - assert_numeric_vector(weight) - - if_else(height == 0, NA_real_, weight / (height * height / 10000)) -} diff --git a/R/derive_param_bmi.R b/R/derive_param_bmi.R new file mode 100644 index 0000000000..26df7c9f11 --- /dev/null +++ b/R/derive_param_bmi.R @@ -0,0 +1,244 @@ +#' Adds a Parameter for BMI +#' +#' @description Adds a record for BMI/Body Mass Index using Weight and Height each by group +#' (e.g., subject and visit) where the source parameters are available. +#' +#' **Note:** This is a wrapper function for the more generic `derive_param_computed()`. +#' +#' @param dataset +#' `r roxygen_param_dataset(expected_vars = c("by_vars"))` +#' `PARAMCD`, and `AVAL` are expected as well. +#' +#' The variable specified by `by_vars` and `PARAMCD` must be a unique key of +#' the input dataset after restricting it by the filter condition (`filter` +#' parameter) and to the parameters specified by `weight_code` and `height_code`. +#' +#' @param weight_code WEIGHT parameter code +#' +#' The observations where `PARAMCD` equals the specified value are considered +#' as the WEIGHT. It is expected that WEIGHT is measured in kg +#' +#' *Permitted Values:* character value +#' +#' @param height_code HEIGHT parameter code +#' +#' The observations where `PARAMCD` equals the specified value are considered +#' as the HEIGHT. It is expected that HEIGHT is measured in cm +#' +#' *Permitted Values:* character value +#' +#' *Permitted Values:* logical scalar +#' +#' @param constant_by_vars By variables for when HEIGHT is constant +#' +#' When HEIGHT is constant, the HEIGHT parameters (measured only once) are merged +#' to the other parameters using the specified variables. +#' +#' If height is constant (e.g. only measured once at screening or baseline) then +#' use `constant_by_vars` to select the subject-level variable to merge on (e.g. `USUBJID`). +#' This will produce BMI at all visits where weight is measured. Otherwise +#' it will only be calculated at visits with both height and weight collected. +#' +#' `r roxygen_param_by_vars()` +#' +#' @inheritParams derive_param_map +#' +#' @inheritParams derive_param_computed +#' +#' @inheritParams derive_param_qtc +#' +#' @details +#' The analysis value of the new parameter is derived as +#' \deqn{BMI = \frac{WEIGHT}{HEIGHT^2}} +#' +#' +#' @return The input dataset with the new parameter added. Note, a variable will only +#' be populated in the new parameter rows if it is specified in `by_vars`. +#' +#' @family der_prm_bds_findings +#' +#' @keywords der_prm_bds_findings +#' +#' @export +#' +#' @seealso [compute_bmi()] +#' +#' @examples +#' +#' # Example 1: Derive BMI where height is measured only once using constant_by_vars +#' advs <- tibble::tribble( +#' ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~AVISIT, +#' "01-701-1015", "HEIGHT", "Height (cm)", 147, "SCREENING", +#' "01-701-1015", "WEIGHT", "Weight (kg)", 54.0, "SCREENING", +#' "01-701-1015", "WEIGHT", "Weight (kg)", 54.4, "BASELINE", +#' "01-701-1015", "WEIGHT", "Weight (kg)", 53.1, "WEEK 2", +#' "01-701-1028", "HEIGHT", "Height (cm)", 163, "SCREENING", +#' "01-701-1028", "WEIGHT", "Weight (kg)", 78.5, "SCREENING", +#' "01-701-1028", "WEIGHT", "Weight (kg)", 80.3, "BASELINE", +#' "01-701-1028", "WEIGHT", "Weight (kg)", 80.7, "WEEK 2" +#' ) +#' +#' derive_param_bmi( +#' advs, +#' by_vars = exprs(USUBJID, AVISIT), +#' weight_code = "WEIGHT", +#' height_code = "HEIGHT", +#' set_values_to = exprs( +#' PARAMCD = "BMI", +#' PARAM = "Body Mass Index (kg/m^2)" +#' ), +#' get_unit_expr = extract_unit(PARAM), +#' constant_by_vars = exprs(USUBJID) +#' ) +#' +#' # Example 2: Derive BMI where height is measured only once and keep only one record +#' # where both height and weight are measured. +#' derive_param_bmi( +#' advs, +#' by_vars = exprs(USUBJID, AVISIT), +#' weight_code = "WEIGHT", +#' height_code = "HEIGHT", +#' set_values_to = exprs( +#' PARAMCD = "BMI", +#' PARAM = "Body Mass Index (kg/m^2)" +#' ), +#' get_unit_expr = extract_unit(PARAM) +#' ) +#' +#' # Example 3: Pediatric study where height and weight are measured multiple times +#' advs <- tibble::tribble( +#' ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~VISIT, +#' "01-101-1001", "HEIGHT", "Height (cm)", 47.1, "BASELINE", +#' "01-101-1001", "HEIGHT", "Height (cm)", 59.1, "WEEK 12", +#' "01-101-1001", "HEIGHT", "Height (cm)", 64.7, "WEEK 24", +#' "01-101-1001", "HEIGHT", "Height (cm)", 68.2, "WEEK 48", +#' "01-101-1001", "WEIGHT", "Weight (kg)", 2.6, "BASELINE", +#' "01-101-1001", "WEIGHT", "Weight (kg)", 5.3, "WEEK 12", +#' "01-101-1001", "WEIGHT", "Weight (kg)", 6.7, "WEEK 24", +#' "01-101-1001", "WEIGHT", "Weight (kg)", 7.4, "WEEK 48", +#' ) +#' +#' derive_param_bmi( +#' advs, +#' by_vars = exprs(USUBJID, VISIT), +#' weight_code = "WEIGHT", +#' height_code = "HEIGHT", +#' set_values_to = exprs( +#' PARAMCD = "BMI", +#' PARAM = "Body Mass Index (kg/m^2)" +#' ), +#' get_unit_expr = extract_unit(PARAM) +#' ) +derive_param_bmi <- function(dataset, + by_vars, + set_values_to = exprs(PARAMCD = "BMI"), + weight_code = "WEIGHT", + height_code = "HEIGHT", + get_unit_expr, + filter = NULL, + constant_by_vars = NULL) { + assert_vars(by_vars) + assert_data_frame(dataset, required_vars = exprs(!!!by_vars, PARAMCD, AVAL)) + assert_varval_list(set_values_to, required_elements = "PARAMCD") + assert_param_does_not_exist(dataset, set_values_to$PARAMCD) + assert_character_scalar(weight_code) + assert_character_scalar(height_code) + get_unit_expr <- assert_expr(enexpr(get_unit_expr)) + filter <- assert_filter_cond(enexpr(filter), optional = TRUE) + assert_vars(constant_by_vars, optional = TRUE) + + + assert_unit( + dataset, + param = weight_code, + required_unit = "kg", + get_unit_expr = !!get_unit_expr + ) + assert_unit( + dataset, + param = height_code, + required_unit = "cm", + get_unit_expr = !!get_unit_expr + ) + + bmi_formula <- expr( + compute_bmi( + height = !!sym(paste0("AVAL.", height_code)), + weight = !!sym(paste0("AVAL.", weight_code)) + ) + ) + + if (is.null(constant_by_vars)) { + parameters <- c(weight_code, height_code) + constant_parameters <- NULL + } else { + parameters <- c(weight_code) + constant_parameters <- c(height_code) + } + + withCallingHandlers( + derive_param_computed( + dataset, + filter = !!filter, + parameters = parameters, + by_vars = by_vars, + set_values_to = exprs( + AVAL = !!bmi_formula, + !!!set_values_to + ), + constant_parameters = constant_parameters, + constant_by_vars = constant_by_vars + ), + derive_param_computed_all_na = function(cnd) { + cli_inform( + c( + paste( + "No computed records were added because for all potential computed", + "records at least one of the contributing values was {.val {NA}}." + ), + "If this is not expected, please check the input data." + ), + class = class(cnd) + ) + cnd_muffle(cnd) + } + ) +} + +#' Compute Body Mass Index (BMI) +#' +#' Computes BMI from height and weight +#' +#' @param height HEIGHT value +#' +#' It is expected that HEIGHT is in cm. +#' +#' *Permitted Values:* numeric vector +#' +#' @param weight WEIGHT value +#' +#' It is expected that WEIGHT is in kg. +#' +#' *Permitted Values:* numeric vector +#' +#' +#' @details Usually this computation function can not be used with `%>%`. +#' +#' @return The BMI (Body Mass Index Area) in kg/m^2. +#' +#' @family com_bds_findings +#' +#' @keywords com_bds_findings +#' +#' @export +#' +#' @seealso [derive_param_bmi()] +#' +#' @examples +#' compute_bmi(height = 170, weight = 75) +compute_bmi <- function(height, weight) { + assert_numeric_vector(height) + assert_numeric_vector(weight) + + if_else(height == 0, NA_real_, weight / (height * height / 10000)) +} diff --git a/R/derive_param_bsa.R b/R/derive_param_bsa.R new file mode 100644 index 0000000000..03aec00fe8 --- /dev/null +++ b/R/derive_param_bsa.R @@ -0,0 +1,335 @@ +#' Adds a Parameter for BSA (Body Surface Area) Using the Specified Method +#' +#' @description Adds a record for BSA (Body Surface Area) using the specified derivation +#' method for each by group (e.g., subject and visit) where the source parameters are +#' available. +#' +#' **Note:** This is a wrapper function for the more generic `derive_param_computed()`. +#' +#' @param dataset +#' `r roxygen_param_dataset(expected_vars = c("by_vars"))` +#' `PARAMCD`, and `AVAL` are expected as well. +#' +#' The variable specified by `by_vars` and `PARAMCD` must be a unique key of +#' the input dataset after restricting it by the filter condition (`filter` +#' parameter) and to the parameters specified by `HEIGHT` and `WEIGHT`. +#' +#' @param method Derivation method to use. Note that `HEIGHT` is expected +#' in cm and `WEIGHT` is expected in kg: +#' +#' Mosteller: `sqrt(height * weight / 3600)` +#' +#' DuBois-DuBois: `0.20247 * (height/100) ^ 0.725 * weight ^ 0.425` +#' +#' Haycock: `0.024265 * height ^ 0.3964 * weight ^ 0.5378` +#' +#' Gehan-George: `0.0235 * height ^ 0.42246 * weight ^ 0.51456` +#' +#' Boyd: `0.0003207 * (height ^ 0.3) * (1000 * weight) ^ +#' (0.7285 - (0.0188 * log10(1000 * weight)))` +#' +#' Fujimoto: `0.008883 * height ^ 0.663 * weight ^ 0.444` +#' +#' Takahira: `0.007241 * height ^ 0.725 * weight ^ 0.425` +#' +#' *Permitted Values:* character value +#' +#' @param height_code HEIGHT parameter code +#' +#' The observations where `PARAMCD` equals the specified value are considered +#' as the HEIGHT assessments. It is expected that HEIGHT is measured in cm. +#' +#' *Permitted Values:* character value +#' +#' @param weight_code WEIGHT parameter code +#' +#' The observations where `PARAMCD` equals the specified value are considered +#' as the WEIGHT assessments. It is expected that WEIGHT is measured in kg. +#' +#' *Permitted Values:* character value +#' +#' @param constant_by_vars By variables for when HEIGHT is constant +#' +#' When HEIGHT is constant, the HEIGHT parameters (measured only once) are merged +#' to the other parameters using the specified variables. +#' +#' If height is constant (e.g. only measured once at screening or baseline) then +#' use `constant_by_vars` to select the subject-level variable to merge on (e.g. `USUBJID`). +#' This will produce BSA at all visits where weight is measured. Otherwise +#' it will only be calculated at visits with both height and weight collected. +#' +#' `r roxygen_param_by_vars()` +#' +#' @inheritParams derive_param_map +#' +#' @inheritParams derive_param_computed +#' +#' @inheritParams derive_param_qtc +#' +#' +#' @return The input dataset with the new parameter added. Note, a variable will only +#' be populated in the new parameter rows if it is specified in `by_vars`. +#' +#' @family der_prm_bds_findings +#' +#' @keywords der_prm_bds_findings +#' +#' @export +#' +#' @seealso [compute_bsa()] +#' +#' @examples +#' library(tibble) +#' +#' # Example 1: Derive BSA where height is measured only once using constant_by_vars +#' advs <- tibble::tribble( +#' ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~VISIT, +#' "01-701-1015", "HEIGHT", "Height (cm)", 170, "BASELINE", +#' "01-701-1015", "WEIGHT", "Weight (kg)", 75, "BASELINE", +#' "01-701-1015", "WEIGHT", "Weight (kg)", 78, "MONTH 1", +#' "01-701-1015", "WEIGHT", "Weight (kg)", 80, "MONTH 2", +#' "01-701-1028", "HEIGHT", "Height (cm)", 185, "BASELINE", +#' "01-701-1028", "WEIGHT", "Weight (kg)", 90, "BASELINE", +#' "01-701-1028", "WEIGHT", "Weight (kg)", 88, "MONTH 1", +#' "01-701-1028", "WEIGHT", "Weight (kg)", 85, "MONTH 2", +#' ) +#' +#' derive_param_bsa( +#' advs, +#' by_vars = exprs(USUBJID, VISIT), +#' method = "Mosteller", +#' set_values_to = exprs( +#' PARAMCD = "BSA", +#' PARAM = "Body Surface Area (m^2)" +#' ), +#' get_unit_expr = extract_unit(PARAM), +#' constant_by_vars = exprs(USUBJID) +#' ) +#' +#' derive_param_bsa( +#' advs, +#' by_vars = exprs(USUBJID, VISIT), +#' method = "Fujimoto", +#' set_values_to = exprs( +#' PARAMCD = "BSA", +#' PARAM = "Body Surface Area (m^2)" +#' ), +#' get_unit_expr = extract_unit(PARAM), +#' constant_by_vars = exprs(USUBJID) +#' ) +#' +#' # Example 2: Derive BSA where height is measured only once and keep only one record +#' # where both height and weight are measured. +#' +#' derive_param_bsa( +#' advs, +#' by_vars = exprs(USUBJID, VISIT), +#' method = "Mosteller", +#' set_values_to = exprs( +#' PARAMCD = "BSA", +#' PARAM = "Body Surface Area (m^2)" +#' ), +#' get_unit_expr = extract_unit(PARAM) +#' ) +#' +#' # Example 3: Pediatric study where height and weight are measured multiple times +#' advs <- tibble::tribble( +#' ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~VISIT, +#' "01-101-1001", "HEIGHT", "Height (cm)", 47.1, "BASELINE", +#' "01-101-1001", "HEIGHT", "Height (cm)", 59.1, "WEEK 12", +#' "01-101-1001", "HEIGHT", "Height (cm)", 64.7, "WEEK 24", +#' "01-101-1001", "HEIGHT", "Height (cm)", 68.2, "WEEK 48", +#' "01-101-1001", "WEIGHT", "Weight (kg)", 2.6, "BASELINE", +#' "01-101-1001", "WEIGHT", "Weight (kg)", 5.3, "WEEK 12", +#' "01-101-1001", "WEIGHT", "Weight (kg)", 6.7, "WEEK 24", +#' "01-101-1001", "WEIGHT", "Weight (kg)", 7.4, "WEEK 48", +#' ) +#' derive_param_bsa( +#' advs, +#' by_vars = exprs(USUBJID, VISIT), +#' method = "Mosteller", +#' set_values_to = exprs( +#' PARAMCD = "BSA", +#' PARAM = "Body Surface Area (m^2)" +#' ), +#' get_unit_expr = extract_unit(PARAM) +#' ) +derive_param_bsa <- function(dataset, + by_vars, + method, + set_values_to = exprs(PARAMCD = "BSA"), + height_code = "HEIGHT", + weight_code = "WEIGHT", + get_unit_expr, + filter = NULL, + constant_by_vars = NULL) { + assert_vars(by_vars) + assert_data_frame(dataset, required_vars = exprs(!!!by_vars, PARAMCD, AVAL)) + assert_character_scalar( + method, + values = c( + "Mosteller", "DuBois-DuBois", "Haycock", "Gehan-George", + "Boyd", "Fujimoto", "Takahira" + ) + ) + assert_varval_list(set_values_to, required_elements = "PARAMCD") + assert_param_does_not_exist(dataset, set_values_to$PARAMCD) + assert_character_scalar(height_code) + assert_character_scalar(weight_code) + get_unit_expr <- assert_expr(enexpr(get_unit_expr)) + filter <- assert_filter_cond(enexpr(filter), optional = TRUE) + assert_vars(constant_by_vars, optional = TRUE) + + assert_unit( + dataset, + param = height_code, + required_unit = "cm", + get_unit_expr = !!get_unit_expr + ) + assert_unit( + dataset, + param = weight_code, + required_unit = "kg", + get_unit_expr = !!get_unit_expr + ) + + bsa_formula <- expr( + compute_bsa( + height = !!sym(paste0("AVAL.", height_code)), + weight = !!sym(paste0("AVAL.", weight_code)), + method = !!method + ) + ) + + if (is.null(constant_by_vars)) { + parameters <- c(weight_code, height_code) + constant_parameters <- NULL + } else { + parameters <- c(weight_code) + constant_parameters <- c(height_code) + } + + withCallingHandlers( + derive_param_computed( + dataset, + filter = !!filter, + parameters = parameters, + by_vars = by_vars, + set_values_to = exprs( + AVAL = !!bsa_formula, + !!!set_values_to + ), + constant_parameters = constant_parameters, + constant_by_vars = constant_by_vars + ), + derive_param_computed_all_na = function(cnd) { + cli_inform( + c( + paste( + "No computed records were added because for all potential computed", + "records at least one of the contributing values was {.val {NA}}." + ), + "If this is not expected, please check the input data." + ), + class = class(cnd) + ) + cnd_muffle(cnd) + } + ) +} + +#' Compute Body Surface Area (BSA) +#' +#' Computes BSA from height and weight making use of the specified derivation method +#' +#' @param height HEIGHT value +#' +#' It is expected that HEIGHT is in cm. +#' +#' *Permitted Values:* numeric vector +#' +#' @param weight WEIGHT value +#' +#' It is expected that WEIGHT is in kg. +#' +#' *Permitted Values:* numeric vector +#' +#' @param method Derivation method to use: +#' +#' Mosteller: sqrt(height * weight / 3600) +#' +#' DuBois-DuBois: 0.007184 * height ^ 0.725 * weight ^ 0.425 +#' +#' Haycock: 0.024265 * height ^ 0.3964 * weight ^ 0.5378 +#' +#' Gehan-George: 0.0235 * height ^ 0.42246 * weight ^ 0.51456 +#' +#' Boyd: 0.0003207 * (height ^ 0.3) * (1000 * weight) ^ (0.7285 - (0.0188 * log10(1000 * weight))) +#' +#' Fujimoto: 0.008883 * height ^ 0.663 * weight ^ 0.444 +#' +#' Takahira: 0.007241 * height ^ 0.725 * weight ^ 0.425 +#' +#' *Permitted Values:* character value +#' +#' +#' @details Usually this computation function can not be used with `%>%`. +#' +#' @return The BSA (Body Surface Area) in m^2. +#' +#' @family com_bds_findings +#' +#' @keywords com_bds_findings +#' +#' @export +#' +#' @seealso [derive_param_bsa()] +#' +#' @examples +#' # Derive BSA by the Mosteller method +#' compute_bsa( +#' height = 170, +#' weight = 75, +#' method = "Mosteller" +#' ) +#' +#' # Derive BSA by the DuBois & DuBois method +#' compute_bsa( +#' height = c(170, 185), +#' weight = c(75, 90), +#' method = "DuBois-DuBois" +#' ) +compute_bsa <- function(height = height, + weight = weight, + method) { + assert_numeric_vector(height) + assert_numeric_vector(weight) + assert_character_scalar( + method, + values = c( + "Mosteller", "DuBois-DuBois", "Haycock", "Gehan-George", + "Boyd", "Fujimoto", "Takahira" + ) + ) + + if (method == "Mosteller") { + bsa <- sqrt(height * weight / 3600) + } else if (method == "DuBois-DuBois") { + bsa <- 0.007184 * height^0.725 * weight^0.425 + } else if (method == "Haycock") { + bsa <- 0.024265 * height^0.3964 * weight^0.5378 + } else if (method == "Gehan-George") { + bsa <- 0.0235 * height^0.42246 * weight^0.51456 + } else if (method == "Boyd") { + # The Boyd formula expects the value of weight in grams + # we need to convert from kg + bsa <- 0.0003207 * (height^0.3) * + (1000 * weight)^(0.7285 - (0.0188 * log10(1000 * weight))) # nolint + } else if (method == "Fujimoto") { + bsa <- 0.008883 * height^0.663 * weight^0.444 + } else if (method == "Takahira") { + bsa <- 0.007241 * height^0.725 * weight^0.425 + } + + bsa +} diff --git a/R/derive_param_map.R b/R/derive_param_map.R new file mode 100644 index 0000000000..fb56272d38 --- /dev/null +++ b/R/derive_param_map.R @@ -0,0 +1,233 @@ +#' Adds a Parameter for Mean Arterial Pressure +#' +#' @description Adds a record for mean arterial pressure (MAP) for each by group +#' (e.g., subject and visit) where the source parameters are available. +#' +#' **Note:** This is a wrapper function for the more generic `derive_param_computed()`. +#' +#' @param dataset +#' `r roxygen_param_dataset(expected_vars = c("by_vars"))` +#' `PARAMCD`, and `AVAL` are expected as well. +#' +#' The variable specified by `by_vars` and `PARAMCD` must be a unique key of +#' the input dataset after restricting it by the filter condition (`filter` +#' parameter) and to the parameters specified by `sysbp_code`, `diabp_code` +#' and `hr_code`. +#' +#' @param sysbp_code Systolic blood pressure parameter code +#' +#' The observations where `PARAMCD` equals the specified value are considered +#' as the systolic blood pressure assessments. +#' +#' *Permitted Values:* character value +#' +#' @param diabp_code Diastolic blood pressure parameter code +#' +#' The observations where `PARAMCD` equals the specified value are considered +#' as the diastolic blood pressure assessments. +#' +#' *Permitted Values:* character value +#' +#' @param hr_code Heart rate parameter code +#' +#' The observations where `PARAMCD` equals the specified value are considered +#' as the heart rate assessments. +#' +#' *Permitted Values:* character value +#' +#' @param set_values_to Variables to be set +#' +#' The specified variables are set to the specified values for the new +#' observations. For example `exprs(PARAMCD = "MAP")` defines the parameter code +#' for the new parameter. +#' +#' *Permitted Values*: List of variable-value pairs +#' +#' @inheritParams derive_param_computed +#' +#' @inheritParams derive_param_qtc +#' +#' @details +#' The analysis value of the new parameter is derived as +#' \deqn{\frac{2DIABP + SYSBP}{3}}{(2DIABP + SYSBP) / 3} +#' if it is based on diastolic and systolic blood pressure and +#' \deqn{DIABP + 0.01 e^{4.14 - \frac{40.74}{HR}} (SYSBP - DIABP)}{ +#' DIABP + 0.01 exp(4.14 - 40.74 / HR) (SYSBP - DIABP)} +#' if it is based on diastolic, systolic blood pressure, and heart rate. +#' +#' +#' @return The input dataset with the new parameter added. Note, a variable will only +#' be populated in the new parameter rows if it is specified in `by_vars`. +#' +#' @family der_prm_bds_findings +#' +#' @keywords der_prm_bds_findings +#' +#' @export +#' +#' @seealso [compute_map()] +#' +#' @examples +#' library(tibble) +#' library(dplyr, warn.conflicts = FALSE) +#' +#' advs <- tibble::tribble( +#' ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~VISIT, +#' "01-701-1015", "PULSE", "Pulse (beats/min)", 59, "BASELINE", +#' "01-701-1015", "PULSE", "Pulse (beats/min)", 61, "WEEK 2", +#' "01-701-1015", "DIABP", "Diastolic Blood Pressure (mmHg)", 51, "BASELINE", +#' "01-701-1015", "DIABP", "Diastolic Blood Pressure (mmHg)", 50, "WEEK 2", +#' "01-701-1015", "SYSBP", "Systolic Blood Pressure (mmHg)", 121, "BASELINE", +#' "01-701-1015", "SYSBP", "Systolic Blood Pressure (mmHg)", 121, "WEEK 2", +#' "01-701-1028", "PULSE", "Pulse (beats/min)", 62, "BASELINE", +#' "01-701-1028", "PULSE", "Pulse (beats/min)", 77, "WEEK 2", +#' "01-701-1028", "DIABP", "Diastolic Blood Pressure (mmHg)", 79, "BASELINE", +#' "01-701-1028", "DIABP", "Diastolic Blood Pressure (mmHg)", 80, "WEEK 2", +#' "01-701-1028", "SYSBP", "Systolic Blood Pressure (mmHg)", 130, "BASELINE", +#' "01-701-1028", "SYSBP", "Systolic Blood Pressure (mmHg)", 132, "WEEK 2" +#' ) +#' +#' # Derive MAP based on diastolic and systolic blood pressure +#' advs %>% +#' derive_param_map( +#' by_vars = exprs(USUBJID, VISIT), +#' set_values_to = exprs( +#' PARAMCD = "MAP", +#' PARAM = "Mean Arterial Pressure (mmHg)" +#' ), +#' get_unit_expr = extract_unit(PARAM) +#' ) %>% +#' filter(PARAMCD != "PULSE") +#' +#' # Derive MAP based on diastolic and systolic blood pressure and heart rate +#' derive_param_map( +#' advs, +#' by_vars = exprs(USUBJID, VISIT), +#' hr_code = "PULSE", +#' set_values_to = exprs( +#' PARAMCD = "MAP", +#' PARAM = "Mean Arterial Pressure (mmHg)" +#' ), +#' get_unit_expr = extract_unit(PARAM) +#' ) +derive_param_map <- function(dataset, + by_vars, + set_values_to = exprs(PARAMCD = "MAP"), + sysbp_code = "SYSBP", + diabp_code = "DIABP", + hr_code = NULL, + get_unit_expr, + filter = NULL) { + assert_vars(by_vars) + assert_data_frame(dataset, required_vars = exprs(!!!by_vars, PARAMCD, AVAL)) + assert_varval_list(set_values_to, required_elements = "PARAMCD") + assert_param_does_not_exist(dataset, set_values_to$PARAMCD) + assert_character_scalar(sysbp_code) + assert_character_scalar(diabp_code) + assert_character_scalar(hr_code, optional = TRUE) + get_unit_expr <- assert_expr(enexpr(get_unit_expr)) + filter <- assert_filter_cond(enexpr(filter), optional = TRUE) + + assert_unit(dataset, sysbp_code, required_unit = "mmHg", get_unit_expr = !!get_unit_expr) + assert_unit(dataset, diabp_code, required_unit = "mmHg", get_unit_expr = !!get_unit_expr) + + if (is.null(hr_code)) { + analysis_value <- expr( + compute_map( + diabp = !!sym(paste0("AVAL.", diabp_code)), + sysbp = !!sym(paste0("AVAL.", sysbp_code)) + ) + ) + } else { + assert_unit(dataset, hr_code, required_unit = "beats/min", get_unit_expr = !!get_unit_expr) + + analysis_value <- expr( + compute_map( + diabp = !!sym(paste0("AVAL.", diabp_code)), + sysbp = !!sym(paste0("AVAL.", sysbp_code)), + hr = !!sym(paste0("AVAL.", hr_code)) + ) + ) + } + + withCallingHandlers( + derive_param_computed( + dataset, + filter = !!filter, + parameters = c(sysbp_code, diabp_code, hr_code), + by_vars = by_vars, + set_values_to = exprs( + AVAL = !!analysis_value, + !!!set_values_to + ) + ), + derive_param_computed_all_na = function(cnd) { + cli_inform( + c( + paste( + "No computed records were added because for all potential computed", + "records at least one of the contributing values was {.val {NA}}." + ), + "If this is not expected, please check the input data." + ), + class = class(cnd) + ) + cnd_muffle(cnd) + } + ) +} + +#' Compute Mean Arterial Pressure (MAP) +#' +#' Computes mean arterial pressure (MAP) based on diastolic and systolic blood +#' pressure. Optionally heart rate can be used as well. +#' +#' @param diabp Diastolic blood pressure +#' +#' A numeric vector is expected. +#' +#' @param sysbp Systolic blood pressure +#' +#' A numeric vector is expected. +#' +#' @param hr Heart rate +#' +#' A numeric vector or `NULL` is expected. +#' +#' +#' @details +#' \deqn{\frac{2DIABP + SYSBP}{3}}{(2DIABP + SYSBP) / 3} +#' if it is based on diastolic and systolic blood pressure and +#' \deqn{DIABP + 0.01 e^{4.14 - \frac{40.74}{HR}} (SYSBP - DIABP)}{ +#' DIABP + 0.01 exp(4.14 - 40.74 / HR) (SYSBP - DIABP)} +#' if it is based on diastolic, systolic blood pressure, and heart rate. +#' +#' Usually this computation function can not be used with `%>%`. +#' +#' @return A numeric vector of MAP values +#' +#' @family com_bds_findings +#' +#' @keywords com_bds_findings +#' +#' @export +#' +#' @seealso [derive_param_map()] +#' +#' @examples +#' # Compute MAP based on diastolic and systolic blood pressure +#' compute_map(diabp = 51, sysbp = 121) +#' +#' # Compute MAP based on diastolic and systolic blood pressure and heart rate +#' compute_map(diabp = 51, sysbp = 121, hr = 59) +compute_map <- function(diabp, sysbp, hr = NULL) { + assert_numeric_vector(diabp) + assert_numeric_vector(sysbp) + assert_numeric_vector(hr, optional = TRUE) + + if (is.null(hr)) { + (2 * diabp + sysbp) / 3 + } else { + diabp + 0.01 * exp(4.14 - 40.74 / hr) * (sysbp - diabp) + } +} diff --git a/R/derive_adeg_params.R b/R/derive_param_qtc.R similarity index 65% rename from R/derive_adeg_params.R rename to R/derive_param_qtc.R index 05e0509a30..122c419327 100644 --- a/R/derive_adeg_params.R +++ b/R/derive_param_qtc.R @@ -265,152 +265,3 @@ compute_qtc <- function(qt, rr, method) { ) eval(formulae[[method]]) } - -#' Adds a Parameter for Derived RR (an ECG measurement) -#' -#' @description Adds a record for derived RR based on heart rate for each by group (e.g., -#' subject and visit) where the source parameters are available. -#' -#' **Note:** This is a wrapper function for the more generic `derive_param_computed()`. -#' -#' The analysis value of the new parameter is derived as -#' \deqn{\frac{60000}{HR}}{60000 / HR} -#' -#' @param dataset -#' `r roxygen_param_dataset(expected_vars = c("by_vars"))` -#' `PARAMCD`, and `AVAL` are expected as well. -#' -#' The variable specified by `by_vars` and `PARAMCD` must be a unique key of -#' the input dataset after restricting it by the filter condition (`filter` -#' argument) and to the parameters specified by `hr_code`. -#' -#' @param hr_code HR parameter code -#' -#' The observations where `PARAMCD` equals the specified value are considered -#' as the heart rate assessments. -#' -#' Permitted Values: character value -#' -#' @inheritParams derive_param_map -#' -#' @inheritParams derive_param_computed -#' -#' @inheritParams derive_param_qtc -#' -#' -#' @return The input dataset with the new parameter added. Note, a variable will only -#' be populated in the new parameter rows if it is specified in `by_vars`. -#' -#' @family der_prm_bds_findings -#' @keywords der_prm_bds_findings -#' -#' @export -#' -#' @seealso [compute_rr()] -#' -#' @examples -#' library(tibble) -#' -#' adeg <- tribble( -#' ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~AVALU, ~VISIT, -#' "01-701-1015", "HR", "Heart Rate", 70.14, "beats/min", "BASELINE", -#' "01-701-1015", "QT", "QT Duration", 370, "ms", "WEEK 2", -#' "01-701-1015", "HR", "Heart Rate", 62.66, "beats/min", "WEEK 1", -#' "01-701-1015", "RR", "RR Duration", 710, "ms", "WEEK 2", -#' "01-701-1028", "HR", "Heart Rate", 85.45, "beats/min", "BASELINE", -#' "01-701-1028", "QT", "QT Duration", 480, "ms", "WEEK 2", -#' "01-701-1028", "QT", "QT Duration", 350, "ms", "WEEK 3", -#' "01-701-1028", "HR", "Heart Rate", 56.54, "beats/min", "WEEK 3", -#' "01-701-1028", "RR", "RR Duration", 842, "ms", "WEEK 2" -#' ) -#' -#' derive_param_rr( -#' adeg, -#' by_vars = exprs(USUBJID, VISIT), -#' set_values_to = exprs( -#' PARAMCD = "RRR", -#' PARAM = "RR Duration Rederived (ms)", -#' AVALU = "ms" -#' ), -#' get_unit_expr = AVALU -#' ) -derive_param_rr <- function(dataset, - by_vars, - set_values_to = exprs(PARAMCD = "RRR"), - hr_code = "HR", - get_unit_expr, - filter = NULL) { - assert_vars(by_vars) - assert_data_frame( - dataset, - required_vars = exprs(!!!by_vars, PARAMCD, AVAL) - ) - assert_varval_list(set_values_to, required_elements = "PARAMCD", optional = TRUE) - assert_param_does_not_exist(dataset, set_values_to$PARAMCD) - assert_character_scalar(hr_code) - get_unit_expr <- assert_expr(enexpr(get_unit_expr)) - filter <- assert_filter_cond(enexpr(filter), optional = TRUE) - - assert_unit( - dataset, - param = hr_code, - required_unit = "beats/min", - get_unit_expr = !!get_unit_expr - ) - - withCallingHandlers( - derive_param_computed( - dataset, - filter = !!filter, - parameters = c(hr_code), - by_vars = by_vars, - set_values_to = exprs( - AVAL = compute_rr(!!sym(paste0("AVAL.", hr_code))), - !!!set_values_to - ) - ), - derive_param_computed_all_na = function(cnd) { - cli_inform( - c( - paste( - "No computed records were added because for all potential computed", - "records at least one of the contributing values was {.val {NA}}." - ), - "If this is not expected, please check the input data." - ), - class = class(cnd) - ) - cnd_muffle(cnd) - } - ) -} - -#' Compute RR Interval From Heart Rate -#' -#' Computes RR interval from heart rate. -#' -#' @param hr Heart rate -#' -#' A numeric vector is expected. It is expected that heart rate is measured in -#' beats/min. -#' -#' -#' @details Usually this computation function can not be used with `%>%`. -#' -#' @return RR interval in ms: -#' \deqn{\frac{60000}{HR}}{60000 / HR} -#' -#' @family com_bds_findings -#' -#' @keywords com_bds_findings -#' -#' @export -#' -#' @seealso [derive_param_rr()] -#' -#' @examples -#' compute_rr(hr = 70.14) -compute_rr <- function(hr) { - assert_numeric_vector(hr) - 60000 / hr -} diff --git a/R/derive_param_rr.R b/R/derive_param_rr.R new file mode 100644 index 0000000000..20c908bd58 --- /dev/null +++ b/R/derive_param_rr.R @@ -0,0 +1,148 @@ +#' Adds a Parameter for Derived RR (an ECG measurement) +#' +#' @description Adds a record for derived RR based on heart rate for each by group (e.g., +#' subject and visit) where the source parameters are available. +#' +#' **Note:** This is a wrapper function for the more generic `derive_param_computed()`. +#' +#' The analysis value of the new parameter is derived as +#' \deqn{\frac{60000}{HR}}{60000 / HR} +#' +#' @param dataset +#' `r roxygen_param_dataset(expected_vars = c("by_vars"))` +#' `PARAMCD`, and `AVAL` are expected as well. +#' +#' The variable specified by `by_vars` and `PARAMCD` must be a unique key of +#' the input dataset after restricting it by the filter condition (`filter` +#' argument) and to the parameters specified by `hr_code`. +#' +#' @param hr_code HR parameter code +#' +#' The observations where `PARAMCD` equals the specified value are considered +#' as the heart rate assessments. +#' +#' Permitted Values: character value +#' +#' @inheritParams derive_param_map +#' +#' @inheritParams derive_param_computed +#' +#' @inheritParams derive_param_qtc +#' +#' +#' @return The input dataset with the new parameter added. Note, a variable will only +#' be populated in the new parameter rows if it is specified in `by_vars`. +#' +#' @family der_prm_bds_findings +#' @keywords der_prm_bds_findings +#' +#' @export +#' +#' @seealso [compute_rr()] +#' +#' @examples +#' library(tibble) +#' +#' adeg <- tribble( +#' ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~AVALU, ~VISIT, +#' "01-701-1015", "HR", "Heart Rate", 70.14, "beats/min", "BASELINE", +#' "01-701-1015", "QT", "QT Duration", 370, "ms", "WEEK 2", +#' "01-701-1015", "HR", "Heart Rate", 62.66, "beats/min", "WEEK 1", +#' "01-701-1015", "RR", "RR Duration", 710, "ms", "WEEK 2", +#' "01-701-1028", "HR", "Heart Rate", 85.45, "beats/min", "BASELINE", +#' "01-701-1028", "QT", "QT Duration", 480, "ms", "WEEK 2", +#' "01-701-1028", "QT", "QT Duration", 350, "ms", "WEEK 3", +#' "01-701-1028", "HR", "Heart Rate", 56.54, "beats/min", "WEEK 3", +#' "01-701-1028", "RR", "RR Duration", 842, "ms", "WEEK 2" +#' ) +#' +#' derive_param_rr( +#' adeg, +#' by_vars = exprs(USUBJID, VISIT), +#' set_values_to = exprs( +#' PARAMCD = "RRR", +#' PARAM = "RR Duration Rederived (ms)", +#' AVALU = "ms" +#' ), +#' get_unit_expr = AVALU +#' ) +derive_param_rr <- function(dataset, + by_vars, + set_values_to = exprs(PARAMCD = "RRR"), + hr_code = "HR", + get_unit_expr, + filter = NULL) { + assert_vars(by_vars) + assert_data_frame( + dataset, + required_vars = exprs(!!!by_vars, PARAMCD, AVAL) + ) + assert_varval_list(set_values_to, required_elements = "PARAMCD", optional = TRUE) + assert_param_does_not_exist(dataset, set_values_to$PARAMCD) + assert_character_scalar(hr_code) + get_unit_expr <- assert_expr(enexpr(get_unit_expr)) + filter <- assert_filter_cond(enexpr(filter), optional = TRUE) + + assert_unit( + dataset, + param = hr_code, + required_unit = "beats/min", + get_unit_expr = !!get_unit_expr + ) + + withCallingHandlers( + derive_param_computed( + dataset, + filter = !!filter, + parameters = c(hr_code), + by_vars = by_vars, + set_values_to = exprs( + AVAL = compute_rr(!!sym(paste0("AVAL.", hr_code))), + !!!set_values_to + ) + ), + derive_param_computed_all_na = function(cnd) { + cli_inform( + c( + paste( + "No computed records were added because for all potential computed", + "records at least one of the contributing values was {.val {NA}}." + ), + "If this is not expected, please check the input data." + ), + class = class(cnd) + ) + cnd_muffle(cnd) + } + ) +} + +#' Compute RR Interval From Heart Rate +#' +#' Computes RR interval from heart rate. +#' +#' @param hr Heart rate +#' +#' A numeric vector is expected. It is expected that heart rate is measured in +#' beats/min. +#' +#' +#' @details Usually this computation function can not be used with `%>%`. +#' +#' @return RR interval in ms: +#' \deqn{\frac{60000}{HR}}{60000 / HR} +#' +#' @family com_bds_findings +#' +#' @keywords com_bds_findings +#' +#' @export +#' +#' @seealso [derive_param_rr()] +#' +#' @examples +#' compute_rr(hr = 70.14) +compute_rr <- function(hr) { + assert_numeric_vector(hr) + 60000 / hr +} diff --git a/man/compute_bmi.Rd b/man/compute_bmi.Rd index 68a12c0248..e9ed109ff7 100644 --- a/man/compute_bmi.Rd +++ b/man/compute_bmi.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/derive_advs_params.R +% Please edit documentation in R/derive_param_bmi.R \name{compute_bmi} \alias{compute_bmi} \title{Compute Body Mass Index (BMI)} diff --git a/man/compute_bsa.Rd b/man/compute_bsa.Rd index f16172a3ef..0f3bf00e1d 100644 --- a/man/compute_bsa.Rd +++ b/man/compute_bsa.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/derive_advs_params.R +% Please edit documentation in R/derive_param_bsa.R \name{compute_bsa} \alias{compute_bsa} \title{Compute Body Surface Area (BSA)} diff --git a/man/compute_map.Rd b/man/compute_map.Rd index 67980bf21c..35e2e96812 100644 --- a/man/compute_map.Rd +++ b/man/compute_map.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/derive_advs_params.R +% Please edit documentation in R/derive_param_map.R \name{compute_map} \alias{compute_map} \title{Compute Mean Arterial Pressure (MAP)} diff --git a/man/compute_qtc.Rd b/man/compute_qtc.Rd index 32c3dd0dc6..8bed0198ea 100644 --- a/man/compute_qtc.Rd +++ b/man/compute_qtc.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/derive_adeg_params.R +% Please edit documentation in R/derive_param_qtc.R \name{compute_qtc} \alias{compute_qtc} \title{Compute Corrected QT} diff --git a/man/compute_rr.Rd b/man/compute_rr.Rd index 8215947825..0db38c0141 100644 --- a/man/compute_rr.Rd +++ b/man/compute_rr.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/derive_adeg_params.R +% Please edit documentation in R/derive_param_rr.R \name{compute_rr} \alias{compute_rr} \title{Compute RR Interval From Heart Rate} diff --git a/man/default_qtc_paramcd.Rd b/man/default_qtc_paramcd.Rd index 58caf4dd87..1e9af05ddc 100644 --- a/man/default_qtc_paramcd.Rd +++ b/man/default_qtc_paramcd.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/derive_adeg_params.R +% Please edit documentation in R/derive_param_qtc.R \name{default_qtc_paramcd} \alias{default_qtc_paramcd} \title{Get Default Parameter Code for Corrected QT} diff --git a/man/derive_param_bmi.Rd b/man/derive_param_bmi.Rd index cf6c09c910..c844702b4c 100644 --- a/man/derive_param_bmi.Rd +++ b/man/derive_param_bmi.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/derive_advs_params.R +% Please edit documentation in R/derive_param_bmi.R \name{derive_param_bmi} \alias{derive_param_bmi} \title{Adds a Parameter for BMI} diff --git a/man/derive_param_bsa.Rd b/man/derive_param_bsa.Rd index 865ceebc5e..62db8c00c8 100644 --- a/man/derive_param_bsa.Rd +++ b/man/derive_param_bsa.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/derive_advs_params.R +% Please edit documentation in R/derive_param_bsa.R \name{derive_param_bsa} \alias{derive_param_bsa} \title{Adds a Parameter for BSA (Body Surface Area) Using the Specified Method} diff --git a/man/derive_param_map.Rd b/man/derive_param_map.Rd index a5d841a784..880c8fe7ae 100644 --- a/man/derive_param_map.Rd +++ b/man/derive_param_map.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/derive_advs_params.R +% Please edit documentation in R/derive_param_map.R \name{derive_param_map} \alias{derive_param_map} \title{Adds a Parameter for Mean Arterial Pressure} diff --git a/man/derive_param_qtc.Rd b/man/derive_param_qtc.Rd index 8bd9f9b1f0..a4a826ff49 100644 --- a/man/derive_param_qtc.Rd +++ b/man/derive_param_qtc.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/derive_adeg_params.R +% Please edit documentation in R/derive_param_qtc.R \name{derive_param_qtc} \alias{derive_param_qtc} \title{Adds a Parameter for Corrected QT (an ECG measurement)} diff --git a/man/derive_param_rr.Rd b/man/derive_param_rr.Rd index 8a67a67719..8d06a3e770 100644 --- a/man/derive_param_rr.Rd +++ b/man/derive_param_rr.Rd @@ -1,5 +1,5 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/derive_adeg_params.R +% Please edit documentation in R/derive_param_rr.R \name{derive_param_rr} \alias{derive_param_rr} \title{Adds a Parameter for Derived RR (an ECG measurement)} diff --git a/tests/testthat/_snaps/derive_adeg_params.md b/tests/testthat/_snaps/derive_adeg_params.md deleted file mode 100644 index 8e4f15fb40..0000000000 --- a/tests/testthat/_snaps/derive_adeg_params.md +++ /dev/null @@ -1,19 +0,0 @@ -# derive_param_qtc Test 4: Message if no new records - - Code - actual <- derive_param_qtc(input, by_vars = exprs(USUBJID, VISIT), method = "Bazett", - get_unit_expr = AVALU) - Message - No computed records were added because for all potential computed records at least one of the contributing values was NA. - If this is not expected, please check the input data. - -# derive_param_rr Test 6: Message if no new records - - Code - actual <- derive_param_rr(input, by_vars = exprs(USUBJID, VISIT), - set_values_to = exprs(PARAMCD = "RRR", PARAM = "RR Duration Rederived (ms)", - AVALU = "ms"), get_unit_expr = AVALU) - Message - No computed records were added because for all potential computed records at least one of the contributing values was NA. - If this is not expected, please check the input data. - diff --git a/tests/testthat/_snaps/derive_advs_params.md b/tests/testthat/_snaps/derive_advs_params.md deleted file mode 100644 index cb24b48cf6..0000000000 --- a/tests/testthat/_snaps/derive_advs_params.md +++ /dev/null @@ -1,27 +0,0 @@ -# derive_param_bmi Test 36: BMI parameter NOT added - - Code - result <- derive_param_bmi(input, by_vars = exprs(USUBJID, VISIT), - get_unit_expr = VSSTRESU) - Message - No computed records were added because for all potential computed records at least one of the contributing values was NA. - If this is not expected, please check the input data. - -# derive_param_bsa Test 43: BSA parameter NOT added - - Code - result <- derive_param_bsa(input, by_vars = exprs(USUBJID, VISIT), method = "Mosteller", - get_unit_expr = VSSTRESU) - Message - No computed records were added because for all potential computed records at least one of the contributing values was NA. - If this is not expected, please check the input data. - -# derive_param_map Test 56: MAP parameter NOT added - - Code - result <- derive_param_map(input, by_vars = exprs(USUBJID, VISIT), hr_code = "PULSE", - get_unit_expr = extract_unit(PARAM)) - Message - No computed records were added because for all potential computed records at least one of the contributing values was NA. - If this is not expected, please check the input data. - diff --git a/tests/testthat/_snaps/derive_param_bmi.md b/tests/testthat/_snaps/derive_param_bmi.md new file mode 100644 index 0000000000..58c748322d --- /dev/null +++ b/tests/testthat/_snaps/derive_param_bmi.md @@ -0,0 +1,9 @@ +# derive_param_bmi Test 8: BMI parameter NOT added + + Code + result <- derive_param_bmi(input, by_vars = exprs(USUBJID, VISIT), + get_unit_expr = VSSTRESU) + Message + No computed records were added because for all potential computed records at least one of the contributing values was NA. + If this is not expected, please check the input data. + diff --git a/tests/testthat/_snaps/derive_param_bsa.md b/tests/testthat/_snaps/derive_param_bsa.md new file mode 100644 index 0000000000..a15c331873 --- /dev/null +++ b/tests/testthat/_snaps/derive_param_bsa.md @@ -0,0 +1,9 @@ +# derive_param_bsa Test 27: BSA parameter NOT added + + Code + result <- derive_param_bsa(input, by_vars = exprs(USUBJID, VISIT), method = "Mosteller", + get_unit_expr = VSSTRESU) + Message + No computed records were added because for all potential computed records at least one of the contributing values was NA. + If this is not expected, please check the input data. + diff --git a/tests/testthat/_snaps/derive_param_map.md b/tests/testthat/_snaps/derive_param_map.md new file mode 100644 index 0000000000..b9f2c5978e --- /dev/null +++ b/tests/testthat/_snaps/derive_param_map.md @@ -0,0 +1,9 @@ +# derive_param_map Test 11: MAP parameter NOT added + + Code + result <- derive_param_map(input, by_vars = exprs(USUBJID, VISIT), hr_code = "PULSE", + get_unit_expr = extract_unit(PARAM)) + Message + No computed records were added because for all potential computed records at least one of the contributing values was NA. + If this is not expected, please check the input data. + diff --git a/tests/testthat/_snaps/derive_param_qtc.md b/tests/testthat/_snaps/derive_param_qtc.md new file mode 100644 index 0000000000..0a30e22fc6 --- /dev/null +++ b/tests/testthat/_snaps/derive_param_qtc.md @@ -0,0 +1,9 @@ +# derive_param_qtc Test 4: Message if no new records + + Code + actual <- derive_param_qtc(input, by_vars = exprs(USUBJID, VISIT), method = "Bazett", + get_unit_expr = AVALU) + Message + No computed records were added because for all potential computed records at least one of the contributing values was NA. + If this is not expected, please check the input data. + diff --git a/tests/testthat/_snaps/derive_param_rr.md b/tests/testthat/_snaps/derive_param_rr.md new file mode 100644 index 0000000000..13538df266 --- /dev/null +++ b/tests/testthat/_snaps/derive_param_rr.md @@ -0,0 +1,10 @@ +# derive_param_rr Test 2: Message if no new records + + Code + actual <- derive_param_rr(input, by_vars = exprs(USUBJID, VISIT), + set_values_to = exprs(PARAMCD = "RRR", PARAM = "RR Duration Rederived (ms)", + AVALU = "ms"), get_unit_expr = AVALU) + Message + No computed records were added because for all potential computed records at least one of the contributing values was NA. + If this is not expected, please check the input data. + diff --git a/tests/testthat/test-derive_advs_params.R b/tests/testthat/test-derive_advs_params.R deleted file mode 100644 index 8865493f23..0000000000 --- a/tests/testthat/test-derive_advs_params.R +++ /dev/null @@ -1,1064 +0,0 @@ -# compute_bmi ---- - -## Test 1: BMI calculation - single height & weight values ---- -test_that("compute_bmi Test 1: BMI calculation - single height & weight values", { - # Expected values are taken from the Center of Disease Control and Prevention's - # (CDC) 'Adult BMI Calculator' at - # https://cdc.gov/healthyweight/assessing/bmi/adult_bmi/metric_bmi_calculator/bmi_calculator.html - expect_equal(round(compute_bmi(height = 180, weight = 75), 3L), 23.148) -}) - -## Test 2: compute_bmi BMI calculation - height & weight vectors ---- -test_that("compute_bmi Test 2: compute_bmi BMI calculation - height & weight vectors", { - expect_equal( - round(compute_bmi(height = c(180, 200), weight = c(75, 100)), 3L), - c(23.148, 25) - ) -}) - -## Test 3: BMI height & weight vectors - missing values ---- -test_that("compute_bmi Test 3: BMI height & weight vectors - missing values", { - expect_equal( - compute_bmi(height = c(NA, 200, 0), weight = c(75, NA, 75)), - c(NA_real_, NA_real_, NA_real_) - ) -}) - -# compute_bsa ---- - -## compute_bsa: Mosteller method ---- -# sqrt (Height x Weight / 3600) - -## Test 4: Mosteller method - single height & weight values ---- -test_that("compute_bsa Test 4: Mosteller method - single height & weight values", { - expect_equal( - round(compute_bsa(height = 170, weight = 75, method = "Mosteller"), 3L), - 1.882 - ) -}) - -## Test 5: Mosteller method - height & weight vectors ---- -test_that("compute_bsa Test 5: Mosteller method - height & weight vectors", { - expect_equal( - round(compute_bsa(height = c(170, 185), weight = c(75, 90), method = "Mosteller"), 3L), - c(1.882, 2.151) - ) -}) - -## Test 6: Mosteller method - height & weight vectors - missing values ---- -test_that("compute_bsa Test 6: Mosteller method - height & weight vectors - missing values", { - expect_equal( - compute_bsa(height = c(NA, 185), weight = c(75, NA), method = "Mosteller"), - c(NA_real_, NA_real_) - ) -}) - -## compute_bsa: DuBois-DuBois method ---- -# FORMULA : 0.007184 x (HGT)^0.725 x WGT^0.425 - -## Test 7: DuBois-DuBois method - single height & weight values ---- -test_that("compute_bsa Test 7: DuBois-DuBois method - single height & weight values", { - expect_equal( - round(compute_bsa(height = 170, weight = 75, method = "DuBois-DuBois"), 3L), - 1.864 - ) -}) - -## Test 8: DuBois-DuBois method - height & weight vectors ---- -test_that("compute_bsa Test 8: DuBois-DuBois method - height & weight vectors", { - expect_equal( - round(compute_bsa(height = c(170, 185), weight = c(75, 90), method = "DuBois-DuBois"), 3L), - c(1.864, 2.141) - ) -}) - -## Test 9: DuBois-DuBois method - hgt and wgt vectors - missing values ---- -test_that("compute_bsa Test 9: DuBois-DuBois method - hgt and wgt vectors - missing values", { - expect_equal( - compute_bsa(height = c(NA, 185), weight = c(75, NA), method = "DuBois-DuBois"), - c(NA_real_, NA_real_) - ) -}) - -## compute_bsa: Haycock method (Test 03.xx) ---- -# 0.024265 x HGT^0.3964 x WGT^0.5378 - -## Test 10: Haycock method - single height & weight values ---- -test_that("compute_bsa Test 10: Haycock method - single height & weight values", { - expect_equal( - round(compute_bsa(height = 170, weight = 75, method = "Haycock"), 3L), - 1.895 - ) -}) - -## Test 11: Haycock method - height & weight vectors ---- -test_that("compute_bsa Test 11: Haycock method - height & weight vectors", { - expect_equal( - round(compute_bsa(height = c(170, 185), weight = c(75, 90), method = "Haycock"), 3L), - c(1.895, 2.161) - ) -}) - -## Test 12: Haycock method - height & weight vectors - missing values ---- -test_that("compute_bsa Test 12: Haycock method - height & weight vectors - missing values", { - expect_equal( - compute_bsa(height = c(NA, 185), weight = c(75, NA), method = "Haycock"), - c(NA_real_, NA_real_) - ) -}) - -## compute_bsa: Gehan-George method ---- -# 0.0235 x HGT^0.42246 x WGT^0.51456 - -## Test 13: Gehan-George method - single height & weight values ---- -test_that("compute_bsa Test 13: Gehan-George method - single height & weight values", { - expect_equal( - round(compute_bsa(height = 170, weight = 75, method = "Gehan-George"), 3L), - 1.897 - ) -}) - -## Test 14: Gehan-George method - height & weight vectors ---- -test_that("compute_bsa Test 14: Gehan-George method - height & weight vectors", { - expect_equal( - round(compute_bsa(height = c(170, 185), weight = c(75, 90), method = "Gehan-George"), 3L), - c(1.897, 2.16) - ) -}) - -## Test 15: Gehan-George method - height & weight vectors - missing values ---- -test_that("compute_bsa Test 15: Gehan-George method - height & weight vectors - missing values", { - expect_equal( - compute_bsa(height = c(NA, 185), weight = c(75, NA), method = "Gehan-George"), - c(NA_real_, NA_real_) - ) -}) - -## compute_bsa: Boyd method ---- -# 0.0003207 x (HGT^0.3) x (1000 x WGT)^(0.7285 - (0.0188 x log10(1000 x WGT))) - -## Test 16: Boyd method - single height & weight values ---- -test_that("compute_bsa Test 16: Boyd method - single height & weight values", { - expect_equal( - round(compute_bsa(height = 170, weight = 75, method = "Boyd"), 3L), - 1.905 - ) -}) - -## Test 17: Boyd method - height & weight vectors ---- -test_that("compute_bsa Test 17: Boyd method - height & weight vectors", { - expect_equal( - round(compute_bsa(height = c(170, 185), weight = c(75, 90), method = "Boyd"), 3L), - c(1.905, 2.158) - ) -}) - -## Test 18: Boyd method - height & weight vectors - missing values ---- -test_that("compute_bsa Test 18: Boyd method - height & weight vectors - missing values", { - expect_equal( - compute_bsa(height = c(NA, 185), weight = c(75, NA), method = "Boyd"), - c(NA_real_, NA_real_) - ) -}) - -## compute_bsa: Fujimoto method ---- -# 0.008883 x HGT^0.663 x WGT^0.444 - -## Test 19: Fujimoto method - single height & weight values ---- -test_that("compute_bsa Test 19: Fujimoto method - single height & weight values", { - expect_equal( - round(compute_bsa(height = 170, weight = 75, method = "Fujimoto"), 3L), - 1.819 - ) -}) - -## Test 20: Fujimoto method - height & weight vectors ---- -test_that("compute_bsa Test 20: Fujimoto method - height & weight vectors", { - expect_equal( - round(compute_bsa(height = c(170, 185), weight = c(75, 90), method = "Fujimoto"), 3L), - c(1.819, 2.086) - ) -}) - -## Test 21: Fujimoto method - height & weight vectors - missing values ---- -test_that("compute_bsa Test 21: Fujimoto method - height & weight vectors - missing values", { - expect_equal( - compute_bsa(height = c(NA, 185), weight = c(75, NA), method = "Fujimoto"), - c(NA_real_, NA_real_) - ) -}) - -## compute_bsa: Takahira method ---- -# 0.007241 x HGT^0.725 x WGT^0.425 - -## Test 22: Takahira method - single height & weight values ---- -test_that("compute_bsa Test 22: Takahira method - single height & weight values", { - expect_equal( - round(compute_bsa(height = 170, weight = 75, method = "Takahira"), 3L), - 1.878 - ) -}) - -## Test 23: Takahira method - height & weight vectors ---- -test_that("compute_bsa Test 23: Takahira method - height & weight vectors", { - expect_equal( - round(compute_bsa(height = c(170, 185), weight = c(75, 90), method = "Takahira"), 3L), - c(1.878, 2.158) - ) -}) - -## Test 24: Takahira method - height & weight vectors - missing values ---- -test_that("compute_bsa Test 24: Takahira method - height & weight vectors - missing values", { - expect_equal( - compute_bsa(height = c(NA, 185), weight = c(75, NA), method = "Takahira"), - c(NA_real_, NA_real_) - ) -}) - -## compute_bsa: Check error messages ---- - -## Test 25: an error is issued if an invalid method is specified ---- -test_that("compute_bsa Test 25: an error is issued if an invalid method is specified", { - expect_error( - compute_bsa(height = c(170, 185), weight = c(75, 90), method = "unknown-method"), - class = "assert_character_scalar" - ) -}) - -# compute_map ---- - -## compute_map: DBP & SBP ---- -# ((2 x DBP) + SBP) / 3 - -## Test 26: MAP based on diastolic & systolic BP - single values ---- -test_that("compute_map Test 26: MAP based on diastolic & systolic BP - single values", { - expect_equal(round(compute_map(diabp = 51, sysbp = 121), 3L), 74.333) -}) - -## Test 27: MAP based on diastolic & systolic BP - vectors ---- -test_that("compute_map Test 27: MAP based on diastolic & systolic BP - vectors", { - expect_equal( - round(compute_map(diabp = c(51, 61), sysbp = c(121, 141)), 3L), c(74.333, 87.667) - ) -}) - -## Test 28: MAP based on diastolic & systolic BP with missing values ---- -test_that("compute_map Test 28: MAP based on diastolic & systolic BP with missing values", { - expect_equal( - compute_map(diabp = c(NA, 61), sysbp = c(121, NA)), c(NA_real_, NA_real_) - ) -}) - -## compute_map: DBP, SBP & HR ---- -# DBP + 0.01 x exp(4.14 - 40.74 / PULSE) x (SBP - DBP) - -## Test 29: MAP based on DBP & SBP & heart rate - single values ---- -test_that("compute_map Test 29: MAP based on DBP & SBP & heart rate - single values", { - expect_equal( - round(compute_map(diabp = 51, sysbp = 121, hr = 59), 3L), 73.039 - ) -}) - -## Test 30: MAP based on diastolic, systolic BP & heart rate - vectors ---- -test_that("compute_map Test 30: MAP based on diastolic, systolic BP & heart rate - vectors", { - expect_equal( - round(compute_map(diabp = c(51, 91), sysbp = c(121, 101), hr = c(59, 62)), 3L), - c(73.039, 94.255) - ) -}) - -## Test 31: MAP based on DBP, SBP & heart rate - with missing values ---- -test_that("compute_map Test 31: MAP based on DBP, SBP & heart rate - with missing values", { - expect_equal( - compute_map(diabp = c(NA, 61, 51), sysbp = c(121, NA, 121), hr = c(59, 62, NA)), - c(NA_real_, NA_real_, NA_real_) - ) -}) - -# derive_param_bmi ---- - -## derive_param_bmi: Error checks ---- - -## Test 32: BMI parameter NOT added - wrong hgt unit ---- -test_that("derive_param_bmi Test 32: BMI parameter NOT added - wrong hgt unit", { - input <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, - # Wrong unit for HEIGHT should be cm - "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "m", 170, - "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 85, - ) - - expect_error( - derive_param_bmi(input, by_vars = exprs(USUBJID, VISIT), get_unit_expr = VSSTRESU), - class = "assert_unit" - ) -}) - -## Test 33: BMI parameter NOT added - wrong wgt unit ---- -test_that("derive_param_bmi Test 33: BMI parameter NOT added - wrong wgt unit", { - input <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, - "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, - # Wrong unit for WEIGHT should be kg - "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "g", 85, - ) - - expect_error( - derive_param_bmi(input, by_vars = exprs(USUBJID, VISIT), get_unit_expr = VSSTRESU), - class = "assert_unit" - ) -}) - -## Test 34: BMI parameter NOT added - multiple unit for wgt ---- -test_that("derive_param_bmi Test 34: BMI parameter NOT added - multiple unit for wgt", { - input <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, - "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, - # Multiple units for WEIGHT - "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 85, - "01-701-1016", "WEIGHT", "Weight (kg)", "BASELINE", "g", 8500, - ) - - expect_error( - derive_param_bmi(input, by_vars = exprs(USUBJID, VISIT), get_unit_expr = VSSTRESU), - class = "assert_unit" - ) -}) - -## Test 35: BMI parameter NOT added - PARAMCD not set ---- -test_that("derive_param_bmi Test 35: BMI parameter NOT added - PARAMCD not set", { - input <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, - "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, - "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 85, - ) - - expect_error( - derive_param_bmi( - input, - by_vars = exprs(USUBJID, VISIT), - set_values_to = exprs(PARAM = "Body Mass Index"), - get_unit_expr = VSSTRESU - ), - class = "assert_varval_list" - ) -}) - -## derive_param_bmi: No obs added ---- - -## Test 36: BMI parameter NOT added ---- -test_that("derive_param_bmi Test 36: BMI parameter NOT added", { - expected_output <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, - "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, - # WEIGHT set to NA - so BMI not calculated - "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", NA, - "01-701-1015", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 78, - # HEIGHT set to NA - so BMI not calculated - "01-701-1028", "HEIGHT", "Height (cm)", "BASELINE", "cm", NA, - "01-701-1028", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 90, - "01-701-1028", "HEIGHT", "Height (cm)", "MONTH 1", "cm", 88, - ) - - input <- expected_output - - expect_snapshot( - result <- derive_param_bmi( - input, - by_vars = exprs(USUBJID, VISIT), - get_unit_expr = VSSTRESU - ) - ) - - expect_dfs_equal( - result, - expected_output, - keys = c("USUBJID", "PARAMCD", "VISIT") - ) -}) - -## derive_param_bmi: Obs created ---- - -bmi <- function(hgt, wgt) { - wgt / (hgt / 100)^2 -} - -## Test 37: BMI parameter is correctly added ---- -test_that("derive_param_bmi Test 37: BMI parameter is correctly added", { - expected_output <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, - "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, - "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 75, - # New row added for BMI for SUBJID="01-701-1015" and VISIT="BASELINE" - # WEIGHT = 75 and HEIGHT = 170 - "01-701-1015", "BMI", NA, "BASELINE", NA, bmi(170, 75), - "01-701-1015", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 78, - "01-701-1028", "HEIGHT", "Height (cm)", "BASELINE", "cm", 185, - "01-701-1028", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 90, - # New row added for BMI for SUBJID="01-701-1028" and VISIT='BASELINE' - # WEIGHT = 90 and HEIGHT = 185 - "01-701-1028", "BMI", NA, "BASELINE", NA, bmi(185, 90), - "01-701-1028", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 88, - ) - - input <- expected_output %>% filter(PARAMCD != "BMI") - - expect_dfs_equal( - derive_param_bmi(input, by_vars = exprs(USUBJID, VISIT), get_unit_expr = VSSTRESU), - expected_output, - keys = c("USUBJID", "PARAMCD", "VISIT") - ) -}) - - -# Derive BMI where height is measured only once -## Test 38: Derive BMI where height is measured only once ---- -test_that("derive_param_bmi Test 38: Derive BMI where height is measured only once", { - input <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~AVALU, ~VISIT, - "01-701-1015", "HEIGHT", "Height (cm)", 147.0, "cm", "SCREENING", - "01-701-1015", "WEIGHT", "Weight (kg)", 54.0, "kg", "SCREENING", - "01-701-1015", "WEIGHT", "Weight (kg)", 54.4, "kg", "BASELINE", - "01-701-1015", "WEIGHT", "Weight (kg)", 53.1, "kg", "WEEK 2", - "01-701-1028", "HEIGHT", "Height (cm)", 163.0, "cm", "SCREENING", - "01-701-1028", "WEIGHT", "Weight (kg)", 78.5, "kg", "SCREENING", - "01-701-1028", "WEIGHT", "Weight (kg)", 80.3, "kg", "BASELINE", - "01-701-1028", "WEIGHT", "Weight (kg)", 80.7, "kg", "WEEK 2" - ) - - expected_output <- derive_param_computed( - input, - by_vars = exprs(USUBJID, VISIT), - parameters = "WEIGHT", - set_values_to = exprs( - AVAL = AVAL.WEIGHT / (AVAL.HEIGHT / 100)^2, - PARAMCD = "BMI", - PARAM = "Body Mass Index (kg/m^2)", - AVALU = "kg/m^2" - ), - constant_parameters = c("HEIGHT"), - constant_by_vars = exprs(USUBJID) - ) - - expect_dfs_equal( - expected_output, - derive_param_bmi( - input, - by_vars = exprs(USUBJID, VISIT), - weight_code = "WEIGHT", - height_code = "HEIGHT", - set_values_to = exprs( - PARAMCD = "BMI", - PARAM = "Body Mass Index (kg/m^2)", - AVALU = "kg/m^2" - ), - get_unit_expr = extract_unit(PARAM), - constant_by_vars = exprs(USUBJID) - ), - keys = c("USUBJID", "PARAMCD", "VISIT") - ) -}) - -# derive_param_bsa ---- - -## derive_param_bsa: Error checks ---- - -## Test 39: BSA parameter NOT added - wrong unit for height ---- -test_that("derive_param_bsa Test 39: BSA parameter NOT added - wrong unit for height", { - input <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, - # Wrong unit for HEIGHT should be cm - "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "m", 170, - "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 85, - ) - - expect_error( - derive_param_bsa( - input, - by_vars = exprs(USUBJID, VISIT), - method = "Mosteller", - get_unit_expr = VSSTRESU - ), - class = "assert_unit" - ) -}) - -## Test 40: BSA parameter NOT added - wrong unit for weight ---- -test_that("derive_param_bsa Test 40: BSA parameter NOT added - wrong unit for weight", { - input <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, - "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, - # Wrong unit for WEIGHT should be kg - "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "g", 85, - ) - - expect_error( - derive_param_bsa( - input, - by_vars = exprs(USUBJID, VISIT), - method = "Mosteller", - get_unit_expr = VSSTRESU - ), - class = "assert_unit" - ) -}) - -## Test 41: BSA parameter NOT added - multiple unit for weight ---- -test_that("derive_param_bsa Test 41: BSA parameter NOT added - multiple unit for weight", { - input <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, - "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, - # Multiple units for WEIGHT - "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 85, - "01-701-1016", "WEIGHT", "Weight (kg)", "BASELINE", "g", 8500, - ) - - expect_error( - derive_param_bsa( - input, - by_vars = exprs(USUBJID, VISIT), - method = "Mosteller", - get_unit_expr = VSSTRESU - ), - class = "assert_unit" - ) -}) - -## Test 42: BSA parameter NOT added - PARAMCD not set ---- -test_that("derive_param_bsa Test 42: BSA parameter NOT added - PARAMCD not set", { - input <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, - "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, - "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 85, - ) - - expect_error( - derive_param_bsa( - input, - by_vars = exprs(USUBJID, VISIT), - method = "Mosteller", - set_values_to = exprs(PARAM = "Body Surface Area"), - get_unit_expr = VSSTRESU - ), - class = "assert_varval_list" - ) -}) - -## derive_param_bsa: No obs added ---- - -## Test 43: BSA parameter NOT added ---- -test_that("derive_param_bsa Test 43: BSA parameter NOT added", { - expected_output <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, - "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, - # WEIGHT set to NA - so BSA not calculated - "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", NA, - "01-701-1015", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 78, - # HEIGHT set to NA - so BSA not calculated - "01-701-1028", "HEIGHT", "Height (cm)", "BASELINE", "cm", NA, - "01-701-1028", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 90, - "01-701-1028", "HEIGHT", "Height (cm)", "MONTH 1", "cm", 88, - ) - - input <- expected_output - - expect_snapshot( - result <- derive_param_bsa( - input, - by_vars = exprs(USUBJID, VISIT), - method = "Mosteller", - get_unit_expr = VSSTRESU - ) - ) - - expect_dfs_equal( - result, - expected_output, - keys = c("USUBJID", "PARAMCD", "VISIT") - ) -}) - -## derive_param_bsa: Obs created ---- - -mosteller <- function(hgt, wgt) { - sqrt(hgt * wgt / 3600) -} - -## Test 44: BSA parameter (Mosteller Method) is correctly added ---- -test_that("derive_param_bsa Test 44: BSA parameter (Mosteller Method) is correctly added", { - expected_output <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, - "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, - "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 75, - # New row added for BMI for SUBJID="01-701-1015" and VISIT="BASELINE" - # WEIGHT = 75 and HEIGHT = 170 - "01-701-1015", "BSA", NA, "BASELINE", NA, mosteller(170, 75), - "01-701-1015", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 78, - "01-701-1028", "HEIGHT", "Height (cm)", "BASELINE", "cm", 185, - "01-701-1028", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 90, - # New row added for BMI for SUBJID="01-701-1028" and VISIT='BASELINE' - # WEIGHT = 90 and HEIGHT = 185 - "01-701-1028", "BSA", NA, "BASELINE", NA, mosteller(185, 90), - "01-701-1028", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 88, - ) - - input <- expected_output %>% filter(PARAMCD != "BSA") - - expect_dfs_equal( - derive_param_bsa(input, - by_vars = exprs(USUBJID, VISIT), - method = "Mosteller", - get_unit_expr = VSSTRESU - ), - expected_output, - keys = c("USUBJID", "PARAMCD", "VISIT") - ) -}) - -dubois <- function(hgt, wgt) { - 0.007184 * hgt^0.725 * wgt^0.425 -} - -## Test 45: BSA parameter (DuBois-DuBois method) is correctly added ---- -test_that("derive_param_bsa Test 45: BSA parameter (DuBois-DuBois method) is correctly added", { - expected_output <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, - "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, - "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 75, - # New row added for BMI for SUBJID="01-701-1015" and VISIT="BASELINE" - # WEIGHT = 75 and HEIGHT = 170 - "01-701-1015", "BSA", NA, "BASELINE", NA, dubois(170, 75), - "01-701-1015", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 78, - "01-701-1028", "HEIGHT", "Height (cm)", "BASELINE", "cm", 185, - "01-701-1028", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 90, - # New row added for BMI for SUBJID="01-701-1028" and VISIT='BASELINE' - # WEIGHT = 90 and HEIGHT = 185 - "01-701-1028", "BSA", NA, "BASELINE", NA, dubois(185, 90), - "01-701-1028", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 88, - ) - - input <- expected_output %>% filter(PARAMCD != "BSA") - - expect_dfs_equal( - derive_param_bsa( - input, - by_vars = exprs(USUBJID, VISIT), - method = "DuBois-DuBois", - get_unit_expr = VSSTRESU - ), - expected_output, - keys = c("USUBJID", "PARAMCD", "VISIT") - ) -}) - -haycock <- function(hgt, wgt) { - 0.024265 * hgt^0.3964 * wgt^0.5378 -} - -## Test 46: BSA parameter (Haycock method) is correctly added ---- -test_that("derive_param_bsa Test 46: BSA parameter (Haycock method) is correctly added", { - expected_output <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, - "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, - "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 75, - # New row added for BMI for SUBJID="01-701-1015" and VISIT="BASELINE" - # WEIGHT = 75 and HEIGHT = 170 - "01-701-1015", "BSA", NA, "BASELINE", NA, haycock(170, 75), - "01-701-1015", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 78, - "01-701-1028", "HEIGHT", "Height (cm)", "BASELINE", "cm", 185, - "01-701-1028", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 90, - # New row added for BMI for SUBJID="01-701-1028" and VISIT='BASELINE' - # WEIGHT = 90 and HEIGHT = 185 - "01-701-1028", "BSA", NA, "BASELINE", NA, haycock(185, 90), - "01-701-1028", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 88, - ) - - input <- expected_output %>% filter(PARAMCD != "BSA") - - expect_dfs_equal( - derive_param_bsa(input, - by_vars = exprs(USUBJID, VISIT), - method = "Haycock", - get_unit_expr = VSSTRESU - ), - expected_output, - keys = c("USUBJID", "PARAMCD", "VISIT") - ) -}) - -gehan <- function(hgt, wgt) { - 0.0235 * hgt^0.42246 * wgt^0.51456 -} - -## Test 47: BSA parameter (Gehan-George method) is correctly added ---- -test_that("derive_param_bsa Test 47: BSA parameter (Gehan-George method) is correctly added", { - expected_output <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, - "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, - "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 75, - # New row added for BMI for SUBJID="01-701-1015" and VISIT="BASELINE" - # WEIGHT = 75 and HEIGHT = 170 - "01-701-1015", "BSA", NA, "BASELINE", NA, gehan(170, 75), - "01-701-1015", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 78, - "01-701-1028", "HEIGHT", "Height (cm)", "BASELINE", "cm", 185, - "01-701-1028", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 90, - # New row added for BMI for SUBJID="01-701-1028" and VISIT='BASELINE' - # WEIGHT = 90 and HEIGHT = 185 - "01-701-1028", "BSA", NA, "BASELINE", NA, gehan(185, 90), - "01-701-1028", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 88, - ) - - input <- expected_output %>% filter(PARAMCD != "BSA") - - expect_dfs_equal( - derive_param_bsa( - input, - by_vars = exprs(USUBJID, VISIT), - method = "Gehan-George", - get_unit_expr = VSSTRESU - ), - expected_output, - keys = c("USUBJID", "PARAMCD", "VISIT") - ) -}) - -boyd <- function(hgt, wgt) { - 0.0003207 * (hgt^0.3) * (1000 * wgt)^(0.7285 - (0.0188 * log10(1000 * wgt))) # nolint -} - -## Test 48: BSA parameter (Boyd method) is correctly added ---- -test_that("derive_param_bsa Test 48: BSA parameter (Boyd method) is correctly added", { - expected_output <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, - "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, - "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 75, - # New row added for BMI for SUBJID="01-701-1015" and VISIT="BASELINE" - # WEIGHT = 75 and HEIGHT = 170 - "01-701-1015", "BSA", NA, "BASELINE", NA, boyd(170, 75), - "01-701-1015", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 78, - "01-701-1028", "HEIGHT", "Height (cm)", "BASELINE", "cm", 185, - "01-701-1028", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 90, - # New row added for BMI for SUBJID="01-701-1028" and VISIT='BASELINE' - # WEIGHT = 90 and HEIGHT = 185 - "01-701-1028", "BSA", NA, "BASELINE", NA, boyd(185, 90), - "01-701-1028", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 88, - ) - - input <- expected_output %>% filter(PARAMCD != "BSA") - - expect_dfs_equal( - derive_param_bsa(input, - by_vars = exprs(USUBJID, VISIT), - method = "Boyd", - get_unit_expr = VSSTRESU - ), - expected_output, - keys = c("USUBJID", "PARAMCD", "VISIT") - ) -}) - -fujimoto <- function(hgt, wgt) { - 0.008883 * hgt^0.663 * wgt^0.444 -} - -## Test 49: BSA parameter (Fujimoto method) is correctly added ---- -test_that("derive_param_bsa Test 49: BSA parameter (Fujimoto method) is correctly added", { - expected_output <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, - "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, - "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 75, - # New row added for BMI for SUBJID="01-701-1015" and VISIT="BASELINE" - # WEIGHT = 75 and HEIGHT = 170 - "01-701-1015", "BSA", NA, "BASELINE", NA, fujimoto(170, 75), - "01-701-1015", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 78, - "01-701-1028", "HEIGHT", "Height (cm)", "BASELINE", "cm", 185, - "01-701-1028", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 90, - # New row added for BMI for SUBJID="01-701-1028" and VISIT='BASELINE' - # WEIGHT = 90 and HEIGHT = 185 - "01-701-1028", "BSA", NA, "BASELINE", NA, fujimoto(185, 90), - "01-701-1028", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 88, - ) - - input <- expected_output %>% filter(PARAMCD != "BSA") - - expect_dfs_equal( - derive_param_bsa( - input, - by_vars = exprs(USUBJID, VISIT), - method = "Fujimoto", - get_unit_expr = VSSTRESU - ), - expected_output, - keys = c("USUBJID", "PARAMCD", "VISIT") - ) -}) - -takahira <- function(hgt, wgt) { - 0.007241 * hgt^0.725 * wgt^0.425 -} - -## Test 50: BSA parameter (Takahira method) is correctly added ---- -test_that("derive_param_bsa Test 50: BSA parameter (Takahira method) is correctly added", { - expected_output <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, - "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, - "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 75, - # New row added for BMI for SUBJID="01-701-1015" and VISIT="BASELINE" - # WEIGHT = 75 and HEIGHT = 170 - "01-701-1015", "BSA", NA, "BASELINE", NA, takahira(170, 75), - "01-701-1015", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 78, - "01-701-1028", "HEIGHT", "Height (cm)", "BASELINE", "cm", 185, - "01-701-1028", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 90, - # New row added for BMI for SUBJID="01-701-1028" and VISIT='BASELINE' - # WEIGHT = 90 and HEIGHT = 185 - "01-701-1028", "BSA", NA, "BASELINE", NA, takahira(185, 90), - "01-701-1028", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 88, - ) - - input <- expected_output %>% filter(PARAMCD != "BSA") - - expect_dfs_equal( - derive_param_bsa( - input, - by_vars = exprs(USUBJID, VISIT), - method = "Takahira", - get_unit_expr = VSSTRESU - ), - expected_output, - keys = c("USUBJID", "PARAMCD", "VISIT") - ) -}) - -## Test 51: Derive BSA where height is measured only once ---- -test_that("derive_param_bsa Test 51: Derive BSA where height is measured only once", { - input <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~AVALU, ~VISIT, - "01-701-1015", "HEIGHT", "Height (cm)", 147.0, "cm", "SCREENING", - "01-701-1015", "WEIGHT", "Weight (kg)", 54.0, "kg", "SCREENING", - "01-701-1015", "WEIGHT", "Weight (kg)", 54.4, "kg", "BASELINE", - "01-701-1015", "WEIGHT", "Weight (kg)", 53.1, "kg", "WEEK 2", - "01-701-1028", "HEIGHT", "Height (cm)", 163.0, "cm", "SCREENING", - "01-701-1028", "WEIGHT", "Weight (kg)", 78.5, "kg", "SCREENING", - "01-701-1028", "WEIGHT", "Weight (kg)", 80.3, "kg", "BASELINE", - "01-701-1028", "WEIGHT", "Weight (kg)", 80.7, "kg", "WEEK 2" - ) - - expected_output <- derive_param_computed( - input, - by_vars = exprs(USUBJID, VISIT), - parameters = "WEIGHT", - set_values_to = exprs( - AVAL = compute_bsa( - height = AVAL.HEIGHT, weight = AVAL.WEIGHT, - method = "Mosteller" - ), - PARAMCD = "BSA", - PARAM = "Body Surface Area (m^2)", - AVALU = "m^2" - ), - constant_parameters = c("HEIGHT"), - constant_by_vars = exprs(USUBJID) - ) - - expect_dfs_equal( - expected_output, - derive_param_bsa( - input, - by_vars = exprs(USUBJID, VISIT), - method = "Mosteller", - set_values_to = exprs( - PARAMCD = "BSA", - PARAM = "Body Surface Area (m^2)", - AVALU = "m^2" - ), - get_unit_expr = extract_unit(PARAM), - constant_by_vars = exprs(USUBJID) - ), - keys = c("USUBJID", "PARAMCD", "VISIT") - ) -}) - - -# derive_param_map ---- - -## derive_param_map: Error checks ---- - -## Test 52: MAP parameter NOT added - wrong DIABP unit ---- -test_that("derive_param_map Test 52: MAP parameter NOT added - wrong DIABP unit", { - input <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~VISIT, - "01-701-1015", "DIABP", "Diastolic Blood Pressure (mHg)", 51, "BASELINE", - "01-701-1015", "SYSBP", "Systolic Blood Pressure (mmHg)", 121, "BASELINE", - ) - - expect_error( - derive_param_map( - input, - by_vars = exprs(USUBJID, VISIT), - get_unit_expr = extract_unit(PARAM) - ), - class = "assert_unit" - ) -}) - -## Test 53: MAP parameter NOT added - wrong SYSBP unit ---- -test_that("derive_param_map Test 53: MAP parameter NOT added - wrong SYSBP unit", { - input <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~VISIT, - "01-701-1015", "DIABP", "Diastolic Blood Pressure (mmHg)", 51, "BASELINE", - "01-701-1015", "SYSBP", "Systolic Blood Pressure (mHg)", 121, "BASELINE", - ) - - expect_error( - derive_param_map( - input, - by_vars = exprs(USUBJID, VISIT), - get_unit_expr = extract_unit(PARAM) - ), - class = "assert_unit" - ) -}) - -## Test 54: MAP parameter NOT added - wrong PULSE unit ---- -test_that("derive_param_map Test 54: MAP parameter NOT added - wrong PULSE unit", { - input <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~VISIT, - "01-701-1015", "DIABP", "Diastolic Blood Pressure (mmHg)", 51, "BASELINE", - "01-701-1015", "SYSBP", "Systolic Blood Pressure (mmHg)", 121, "BASELINE", - "01-701-1015", "PULSE", "Pulse (beats/m)", 65, "BASELINE", - ) - - expect_error( - derive_param_map( - input, - by_vars = exprs(USUBJID, VISIT), - hr_code = "PULSE", - get_unit_expr = extract_unit(PARAM) - ), - class = "assert_unit" - ) -}) - -## Test 55: MAP parameter NOT added - PARAMCD not set ---- -test_that("derive_param_map Test 55: MAP parameter NOT added - PARAMCD not set", { - input <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~VISIT, - "01-701-1015", "DIABP", "Diastolic Blood Pressure (mmHg)", 51, "BASELINE", - "01-701-1015", "SYSBP", "Systolic Blood Pressure (mmHg)", 121, "BASELINE", - ) - - expect_error( - derive_param_map( - input, - by_vars = exprs(USUBJID, VISIT), - set_values_to = exprs(PARAM = "Mean Arterial Pressure"), - get_unit_expr = extract_unit(PARAM) - ), - class = "assert_varval_list" - ) -}) - -## derive_param_map: No obs added ---- - -## Test 56: MAP parameter NOT added ---- -test_that("derive_param_map Test 56: MAP parameter NOT added", { - expected_output <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~VISIT, - "01-701-1015", "DIABP", "Diastolic Blood Pressure (mmHg)", NA, "BASELINE", - "01-701-1015", "DIABP", "Diastolic Blood Pressure (mmHg)", 50, "WEEK 2", - "01-701-1015", "DIABP", "Diastolic Blood Pressure (mmHg)", 55, "WEEK 4", - "01-701-1015", "SYSBP", "Systolic Blood Pressure (mmHg)", 121, "BASELINE", - "01-701-1015", "SYSBP", "Systolic Blood Pressure (mmHg)", NA, "WEEK 2", - "01-701-1015", "SYSBP", "Systolic Blood Pressure (mmHg)", 127, "WEEK 4", - "01-701-1015", "PULSE", "Pulse (beats/min)", 65, "BASELINE", - "01-701-1015", "PULSE", "Pulse (beats/min)", 68, "WEEK 2", - "01-701-1015", "PULSE", "Pulse (beats/min)", NA, "WEEK 4", - ) - - input <- expected_output - - expect_snapshot( - result <- derive_param_map( - input, - by_vars = exprs(USUBJID, VISIT), - hr_code = "PULSE", - get_unit_expr = extract_unit(PARAM) - ) - ) - - expect_dfs_equal( - result, - expected_output, - keys = c("USUBJID", "PARAMCD", "VISIT") - ) -}) - -## derive_param_map: Obs created ---- - -maphr <- function(sbp, dbp, hr) { - dbp + 0.01 * exp(4.14 - 40.74 / hr) * (sbp - dbp) -} - -## Test 57: MAP parameter (DBP/SBP/PULSE) is correctly added ---- -test_that("derive_param_map Test 57: MAP parameter (DBP/SBP/PULSE) is correctly added", { - expected_output <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~AVAL, - "01-701-1015", "PULSE", "Pulse (beats/min)", "BASELINE", 59, - "01-701-1015", "DIABP", "Diastolic Blood Pressure (mmHg)", "BASELINE", 51, - "01-701-1015", "SYSBP", "Systolic Blood Pressure (mmHg)", "BASELINE", 121, - # New row added for MAP for SUBJID="01-701-1015" and VISIT="BASELINE" - # PULSE = 59 DIABP = 51 and SYSBP = 121 - "01-701-1015", "MAP", NA, "BASELINE", maphr(121, 51, 59), - "01-701-1028", "PULSE", "Pulse (beats/min)", "WEEK 2", 61, - "01-701-1028", "DIABP", "Diastolic Blood Pressure (mmHg)", "WEEK 2", 50, - "01-701-1028", "SYSBP", "Systolic Blood Pressure (mmHg)", "WEEK 2", 125, - # New row added for MAP for SUBJID="01-701-1028" and VISIT="WEEK 2" - # PULSE = 61 DIABP = 50 and SYSBP = 125 - "01-701-1028", "MAP", NA, "WEEK 2", maphr(125, 50, 61), - ) - - input <- expected_output %>% filter(PARAMCD != "MAP") - - expect_dfs_equal( - derive_param_map( - input, - by_vars = exprs(USUBJID, VISIT), - hr_code = "PULSE", - get_unit_expr = extract_unit(PARAM) - ), - expected_output, - keys = c("USUBJID", "PARAMCD", "VISIT") - ) -}) - -map <- function(sbp, dbp) { - (2 * dbp + sbp) / 3 -} - -## Test 58: MAP parameter (DBP/SBP) is correctly added ---- -test_that("derive_param_map Test 58: MAP parameter (DBP/SBP) is correctly added", { - expected_output <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~AVAL, - "01-701-1015", "DIABP", "Diastolic Blood Pressure (mmHg)", "BASELINE", 51, - "01-701-1015", "SYSBP", "Systolic Blood Pressure (mmHg)", "BASELINE", 121, - # New row added for MAP for SUBJID="01-701-1015" and VISIT="BASELINE" - # DIABP = 51 and SYSBP = 121 - "01-701-1015", "MAP", NA, "BASELINE", map(121, 51), - "01-701-1028", "DIABP", "Diastolic Blood Pressure (mmHg)", "WEEK 2", 50, - "01-701-1028", "SYSBP", "Systolic Blood Pressure (mmHg)", "WEEK 2", 125, - # New row added for MAP for SUBJID="01-701-1028" and VISIT="WEEK 2" - # DIABP = 50 and SYSBP = 125 - "01-701-1028", "MAP", NA, "WEEK 2", map(125, 50), - ) - - input <- expected_output %>% filter(PARAMCD != "MAP") - - expect_dfs_equal( - derive_param_map(input, - by_vars = exprs(USUBJID, VISIT), - get_unit_expr = extract_unit(PARAM) - ), - expected_output, - keys = c("USUBJID", "PARAMCD", "VISIT") - ) -}) diff --git a/tests/testthat/test-derive_param_bmi.R b/tests/testthat/test-derive_param_bmi.R new file mode 100644 index 0000000000..ef02a10de0 --- /dev/null +++ b/tests/testthat/test-derive_param_bmi.R @@ -0,0 +1,209 @@ +# compute_bmi ---- + +## Test 1: BMI calculation - single height & weight values ---- +test_that("compute_bmi Test 1: BMI calculation - single height & weight values", { + # Expected values are taken from the Center of Disease Control and Prevention's + # (CDC) 'Adult BMI Calculator' at + # https://cdc.gov/healthyweight/assessing/bmi/adult_bmi/metric_bmi_calculator/bmi_calculator.html + expect_equal(round(compute_bmi(height = 180, weight = 75), 3L), 23.148) +}) + +## Test 2: compute_bmi BMI calculation - height & weight vectors ---- +test_that("compute_bmi Test 2: compute_bmi BMI calculation - height & weight vectors", { + expect_equal( + round(compute_bmi(height = c(180, 200), weight = c(75, 100)), 3L), + c(23.148, 25) + ) +}) + +## Test 3: BMI height & weight vectors - missing values ---- +test_that("compute_bmi Test 3: BMI height & weight vectors - missing values", { + expect_equal( + compute_bmi(height = c(NA, 200, 0), weight = c(75, NA, 75)), + c(NA_real_, NA_real_, NA_real_) + ) +}) + +# derive_param_bmi ---- + +## derive_param_bmi: Error checks ---- + +## Test 4: BMI parameter NOT added - wrong hgt unit ---- +test_that("derive_param_bmi Test 4: BMI parameter NOT added - wrong hgt unit", { + input <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, + # Wrong unit for HEIGHT should be cm + "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "m", 170, + "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 85, + ) + + expect_error( + derive_param_bmi(input, by_vars = exprs(USUBJID, VISIT), get_unit_expr = VSSTRESU), + class = "assert_unit" + ) +}) + +## Test 5: BMI parameter NOT added - wrong wgt unit ---- +test_that("derive_param_bmi Test 5: BMI parameter NOT added - wrong wgt unit", { + input <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, + "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, + # Wrong unit for WEIGHT should be kg + "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "g", 85, + ) + + expect_error( + derive_param_bmi(input, by_vars = exprs(USUBJID, VISIT), get_unit_expr = VSSTRESU), + class = "assert_unit" + ) +}) + +## Test 6: BMI parameter NOT added - multiple unit for wgt ---- +test_that("derive_param_bmi Test 6: BMI parameter NOT added - multiple unit for wgt", { + input <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, + "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, + # Multiple units for WEIGHT + "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 85, + "01-701-1016", "WEIGHT", "Weight (kg)", "BASELINE", "g", 8500, + ) + + expect_error( + derive_param_bmi(input, by_vars = exprs(USUBJID, VISIT), get_unit_expr = VSSTRESU), + class = "assert_unit" + ) +}) + +## Test 7: BMI parameter NOT added - PARAMCD not set ---- +test_that("derive_param_bmi Test 7: BMI parameter NOT added - PARAMCD not set", { + input <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, + "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, + "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 85, + ) + + expect_error( + derive_param_bmi( + input, + by_vars = exprs(USUBJID, VISIT), + set_values_to = exprs(PARAM = "Body Mass Index"), + get_unit_expr = VSSTRESU + ), + class = "assert_varval_list" + ) +}) + +## derive_param_bmi: No obs added ---- + +## Test 8: BMI parameter NOT added ---- +test_that("derive_param_bmi Test 8: BMI parameter NOT added", { + expected_output <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, + "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, + # WEIGHT set to NA - so BMI not calculated + "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", NA, + "01-701-1015", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 78, + # HEIGHT set to NA - so BMI not calculated + "01-701-1028", "HEIGHT", "Height (cm)", "BASELINE", "cm", NA, + "01-701-1028", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 90, + "01-701-1028", "HEIGHT", "Height (cm)", "MONTH 1", "cm", 88, + ) + + input <- expected_output + + expect_snapshot( + result <- derive_param_bmi( + input, + by_vars = exprs(USUBJID, VISIT), + get_unit_expr = VSSTRESU + ) + ) + + expect_dfs_equal( + result, + expected_output, + keys = c("USUBJID", "PARAMCD", "VISIT") + ) +}) + +## derive_param_bmi: Obs created ---- + +bmi <- function(hgt, wgt) { + wgt / (hgt / 100)^2 +} + +## Test 9: BMI parameter is correctly added ---- +test_that("derive_param_bmi Test 9: BMI parameter is correctly added", { + expected_output <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, + "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, + "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 75, + # New row added for BMI for SUBJID="01-701-1015" and VISIT="BASELINE" + # WEIGHT = 75 and HEIGHT = 170 + "01-701-1015", "BMI", NA, "BASELINE", NA, bmi(170, 75), + "01-701-1015", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 78, + "01-701-1028", "HEIGHT", "Height (cm)", "BASELINE", "cm", 185, + "01-701-1028", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 90, + # New row added for BMI for SUBJID="01-701-1028" and VISIT='BASELINE' + # WEIGHT = 90 and HEIGHT = 185 + "01-701-1028", "BMI", NA, "BASELINE", NA, bmi(185, 90), + "01-701-1028", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 88, + ) + + input <- expected_output %>% filter(PARAMCD != "BMI") + + expect_dfs_equal( + derive_param_bmi(input, by_vars = exprs(USUBJID, VISIT), get_unit_expr = VSSTRESU), + expected_output, + keys = c("USUBJID", "PARAMCD", "VISIT") + ) +}) + + +# Derive BMI where height is measured only once +## Test 10: Derive BMI where height is measured only once ---- +test_that("derive_param_bmi Test 10: Derive BMI where height is measured only once", { + input <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~AVALU, ~VISIT, + "01-701-1015", "HEIGHT", "Height (cm)", 147.0, "cm", "SCREENING", + "01-701-1015", "WEIGHT", "Weight (kg)", 54.0, "kg", "SCREENING", + "01-701-1015", "WEIGHT", "Weight (kg)", 54.4, "kg", "BASELINE", + "01-701-1015", "WEIGHT", "Weight (kg)", 53.1, "kg", "WEEK 2", + "01-701-1028", "HEIGHT", "Height (cm)", 163.0, "cm", "SCREENING", + "01-701-1028", "WEIGHT", "Weight (kg)", 78.5, "kg", "SCREENING", + "01-701-1028", "WEIGHT", "Weight (kg)", 80.3, "kg", "BASELINE", + "01-701-1028", "WEIGHT", "Weight (kg)", 80.7, "kg", "WEEK 2" + ) + + expected_output <- derive_param_computed( + input, + by_vars = exprs(USUBJID, VISIT), + parameters = "WEIGHT", + set_values_to = exprs( + AVAL = AVAL.WEIGHT / (AVAL.HEIGHT / 100)^2, + PARAMCD = "BMI", + PARAM = "Body Mass Index (kg/m^2)", + AVALU = "kg/m^2" + ), + constant_parameters = c("HEIGHT"), + constant_by_vars = exprs(USUBJID) + ) + + expect_dfs_equal( + expected_output, + derive_param_bmi( + input, + by_vars = exprs(USUBJID, VISIT), + weight_code = "WEIGHT", + height_code = "HEIGHT", + set_values_to = exprs( + PARAMCD = "BMI", + PARAM = "Body Mass Index (kg/m^2)", + AVALU = "kg/m^2" + ), + get_unit_expr = extract_unit(PARAM), + constant_by_vars = exprs(USUBJID) + ), + keys = c("USUBJID", "PARAMCD", "VISIT") + ) +}) diff --git a/tests/testthat/test-derive_param_bsa.R b/tests/testthat/test-derive_param_bsa.R new file mode 100644 index 0000000000..9905de45d9 --- /dev/null +++ b/tests/testthat/test-derive_param_bsa.R @@ -0,0 +1,619 @@ +# compute_bsa ---- + +## compute_bsa: Mosteller method ---- +# sqrt (Height x Weight / 3600) + +## Test 1: Mosteller method - single height & weight values ---- +test_that("compute_bsa Test 1: Mosteller method - single height & weight values", { + expect_equal( + round(compute_bsa(height = 170, weight = 75, method = "Mosteller"), 3L), + 1.882 + ) +}) + +## Test 2: Mosteller method - height & weight vectors ---- +test_that("compute_bsa Test 2: Mosteller method - height & weight vectors", { + expect_equal( + round(compute_bsa(height = c(170, 185), weight = c(75, 90), method = "Mosteller"), 3L), + c(1.882, 2.151) + ) +}) + +## Test 3: Mosteller method - height & weight vectors - missing values ---- +test_that("compute_bsa Test 3: Mosteller method - height & weight vectors - missing values", { + expect_equal( + compute_bsa(height = c(NA, 185), weight = c(75, NA), method = "Mosteller"), + c(NA_real_, NA_real_) + ) +}) + +## compute_bsa: DuBois-DuBois method ---- +# FORMULA : 0.007184 x (HGT)^0.725 x WGT^0.425 + +## Test 4: DuBois-DuBois method - single height & weight values ---- +test_that("compute_bsa Test 4: DuBois-DuBois method - single height & weight values", { + expect_equal( + round(compute_bsa(height = 170, weight = 75, method = "DuBois-DuBois"), 3L), + 1.864 + ) +}) + +## Test 5: DuBois-DuBois method - height & weight vectors ---- +test_that("compute_bsa Test 5: DuBois-DuBois method - height & weight vectors", { + expect_equal( + round(compute_bsa(height = c(170, 185), weight = c(75, 90), method = "DuBois-DuBois"), 3L), + c(1.864, 2.141) + ) +}) + +## Test 6: DuBois-DuBois method - hgt and wgt vectors - missing values ---- +test_that("compute_bsa Test 6: DuBois-DuBois method - hgt and wgt vectors - missing values", { + expect_equal( + compute_bsa(height = c(NA, 185), weight = c(75, NA), method = "DuBois-DuBois"), + c(NA_real_, NA_real_) + ) +}) + +## compute_bsa: Haycock method (Test 03.xx) ---- +# 0.024265 x HGT^0.3964 x WGT^0.5378 + +## Test 7: Haycock method - single height & weight values ---- +test_that("compute_bsa Test 7: Haycock method - single height & weight values", { + expect_equal( + round(compute_bsa(height = 170, weight = 75, method = "Haycock"), 3L), + 1.895 + ) +}) + +## Test 8: Haycock method - height & weight vectors ---- +test_that("compute_bsa Test 8: Haycock method - height & weight vectors", { + expect_equal( + round(compute_bsa(height = c(170, 185), weight = c(75, 90), method = "Haycock"), 3L), + c(1.895, 2.161) + ) +}) + +## Test 9: Haycock method - height & weight vectors - missing values ---- +test_that("compute_bsa Test 9: Haycock method - height & weight vectors - missing values", { + expect_equal( + compute_bsa(height = c(NA, 185), weight = c(75, NA), method = "Haycock"), + c(NA_real_, NA_real_) + ) +}) + +## compute_bsa: Gehan-George method ---- +# 0.0235 x HGT^0.42246 x WGT^0.51456 + +## Test 10: Gehan-George method - single height & weight values ---- +test_that("compute_bsa Test 10: Gehan-George method - single height & weight values", { + expect_equal( + round(compute_bsa(height = 170, weight = 75, method = "Gehan-George"), 3L), + 1.897 + ) +}) + +## Test 11: Gehan-George method - height & weight vectors ---- +test_that("compute_bsa Test 11: Gehan-George method - height & weight vectors", { + expect_equal( + round(compute_bsa(height = c(170, 185), weight = c(75, 90), method = "Gehan-George"), 3L), + c(1.897, 2.16) + ) +}) + +## Test 12: Gehan-George method - height & weight vectors - missing values ---- +test_that("compute_bsa Test 12: Gehan-George method - height & weight vectors - missing values", { + expect_equal( + compute_bsa(height = c(NA, 185), weight = c(75, NA), method = "Gehan-George"), + c(NA_real_, NA_real_) + ) +}) + +## compute_bsa: Boyd method ---- +# 0.0003207 x (HGT^0.3) x (1000 x WGT)^(0.7285 - (0.0188 x log10(1000 x WGT))) + +## Test 13: Boyd method - single height & weight values ---- +test_that("compute_bsa Test 13: Boyd method - single height & weight values", { + expect_equal( + round(compute_bsa(height = 170, weight = 75, method = "Boyd"), 3L), + 1.905 + ) +}) + +## Test 14: Boyd method - height & weight vectors ---- +test_that("compute_bsa Test 14: Boyd method - height & weight vectors", { + expect_equal( + round(compute_bsa(height = c(170, 185), weight = c(75, 90), method = "Boyd"), 3L), + c(1.905, 2.158) + ) +}) + +## Test 15: Boyd method - height & weight vectors - missing values ---- +test_that("compute_bsa Test 15: Boyd method - height & weight vectors - missing values", { + expect_equal( + compute_bsa(height = c(NA, 185), weight = c(75, NA), method = "Boyd"), + c(NA_real_, NA_real_) + ) +}) + +## compute_bsa: Fujimoto method ---- +# 0.008883 x HGT^0.663 x WGT^0.444 + +## Test 16: Fujimoto method - single height & weight values ---- +test_that("compute_bsa Test 16: Fujimoto method - single height & weight values", { + expect_equal( + round(compute_bsa(height = 170, weight = 75, method = "Fujimoto"), 3L), + 1.819 + ) +}) + +## Test 17: Fujimoto method - height & weight vectors ---- +test_that("compute_bsa Test 17: Fujimoto method - height & weight vectors", { + expect_equal( + round(compute_bsa(height = c(170, 185), weight = c(75, 90), method = "Fujimoto"), 3L), + c(1.819, 2.086) + ) +}) + +## Test 18: Fujimoto method - height & weight vectors - missing values ---- +test_that("compute_bsa Test 18: Fujimoto method - height & weight vectors - missing values", { + expect_equal( + compute_bsa(height = c(NA, 185), weight = c(75, NA), method = "Fujimoto"), + c(NA_real_, NA_real_) + ) +}) + +## compute_bsa: Takahira method ---- +# 0.007241 x HGT^0.725 x WGT^0.425 + +## Test 19: Takahira method - single height & weight values ---- +test_that("compute_bsa Test 19: Takahira method - single height & weight values", { + expect_equal( + round(compute_bsa(height = 170, weight = 75, method = "Takahira"), 3L), + 1.878 + ) +}) + +## Test 20: Takahira method - height & weight vectors ---- +test_that("compute_bsa Test 20: Takahira method - height & weight vectors", { + expect_equal( + round(compute_bsa(height = c(170, 185), weight = c(75, 90), method = "Takahira"), 3L), + c(1.878, 2.158) + ) +}) + +## Test 21: Takahira method - height & weight vectors - missing values ---- +test_that("compute_bsa Test 21: Takahira method - height & weight vectors - missing values", { + expect_equal( + compute_bsa(height = c(NA, 185), weight = c(75, NA), method = "Takahira"), + c(NA_real_, NA_real_) + ) +}) + +## compute_bsa: Check error messages ---- + +## Test 22: an error is issued if an invalid method is specified ---- +test_that("compute_bsa Test 22: an error is issued if an invalid method is specified", { + expect_error( + compute_bsa(height = c(170, 185), weight = c(75, 90), method = "unknown-method"), + class = "assert_character_scalar" + ) +}) + +# derive_param_bsa ---- + +## derive_param_bsa: Error checks ---- + +## Test 23: BSA parameter NOT added - wrong unit for height ---- +test_that("derive_param_bsa Test 23: BSA parameter NOT added - wrong unit for height", { + input <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, + # Wrong unit for HEIGHT should be cm + "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "m", 170, + "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 85, + ) + + expect_error( + derive_param_bsa( + input, + by_vars = exprs(USUBJID, VISIT), + method = "Mosteller", + get_unit_expr = VSSTRESU + ), + class = "assert_unit" + ) +}) + +## Test 24: BSA parameter NOT added - wrong unit for weight ---- +test_that("derive_param_bsa Test 24: BSA parameter NOT added - wrong unit for weight", { + input <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, + "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, + # Wrong unit for WEIGHT should be kg + "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "g", 85, + ) + + expect_error( + derive_param_bsa( + input, + by_vars = exprs(USUBJID, VISIT), + method = "Mosteller", + get_unit_expr = VSSTRESU + ), + class = "assert_unit" + ) +}) + +## Test 25: BSA parameter NOT added - multiple unit for weight ---- +test_that("derive_param_bsa Test 25: BSA parameter NOT added - multiple unit for weight", { + input <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, + "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, + # Multiple units for WEIGHT + "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 85, + "01-701-1016", "WEIGHT", "Weight (kg)", "BASELINE", "g", 8500, + ) + + expect_error( + derive_param_bsa( + input, + by_vars = exprs(USUBJID, VISIT), + method = "Mosteller", + get_unit_expr = VSSTRESU + ), + class = "assert_unit" + ) +}) + +## Test 26: BSA parameter NOT added - PARAMCD not set ---- +test_that("derive_param_bsa Test 26: BSA parameter NOT added - PARAMCD not set", { + input <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, + "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, + "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 85, + ) + + expect_error( + derive_param_bsa( + input, + by_vars = exprs(USUBJID, VISIT), + method = "Mosteller", + set_values_to = exprs(PARAM = "Body Surface Area"), + get_unit_expr = VSSTRESU + ), + class = "assert_varval_list" + ) +}) + +## derive_param_bsa: No obs added ---- + +## Test 27: BSA parameter NOT added ---- +test_that("derive_param_bsa Test 27: BSA parameter NOT added", { + expected_output <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, + "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, + # WEIGHT set to NA - so BSA not calculated + "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", NA, + "01-701-1015", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 78, + # HEIGHT set to NA - so BSA not calculated + "01-701-1028", "HEIGHT", "Height (cm)", "BASELINE", "cm", NA, + "01-701-1028", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 90, + "01-701-1028", "HEIGHT", "Height (cm)", "MONTH 1", "cm", 88, + ) + + input <- expected_output + + expect_snapshot( + result <- derive_param_bsa( + input, + by_vars = exprs(USUBJID, VISIT), + method = "Mosteller", + get_unit_expr = VSSTRESU + ) + ) + + expect_dfs_equal( + result, + expected_output, + keys = c("USUBJID", "PARAMCD", "VISIT") + ) +}) + +## derive_param_bsa: Obs created ---- + +mosteller <- function(hgt, wgt) { + sqrt(hgt * wgt / 3600) +} + +## Test 28: BSA parameter (Mosteller Method) is correctly added ---- +test_that("derive_param_bsa Test 28: BSA parameter (Mosteller Method) is correctly added", { + expected_output <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, + "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, + "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 75, + # New row added for BMI for SUBJID="01-701-1015" and VISIT="BASELINE" + # WEIGHT = 75 and HEIGHT = 170 + "01-701-1015", "BSA", NA, "BASELINE", NA, mosteller(170, 75), + "01-701-1015", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 78, + "01-701-1028", "HEIGHT", "Height (cm)", "BASELINE", "cm", 185, + "01-701-1028", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 90, + # New row added for BMI for SUBJID="01-701-1028" and VISIT='BASELINE' + # WEIGHT = 90 and HEIGHT = 185 + "01-701-1028", "BSA", NA, "BASELINE", NA, mosteller(185, 90), + "01-701-1028", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 88, + ) + + input <- expected_output %>% filter(PARAMCD != "BSA") + + expect_dfs_equal( + derive_param_bsa(input, + by_vars = exprs(USUBJID, VISIT), + method = "Mosteller", + get_unit_expr = VSSTRESU + ), + expected_output, + keys = c("USUBJID", "PARAMCD", "VISIT") + ) +}) + +dubois <- function(hgt, wgt) { + 0.007184 * hgt^0.725 * wgt^0.425 +} + +## Test 29: BSA parameter (DuBois-DuBois method) is correctly added ---- +test_that("derive_param_bsa Test 29: BSA parameter (DuBois-DuBois method) is correctly added", { + expected_output <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, + "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, + "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 75, + # New row added for BMI for SUBJID="01-701-1015" and VISIT="BASELINE" + # WEIGHT = 75 and HEIGHT = 170 + "01-701-1015", "BSA", NA, "BASELINE", NA, dubois(170, 75), + "01-701-1015", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 78, + "01-701-1028", "HEIGHT", "Height (cm)", "BASELINE", "cm", 185, + "01-701-1028", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 90, + # New row added for BMI for SUBJID="01-701-1028" and VISIT='BASELINE' + # WEIGHT = 90 and HEIGHT = 185 + "01-701-1028", "BSA", NA, "BASELINE", NA, dubois(185, 90), + "01-701-1028", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 88, + ) + + input <- expected_output %>% filter(PARAMCD != "BSA") + + expect_dfs_equal( + derive_param_bsa( + input, + by_vars = exprs(USUBJID, VISIT), + method = "DuBois-DuBois", + get_unit_expr = VSSTRESU + ), + expected_output, + keys = c("USUBJID", "PARAMCD", "VISIT") + ) +}) + +haycock <- function(hgt, wgt) { + 0.024265 * hgt^0.3964 * wgt^0.5378 +} + +## Test 30: BSA parameter (Haycock method) is correctly added ---- +test_that("derive_param_bsa Test 30: BSA parameter (Haycock method) is correctly added", { + expected_output <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, + "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, + "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 75, + # New row added for BMI for SUBJID="01-701-1015" and VISIT="BASELINE" + # WEIGHT = 75 and HEIGHT = 170 + "01-701-1015", "BSA", NA, "BASELINE", NA, haycock(170, 75), + "01-701-1015", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 78, + "01-701-1028", "HEIGHT", "Height (cm)", "BASELINE", "cm", 185, + "01-701-1028", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 90, + # New row added for BMI for SUBJID="01-701-1028" and VISIT='BASELINE' + # WEIGHT = 90 and HEIGHT = 185 + "01-701-1028", "BSA", NA, "BASELINE", NA, haycock(185, 90), + "01-701-1028", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 88, + ) + + input <- expected_output %>% filter(PARAMCD != "BSA") + + expect_dfs_equal( + derive_param_bsa(input, + by_vars = exprs(USUBJID, VISIT), + method = "Haycock", + get_unit_expr = VSSTRESU + ), + expected_output, + keys = c("USUBJID", "PARAMCD", "VISIT") + ) +}) + +gehan <- function(hgt, wgt) { + 0.0235 * hgt^0.42246 * wgt^0.51456 +} + +## Test 31: BSA parameter (Gehan-George method) is correctly added ---- +test_that("derive_param_bsa Test 31: BSA parameter (Gehan-George method) is correctly added", { + expected_output <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, + "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, + "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 75, + # New row added for BMI for SUBJID="01-701-1015" and VISIT="BASELINE" + # WEIGHT = 75 and HEIGHT = 170 + "01-701-1015", "BSA", NA, "BASELINE", NA, gehan(170, 75), + "01-701-1015", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 78, + "01-701-1028", "HEIGHT", "Height (cm)", "BASELINE", "cm", 185, + "01-701-1028", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 90, + # New row added for BMI for SUBJID="01-701-1028" and VISIT='BASELINE' + # WEIGHT = 90 and HEIGHT = 185 + "01-701-1028", "BSA", NA, "BASELINE", NA, gehan(185, 90), + "01-701-1028", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 88, + ) + + input <- expected_output %>% filter(PARAMCD != "BSA") + + expect_dfs_equal( + derive_param_bsa( + input, + by_vars = exprs(USUBJID, VISIT), + method = "Gehan-George", + get_unit_expr = VSSTRESU + ), + expected_output, + keys = c("USUBJID", "PARAMCD", "VISIT") + ) +}) + +boyd <- function(hgt, wgt) { + 0.0003207 * (hgt^0.3) * (1000 * wgt)^(0.7285 - (0.0188 * log10(1000 * wgt))) # nolint +} + +## Test 32: BSA parameter (Boyd method) is correctly added ---- +test_that("derive_param_bsa Test 32: BSA parameter (Boyd method) is correctly added", { + expected_output <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, + "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, + "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 75, + # New row added for BMI for SUBJID="01-701-1015" and VISIT="BASELINE" + # WEIGHT = 75 and HEIGHT = 170 + "01-701-1015", "BSA", NA, "BASELINE", NA, boyd(170, 75), + "01-701-1015", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 78, + "01-701-1028", "HEIGHT", "Height (cm)", "BASELINE", "cm", 185, + "01-701-1028", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 90, + # New row added for BMI for SUBJID="01-701-1028" and VISIT='BASELINE' + # WEIGHT = 90 and HEIGHT = 185 + "01-701-1028", "BSA", NA, "BASELINE", NA, boyd(185, 90), + "01-701-1028", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 88, + ) + + input <- expected_output %>% filter(PARAMCD != "BSA") + + expect_dfs_equal( + derive_param_bsa(input, + by_vars = exprs(USUBJID, VISIT), + method = "Boyd", + get_unit_expr = VSSTRESU + ), + expected_output, + keys = c("USUBJID", "PARAMCD", "VISIT") + ) +}) + +fujimoto <- function(hgt, wgt) { + 0.008883 * hgt^0.663 * wgt^0.444 +} + +## Test 33: BSA parameter (Fujimoto method) is correctly added ---- +test_that("derive_param_bsa Test 33: BSA parameter (Fujimoto method) is correctly added", { + expected_output <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, + "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, + "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 75, + # New row added for BMI for SUBJID="01-701-1015" and VISIT="BASELINE" + # WEIGHT = 75 and HEIGHT = 170 + "01-701-1015", "BSA", NA, "BASELINE", NA, fujimoto(170, 75), + "01-701-1015", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 78, + "01-701-1028", "HEIGHT", "Height (cm)", "BASELINE", "cm", 185, + "01-701-1028", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 90, + # New row added for BMI for SUBJID="01-701-1028" and VISIT='BASELINE' + # WEIGHT = 90 and HEIGHT = 185 + "01-701-1028", "BSA", NA, "BASELINE", NA, fujimoto(185, 90), + "01-701-1028", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 88, + ) + + input <- expected_output %>% filter(PARAMCD != "BSA") + + expect_dfs_equal( + derive_param_bsa( + input, + by_vars = exprs(USUBJID, VISIT), + method = "Fujimoto", + get_unit_expr = VSSTRESU + ), + expected_output, + keys = c("USUBJID", "PARAMCD", "VISIT") + ) +}) + +takahira <- function(hgt, wgt) { + 0.007241 * hgt^0.725 * wgt^0.425 +} + +## Test 34: BSA parameter (Takahira method) is correctly added ---- +test_that("derive_param_bsa Test 34: BSA parameter (Takahira method) is correctly added", { + expected_output <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~VSSTRESU, ~AVAL, + "01-701-1015", "HEIGHT", "Height (cm)", "BASELINE", "cm", 170, + "01-701-1015", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 75, + # New row added for BMI for SUBJID="01-701-1015" and VISIT="BASELINE" + # WEIGHT = 75 and HEIGHT = 170 + "01-701-1015", "BSA", NA, "BASELINE", NA, takahira(170, 75), + "01-701-1015", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 78, + "01-701-1028", "HEIGHT", "Height (cm)", "BASELINE", "cm", 185, + "01-701-1028", "WEIGHT", "Weight (kg)", "BASELINE", "kg", 90, + # New row added for BMI for SUBJID="01-701-1028" and VISIT='BASELINE' + # WEIGHT = 90 and HEIGHT = 185 + "01-701-1028", "BSA", NA, "BASELINE", NA, takahira(185, 90), + "01-701-1028", "WEIGHT", "Weight (kg)", "MONTH 1", "kg", 88, + ) + + input <- expected_output %>% filter(PARAMCD != "BSA") + + expect_dfs_equal( + derive_param_bsa( + input, + by_vars = exprs(USUBJID, VISIT), + method = "Takahira", + get_unit_expr = VSSTRESU + ), + expected_output, + keys = c("USUBJID", "PARAMCD", "VISIT") + ) +}) + +## Test 35: Derive BSA where height is measured only once ---- +test_that("derive_param_bsa Test 35: Derive BSA where height is measured only once", { + input <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~AVALU, ~VISIT, + "01-701-1015", "HEIGHT", "Height (cm)", 147.0, "cm", "SCREENING", + "01-701-1015", "WEIGHT", "Weight (kg)", 54.0, "kg", "SCREENING", + "01-701-1015", "WEIGHT", "Weight (kg)", 54.4, "kg", "BASELINE", + "01-701-1015", "WEIGHT", "Weight (kg)", 53.1, "kg", "WEEK 2", + "01-701-1028", "HEIGHT", "Height (cm)", 163.0, "cm", "SCREENING", + "01-701-1028", "WEIGHT", "Weight (kg)", 78.5, "kg", "SCREENING", + "01-701-1028", "WEIGHT", "Weight (kg)", 80.3, "kg", "BASELINE", + "01-701-1028", "WEIGHT", "Weight (kg)", 80.7, "kg", "WEEK 2" + ) + + expected_output <- derive_param_computed( + input, + by_vars = exprs(USUBJID, VISIT), + parameters = "WEIGHT", + set_values_to = exprs( + AVAL = compute_bsa( + height = AVAL.HEIGHT, weight = AVAL.WEIGHT, + method = "Mosteller" + ), + PARAMCD = "BSA", + PARAM = "Body Surface Area (m^2)", + AVALU = "m^2" + ), + constant_parameters = c("HEIGHT"), + constant_by_vars = exprs(USUBJID) + ) + + expect_dfs_equal( + expected_output, + derive_param_bsa( + input, + by_vars = exprs(USUBJID, VISIT), + method = "Mosteller", + set_values_to = exprs( + PARAMCD = "BSA", + PARAM = "Body Surface Area (m^2)", + AVALU = "m^2" + ), + get_unit_expr = extract_unit(PARAM), + constant_by_vars = exprs(USUBJID) + ), + keys = c("USUBJID", "PARAMCD", "VISIT") + ) +}) diff --git a/tests/testthat/test-derive_param_map.R b/tests/testthat/test-derive_param_map.R new file mode 100644 index 0000000000..79760ba122 --- /dev/null +++ b/tests/testthat/test-derive_param_map.R @@ -0,0 +1,233 @@ +# compute_map ---- + +## compute_map: DBP & SBP ---- +# ((2 x DBP) + SBP) / 3 + +## Test 1: MAP based on diastolic & systolic BP - single values ---- +test_that("compute_map Test 1: MAP based on diastolic & systolic BP - single values", { + expect_equal(round(compute_map(diabp = 51, sysbp = 121), 3L), 74.333) +}) + +## Test 2: MAP based on diastolic & systolic BP - vectors ---- +test_that("compute_map Test 2: MAP based on diastolic & systolic BP - vectors", { + expect_equal( + round(compute_map(diabp = c(51, 61), sysbp = c(121, 141)), 3L), c(74.333, 87.667) + ) +}) + +## Test 3: MAP based on diastolic & systolic BP with missing values ---- +test_that("compute_map Test 3: MAP based on diastolic & systolic BP with missing values", { + expect_equal( + compute_map(diabp = c(NA, 61), sysbp = c(121, NA)), c(NA_real_, NA_real_) + ) +}) + +## compute_map: DBP, SBP & HR ---- +# DBP + 0.01 x exp(4.14 - 40.74 / PULSE) x (SBP - DBP) + +## Test 4: MAP based on DBP & SBP & heart rate - single values ---- +test_that("compute_map Test 4: MAP based on DBP & SBP & heart rate - single values", { + expect_equal( + round(compute_map(diabp = 51, sysbp = 121, hr = 59), 3L), 73.039 + ) +}) + +## Test 5: MAP based on diastolic, systolic BP & heart rate - vectors ---- +test_that("compute_map Test 5: MAP based on diastolic, systolic BP & heart rate - vectors", { + expect_equal( + round(compute_map(diabp = c(51, 91), sysbp = c(121, 101), hr = c(59, 62)), 3L), + c(73.039, 94.255) + ) +}) + +## Test 6: MAP based on DBP, SBP & heart rate - with missing values ---- +test_that("compute_map Test 6: MAP based on DBP, SBP & heart rate - with missing values", { + expect_equal( + compute_map(diabp = c(NA, 61, 51), sysbp = c(121, NA, 121), hr = c(59, 62, NA)), + c(NA_real_, NA_real_, NA_real_) + ) +}) + +# derive_param_map ---- + +## derive_param_map: Error checks ---- + +## Test 7: MAP parameter NOT added - wrong DIABP unit ---- +test_that("derive_param_map Test 7: MAP parameter NOT added - wrong DIABP unit", { + input <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~VISIT, + "01-701-1015", "DIABP", "Diastolic Blood Pressure (mHg)", 51, "BASELINE", + "01-701-1015", "SYSBP", "Systolic Blood Pressure (mmHg)", 121, "BASELINE", + ) + + expect_error( + derive_param_map( + input, + by_vars = exprs(USUBJID, VISIT), + get_unit_expr = extract_unit(PARAM) + ), + class = "assert_unit" + ) +}) + +## Test 8: MAP parameter NOT added - wrong SYSBP unit ---- +test_that("derive_param_map Test 8: MAP parameter NOT added - wrong SYSBP unit", { + input <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~VISIT, + "01-701-1015", "DIABP", "Diastolic Blood Pressure (mmHg)", 51, "BASELINE", + "01-701-1015", "SYSBP", "Systolic Blood Pressure (mHg)", 121, "BASELINE", + ) + + expect_error( + derive_param_map( + input, + by_vars = exprs(USUBJID, VISIT), + get_unit_expr = extract_unit(PARAM) + ), + class = "assert_unit" + ) +}) + +## Test 9: MAP parameter NOT added - wrong PULSE unit ---- +test_that("derive_param_map Test 9: MAP parameter NOT added - wrong PULSE unit", { + input <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~VISIT, + "01-701-1015", "DIABP", "Diastolic Blood Pressure (mmHg)", 51, "BASELINE", + "01-701-1015", "SYSBP", "Systolic Blood Pressure (mmHg)", 121, "BASELINE", + "01-701-1015", "PULSE", "Pulse (beats/m)", 65, "BASELINE", + ) + + expect_error( + derive_param_map( + input, + by_vars = exprs(USUBJID, VISIT), + hr_code = "PULSE", + get_unit_expr = extract_unit(PARAM) + ), + class = "assert_unit" + ) +}) + +## Test 10: MAP parameter NOT added - PARAMCD not set ---- +test_that("derive_param_map Test 10: MAP parameter NOT added - PARAMCD not set", { + input <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~VISIT, + "01-701-1015", "DIABP", "Diastolic Blood Pressure (mmHg)", 51, "BASELINE", + "01-701-1015", "SYSBP", "Systolic Blood Pressure (mmHg)", 121, "BASELINE", + ) + + expect_error( + derive_param_map( + input, + by_vars = exprs(USUBJID, VISIT), + set_values_to = exprs(PARAM = "Mean Arterial Pressure"), + get_unit_expr = extract_unit(PARAM) + ), + class = "assert_varval_list" + ) +}) + +## derive_param_map: No obs added ---- + +## Test 11: MAP parameter NOT added ---- +test_that("derive_param_map Test 11: MAP parameter NOT added", { + expected_output <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~VISIT, + "01-701-1015", "DIABP", "Diastolic Blood Pressure (mmHg)", NA, "BASELINE", + "01-701-1015", "DIABP", "Diastolic Blood Pressure (mmHg)", 50, "WEEK 2", + "01-701-1015", "DIABP", "Diastolic Blood Pressure (mmHg)", 55, "WEEK 4", + "01-701-1015", "SYSBP", "Systolic Blood Pressure (mmHg)", 121, "BASELINE", + "01-701-1015", "SYSBP", "Systolic Blood Pressure (mmHg)", NA, "WEEK 2", + "01-701-1015", "SYSBP", "Systolic Blood Pressure (mmHg)", 127, "WEEK 4", + "01-701-1015", "PULSE", "Pulse (beats/min)", 65, "BASELINE", + "01-701-1015", "PULSE", "Pulse (beats/min)", 68, "WEEK 2", + "01-701-1015", "PULSE", "Pulse (beats/min)", NA, "WEEK 4", + ) + + input <- expected_output + + expect_snapshot( + result <- derive_param_map( + input, + by_vars = exprs(USUBJID, VISIT), + hr_code = "PULSE", + get_unit_expr = extract_unit(PARAM) + ) + ) + + expect_dfs_equal( + result, + expected_output, + keys = c("USUBJID", "PARAMCD", "VISIT") + ) +}) + +## derive_param_map: Obs created ---- + +maphr <- function(sbp, dbp, hr) { + dbp + 0.01 * exp(4.14 - 40.74 / hr) * (sbp - dbp) +} + +## Test 12: MAP parameter (DBP/SBP/PULSE) is correctly added ---- +test_that("derive_param_map Test 12: MAP parameter (DBP/SBP/PULSE) is correctly added", { + expected_output <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~AVAL, + "01-701-1015", "PULSE", "Pulse (beats/min)", "BASELINE", 59, + "01-701-1015", "DIABP", "Diastolic Blood Pressure (mmHg)", "BASELINE", 51, + "01-701-1015", "SYSBP", "Systolic Blood Pressure (mmHg)", "BASELINE", 121, + # New row added for MAP for SUBJID="01-701-1015" and VISIT="BASELINE" + # PULSE = 59 DIABP = 51 and SYSBP = 121 + "01-701-1015", "MAP", NA, "BASELINE", maphr(121, 51, 59), + "01-701-1028", "PULSE", "Pulse (beats/min)", "WEEK 2", 61, + "01-701-1028", "DIABP", "Diastolic Blood Pressure (mmHg)", "WEEK 2", 50, + "01-701-1028", "SYSBP", "Systolic Blood Pressure (mmHg)", "WEEK 2", 125, + # New row added for MAP for SUBJID="01-701-1028" and VISIT="WEEK 2" + # PULSE = 61 DIABP = 50 and SYSBP = 125 + "01-701-1028", "MAP", NA, "WEEK 2", maphr(125, 50, 61), + ) + + input <- expected_output %>% filter(PARAMCD != "MAP") + + expect_dfs_equal( + derive_param_map( + input, + by_vars = exprs(USUBJID, VISIT), + hr_code = "PULSE", + get_unit_expr = extract_unit(PARAM) + ), + expected_output, + keys = c("USUBJID", "PARAMCD", "VISIT") + ) +}) + +map <- function(sbp, dbp) { + (2 * dbp + sbp) / 3 +} + +## Test 13: MAP parameter (DBP/SBP) is correctly added ---- +test_that("derive_param_map Test 13: MAP parameter (DBP/SBP) is correctly added", { + expected_output <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~VISIT, ~AVAL, + "01-701-1015", "DIABP", "Diastolic Blood Pressure (mmHg)", "BASELINE", 51, + "01-701-1015", "SYSBP", "Systolic Blood Pressure (mmHg)", "BASELINE", 121, + # New row added for MAP for SUBJID="01-701-1015" and VISIT="BASELINE" + # DIABP = 51 and SYSBP = 121 + "01-701-1015", "MAP", NA, "BASELINE", map(121, 51), + "01-701-1028", "DIABP", "Diastolic Blood Pressure (mmHg)", "WEEK 2", 50, + "01-701-1028", "SYSBP", "Systolic Blood Pressure (mmHg)", "WEEK 2", 125, + # New row added for MAP for SUBJID="01-701-1028" and VISIT="WEEK 2" + # DIABP = 50 and SYSBP = 125 + "01-701-1028", "MAP", NA, "WEEK 2", map(125, 50), + ) + + input <- expected_output %>% filter(PARAMCD != "MAP") + + expect_dfs_equal( + derive_param_map(input, + by_vars = exprs(USUBJID, VISIT), + get_unit_expr = extract_unit(PARAM) + ), + expected_output, + keys = c("USUBJID", "PARAMCD", "VISIT") + ) +}) diff --git a/tests/testthat/test-derive_adeg_params.R b/tests/testthat/test-derive_param_qtc.R similarity index 64% rename from tests/testthat/test-derive_adeg_params.R rename to tests/testthat/test-derive_param_qtc.R index 8f013e3fdd..1f58510145 100644 --- a/tests/testthat/test-derive_adeg_params.R +++ b/tests/testthat/test-derive_param_qtc.R @@ -124,74 +124,3 @@ test_that("derive_param_qtc Test 4: Message if no new records", { keys = c("USUBJID", "PARAMCD", "VISIT") ) }) - -# derive_param_rr ---- - -## Test 5: new observations are derived correctly ---- -test_that("derive_param_rr Test 5: new observations are derived correctly", { - input <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~AVALU, ~VISIT, - "01-701-1015", "HR", "Heart Rate", 70.14, "beats/min", "BASELINE", - "01-701-1015", "HR", "Heart Rate", 62.66, "beats/min", "WEEK 1", - "01-701-1015", "RR", "RR Duration", 710, "ms", "WEEK 2", - "01-701-1028", "HR", "Heart Rate", 85.45, "beats/min", "BASELINE", - "01-701-1028", "HR", "Heart Rate", 56.54, "beats/min", "WEEK 3", - "01-701-1028", "RR", "RR Duration", 842, "ms", "WEEK 2", - ) - - new_obs <- input %>% - filter(PARAMCD == "HR") %>% - select(USUBJID, VISIT, AVAL) %>% - mutate( - AVAL = 60000 / AVAL, - PARAMCD = "RRR", - PARAM = "RR Duration Rederived (ms)", - AVALU = "ms" - ) - expected_output <- bind_rows(input, new_obs) - - expect_dfs_equal( - derive_param_rr( - input, - by_vars = exprs(USUBJID, VISIT), - set_values_to = exprs( - PARAMCD = "RRR", - PARAM = "RR Duration Rederived (ms)", - AVALU = "ms" - ), - get_unit_expr = AVALU - ), - expected_output, - keys = c("USUBJID", "PARAMCD", "VISIT") - ) -}) - -## Test 6: Message if no new records ---- -test_that("derive_param_rr Test 6: Message if no new records", { - input <- tibble::tribble( - ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~AVALU, ~VISIT, - "01-701-1015", "HR", "Heart Rate", NA, "beats/min", "BASELINE", - "01-701-1015", "HR", "Heart Rate", NA, "beats/min", "WEEK 1", - "01-701-1015", "RR", "RR Duration", 710, "ms", "WEEK 2" - ) - - - expect_snapshot( - actual <- derive_param_rr( - input, - by_vars = exprs(USUBJID, VISIT), - set_values_to = exprs( - PARAMCD = "RRR", - PARAM = "RR Duration Rederived (ms)", - AVALU = "ms" - ), - get_unit_expr = AVALU - ) - ) - - expect_dfs_equal( - base = input, - compare = actual, - keys = c("USUBJID", "PARAMCD", "VISIT") - ) -}) diff --git a/tests/testthat/test-derive_param_rr.R b/tests/testthat/test-derive_param_rr.R new file mode 100644 index 0000000000..78ad4dd9d7 --- /dev/null +++ b/tests/testthat/test-derive_param_rr.R @@ -0,0 +1,70 @@ +# derive_param_rr ---- + +## Test 1: new observations are derived correctly ---- +test_that("derive_param_rr Test 1: new observations are derived correctly", { + input <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~AVALU, ~VISIT, + "01-701-1015", "HR", "Heart Rate", 70.14, "beats/min", "BASELINE", + "01-701-1015", "HR", "Heart Rate", 62.66, "beats/min", "WEEK 1", + "01-701-1015", "RR", "RR Duration", 710, "ms", "WEEK 2", + "01-701-1028", "HR", "Heart Rate", 85.45, "beats/min", "BASELINE", + "01-701-1028", "HR", "Heart Rate", 56.54, "beats/min", "WEEK 3", + "01-701-1028", "RR", "RR Duration", 842, "ms", "WEEK 2", + ) + + new_obs <- input %>% + filter(PARAMCD == "HR") %>% + select(USUBJID, VISIT, AVAL) %>% + mutate( + AVAL = 60000 / AVAL, + PARAMCD = "RRR", + PARAM = "RR Duration Rederived (ms)", + AVALU = "ms" + ) + expected_output <- bind_rows(input, new_obs) + + expect_dfs_equal( + derive_param_rr( + input, + by_vars = exprs(USUBJID, VISIT), + set_values_to = exprs( + PARAMCD = "RRR", + PARAM = "RR Duration Rederived (ms)", + AVALU = "ms" + ), + get_unit_expr = AVALU + ), + expected_output, + keys = c("USUBJID", "PARAMCD", "VISIT") + ) +}) + +## Test 2: Message if no new records ---- +test_that("derive_param_rr Test 2: Message if no new records", { + input <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~AVALU, ~VISIT, + "01-701-1015", "HR", "Heart Rate", NA, "beats/min", "BASELINE", + "01-701-1015", "HR", "Heart Rate", NA, "beats/min", "WEEK 1", + "01-701-1015", "RR", "RR Duration", 710, "ms", "WEEK 2" + ) + + + expect_snapshot( + actual <- derive_param_rr( + input, + by_vars = exprs(USUBJID, VISIT), + set_values_to = exprs( + PARAMCD = "RRR", + PARAM = "RR Duration Rederived (ms)", + AVALU = "ms" + ), + get_unit_expr = AVALU + ) + ) + + expect_dfs_equal( + base = input, + compare = actual, + keys = c("USUBJID", "PARAMCD", "VISIT") + ) +})