-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Create Surv_CDISC.R * updates * doc update * Re-build README.Rmd * Update Surv_CDISC.R * Re-build README.Rmd * Update Surv_CDISC.R * Re-build README.Rmd * doc updates * Re-build README.Rmd * Update NAMESPACE * merge conflict fix * Re-build README.Rmd * updates * Re-build README.Rmd * Update test-Surv_CDISC.R * Re-build README.Rmd * readme * doc updates from review * doc updates * Update test-Surv_CDISC.R * Update testing: - consistent with CDISC philosophy - check the actual requirement - remove req T2.5 as this is not a requirement of our function, but something tested in the backend of survival * removed requirement 2.3 in TOC * change function name * Update testing Included CNSR info in estimate_KM to ensure user will restrict to 0/1 * re-documenting Co-authored-by: GitHub Actions <[email protected]> Co-authored-by: Mark Baillie <[email protected]> Co-authored-by: shaesen2 <[email protected]>
- Loading branch information
1 parent
2bd9b15
commit d6a3c6c
Showing
8 changed files
with
253 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
#' Create a Survival Object from CDISC Data | ||
#' | ||
#' @description | ||
#' `r lifecycle::badge('experimental')` | ||
#' | ||
#' The aim of `Surv_CNSR()` is to map the inconsistency in convention between | ||
#' the [survival](https://cran.r-project.org/package=survival) package and | ||
#' [CDISC ADaM ADTTE data model](https://www.cdisc.org/standards/foundational/adam/adam-basic-data-structure-bds-time-event-tte-analyses-v1-0). | ||
#' | ||
#' The function creates a survival object (e.g. `survival::Surv()`) that | ||
#' uses CDISC ADaM ADTTE coding conventions and converts the arguments to the | ||
#' status/event variable convention used in the | ||
#' [survival](https://cran.r-project.org/package=survival) package. | ||
#' | ||
#' The `AVAL` and `CNSR` arguments are passed to | ||
#' `survival::Surv(time = AVAL, event = 1 - CNSR, type = "right", origin = 0)`. | ||
#' | ||
#' @section Details: | ||
#' | ||
#' The `Surv_CNSR()` function creates a survival object utilizing the | ||
#' expected data structure in the CDISC ADaM ADTTE data model, | ||
#' mapping the CDISC ADaM ADTTE coding conventions with the expected | ||
#' status/event variable convention used in the survival package---specifically, | ||
#' the coding convention used for the status/event indicator. | ||
#' The survival package expects the status/event indicator in the | ||
#' following format: `0=alive`, `1=dead`. Other accepted choices are | ||
#' `TRUE`/`FALSE` (`TRUE = death`) or `1`/`2` (`2=death`). | ||
#' A final but risky option is to omit the indicator variable, in which case | ||
#' all subjects are assumed to have an event. | ||
#' | ||
#' The CDISC ADaM ADTTE data model adopts a different coding convention for | ||
#' the event/status indicator. Using this convention, the event/status variable | ||
#' is named `'CNSR'` and uses the following coding: `censor = 1`, `status/event = 0`. | ||
#' | ||
#' @param AVAL The follow-up time. The follow-up time is assumed to originate from zero. | ||
#' When no argument is passed, the default value is a column/vector named `AVAL`. | ||
#' @param CNSR The censoring indicator where `1=censored` and `0=death/event`. | ||
#' When no argument is passed, the default value is a column/vector named `CNSR`. | ||
#' | ||
#' @return Object of class 'Surv' | ||
#' @seealso [`survival::Surv()`], [`estimate_KM()`] | ||
#' @export | ||
#' | ||
#' @examples | ||
#' # Use the `Surv_CNSR()` function with visR functions | ||
#' adtte %>% | ||
#' visR:: estimate_KM(formula = visR::Surv_CNSR() ~ SEX) | ||
#' | ||
#' # Use the `Surv_CNSR()` function with functions from other packages as well | ||
#' survival::survfit(visR::Surv_CNSR() ~ SEX, data = adtte) | ||
#' survival::survreg(visR::Surv_CNSR() ~ SEX + AGE, data = adtte) %>% | ||
#' broom::tidy() | ||
|
||
Surv_CNSR <- function(AVAL, CNSR) { | ||
# set default values if not passed by user ----------------------------------- | ||
if (missing(AVAL) && exists("AVAL", envir = rlang::caller_env())) | ||
AVAL <- get("AVAL", envir = rlang::caller_env()) | ||
else if (missing(AVAL)) | ||
stop("Default 'AVAL' value not found. Specify argument in `Surv_CNSR(AVAL=)`.") | ||
if (missing(CNSR) && exists("CNSR", envir = rlang::caller_env())) | ||
CNSR <- get("CNSR", envir = rlang::caller_env()) | ||
else if (missing(CNSR)) | ||
stop("Default 'CNSR' value not found. Specify argument in `Surv_CNSR(CNSR=)`.") | ||
|
||
# checking inputs ------------------------------------------------------------ | ||
if (!is.numeric(AVAL) || !is.numeric(CNSR)) | ||
stop("Expecting arguments 'AVAL' and 'CNSR' to be numeric.") | ||
|
||
if (stats::na.omit(CNSR) %>% setdiff(c(0, 1)) %>% {!rlang::is_empty(.)}) | ||
stop("Expecting 'CNSR' argument to be binary with values `0/1`.") | ||
|
||
if (any(AVAL < 0)) | ||
warning("Values of 'AVAL' are less than zero, which is likely a data error.") | ||
|
||
# pass args to `survival::Surv()` -------------------------------------------- | ||
survival::Surv(time = AVAL, event = 1 - CNSR, type = "right", origin = 0) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,6 +26,7 @@ RGBA | |
RRGGBB | ||
RRGGBBAA | ||
SDTM | ||
Surv | ||
Tarone | ||
UCL | ||
UX | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47,6 +47,7 @@ reference: | |
- get_pvalue | ||
- get_quantile | ||
- get_COX_HR | ||
- Surv_CNSR | ||
|
||
- title: Data Summary | ||
- contents: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,104 @@ | ||
#' @title Specifications test-Surv_CNSR.R | ||
#' @section Last updated by: Steven Haesendonckx | ||
#' @section Last update date: 15JUN2022 | ||
#' | ||
#' @section List of tested specifications | ||
#' T1. The function returns a Surv object | ||
#' T1.1 The function returns a Surv object | ||
#' T1.2 The function is compatible with the survival package | ||
#' T1.3 The results of the estimation match between Surv_CNSR and Surv with inverted censoring | ||
#' T2. The function relies on the presence of two numeric variables, specified through AVAL and CNSR, to be present in the envrionment in which they are called | ||
#' T2.1 An error when column name specified through AVAL is not present in the environment | ||
#' T2.2 A warning when the column specified through AVAL has negative values | ||
#' T2.3 A warning when the column specified through AVAL has negative values | ||
#' T2.4 An error when the column name specified through CNSR is not present in the environment | ||
#' T2.5 An error when the column name specified through CNSR in the environment is not numeric | ||
|
||
# Requirement T1 ---------------------------------------------------------- | ||
|
||
testthat::context("Surv_CNSR - T1. The function returns a Surv object") | ||
|
||
testthat::test_that("T1.1 The function returns a Surv object", { | ||
testthat::expect_error(surv1 <- with(adtte, visR::Surv_CNSR()), NA) | ||
testthat::expect_error(surv2 <- with(adtte, visR::Surv_CNSR()), NA) | ||
testthat::expect_true(inherits(surv1, "Surv")) | ||
testthat::expect_true(inherits(surv2, "Surv")) | ||
}) | ||
|
||
testthat::test_that("T1.2 The function is compatible with the survival package", { | ||
testthat::expect_error(survival::survfit(visR::Surv_CNSR() ~ 1, data = adtte), NA) | ||
testthat::expect_error(survival::survfit(visR::Surv_CNSR() ~ SEX, data = adtte), NA) | ||
|
||
testthat::expect_error(adtte %>% visR::estimate_KM(formula = Surv_CNSR() ~ 1), NA) | ||
testthat::expect_error(adtte %>% visR::estimate_KM(formula = Surv_CNSR() ~ SEX), NA) | ||
|
||
testthat::expect_error(survival::survfit(visR::Surv_CNSR(AVAL, CNSR) ~ 1, data = adtte), NA) | ||
testthat::expect_error(survival::survfit(visR::Surv_CNSR(AVAL, CNSR) ~ SEX, data = adtte), NA) | ||
|
||
# WHEN THIS TEST FAILS, THAT IS OUR SIGNAL THAT {survival} HAS BEEN UPDATED ON CRAN!! | ||
# AT THAT POINT WE SHOULD DO THE FOLLOWING | ||
# 1. UPDATE THIS UNIT TEST TO ASSURE THERE IS _NO_ ERROR WITH coxph() | ||
# 2. ADD A MIN VERSION REQUIREMENT FOR THE {survival} PACKAGE | ||
# THIS CAN BE DONE IN TWO WAYS: | ||
# 1. in the DESCRIPTION file | ||
# 2. using rlang::check_installed("survival", version = <add required version number>) | ||
testthat::expect_error(survival::coxph(visR::Surv_CNSR() ~ SEX, data = adtte)) | ||
}) | ||
|
||
|
||
testthat::test_that("T1.3 The results of the estimation match between Surv_CNSR and Surv with inverted censoring", { | ||
testthat::expect_equal( | ||
with(adtte, visR::Surv_CNSR()), | ||
with(adtte, survival::Surv(AVAL, 1 - CNSR)) | ||
) | ||
|
||
km1 <- adtte %>% visR::estimate_KM(formula = visR::Surv_CNSR() ~ 1) | ||
km2 <- adtte %>% visR::estimate_KM() | ||
km1$call <- km2$call <- NULL | ||
testthat::expect_equal(km1, km2) | ||
|
||
km1 <- adtte %>% visR::estimate_KM(formula = visR::Surv_CNSR() ~ SEX) | ||
km2 <- adtte %>% visR::estimate_KM(strata = "SEX") | ||
km1$call <- km2$call <- NULL | ||
testthat::expect_equal(km1, km2) | ||
}) | ||
|
||
# Requirement T2 ---------------------------------------------------------- | ||
|
||
testthat::test_that("T2.1 An error when column name specified through AVAL is not present in the environment", { | ||
testthat::expect_true(! "AVAL" %in% colnames(survival::lung)) | ||
testthat::expect_error(survival::survfit(visR::Surv_CNSR() ~ 1, data = survival::lung)) | ||
testthat::expect_error(survival::survfit(visR::Surv_CNSR() ~ sex, data = survival::lung)) | ||
|
||
adtte[["AVAL"]] <- NULL | ||
testthat::expect_error(survival::survfit(visR::Surv_CNSR() ~ 1, data = adtte)) | ||
}) | ||
|
||
testthat::test_that("T2.2 An error when column name specified through AVAL in the environment is not numeric", { | ||
adtte[["AVAL"]] <- as.character(adtte[["AVAL"]]) | ||
testthat::expect_error(survival::survfit(visR::Surv_CNSR() ~ 1, data = adtte)) | ||
|
||
testthat::expect_error(survival::survfit(visR::Surv_CDISC(AVAL = time) ~ 1, data = survival::lung %>% dplyr::mutate(AVAL = as.character(time)))) | ||
}) | ||
|
||
testthat::test_that("T2.3 A warning when the column specified through AVAL has negative values", { | ||
testthat::expect_warning(survival::survfit(visR::Surv_CNSR() ~ 1, data = adtte %>% dplyr::mutate(AVAL = AVAL - 10000))) | ||
}) | ||
|
||
testthat::test_that("T2.4 An error when the column name specified through CNSR is not present in the environment", { | ||
testthat::expect_true(! "CNSR" %in% colnames(survival::lung)) | ||
testthat::expect_error(survival::survfit(visR::Surv_CNSR() ~ 1, data = survival::lung %>% dplyr::rename(AVAL = time))) | ||
testthat::expect_error(survival::survfit(visR::Surv_CNSR() ~ sex, data = survival::lung %>% dplyr::rename(AVAL = time))) | ||
|
||
adtte[["CNSR"]] <- NULL | ||
testthat::expect_error(survival::survfit(visR::Surv_CNSR() ~ 1, data = adtte)) | ||
}) | ||
|
||
testthat::test_that("T2.5 An error when the column name specified through CNSR in the environment is not numeric", { | ||
adtte[["CNSR"]] <- as.character(adtte[["CNSR"]]) | ||
testthat::expect_error(survival::survfit(visR::Surv_CNSR() ~ 1, data = adtte)) | ||
|
||
testthat::expect_error(survival::survfit(visR::Surv_CDISC(AVAL = time) ~ 1, data = survival::lung %>% dplyr::mutate(CNSR = as.character(status)))) | ||
}) | ||
|
||
# END OF CODE ------------------------------------------------------------- |