diff --git a/.Rbuildignore b/.Rbuildignore index b2ca62554d..25344f5555 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -28,3 +28,4 @@ ^\.lycheeignore$ ^staged_dependencies.yaml$ ^inst/dev_dependencies.R$ +^\.devcontainer$ diff --git a/.Rprofile b/.Rprofile index 77ae067e30..d059c2fcc5 100644 --- a/.Rprofile +++ b/.Rprofile @@ -1,15 +1,48 @@ # Set renv profile base on R version. -if ((Sys.getenv("GITHUB_ACTIONS") == "") && (Sys.getenv("DOCKER_CONTAINER_CONTEXT") == "")) { - renv_profile <- paste(R.version$major, substr(R.version$minor, 1, 1), sep = ".") - if (file.exists("./renv/profile")) { - message("Using renv profile from `renv/profile` file.") - } else if (renv_profile %in% c("4.1", "4.2", "4.3")) { - message("Set renv profile to `", renv_profile, "`") - Sys.setenv("RENV_PROFILE" = renv_profile) +.get_dependencies <- function(project_dir) { + + admdev_loc <- find.package("admiraldev", lib.loc = .libPaths(), quiet = TRUE) + adm_dev_suggests <- if(length(admdev_loc) != 0) { + renv:::renv_dependencies_discover_description(admdev_loc, fields = c("Depends", "Imports", "LinkingTo", "Suggests")) + } else { + data.frame(Packages = character(0)) + } + suggests_packages <- renv:::renv_dependencies_discover_description(project_dir, fields = "Suggests") + + packages <- names( + renv:::renv_package_dependencies( + unique(c( + project_dir, + adm_dev_suggests[["Package"]], + suggests_packages[["Package"]], + c("staged.dependencies", "renv", "styler") + )) + ) + ) + packages[!(packages %in% c("admiral", "admiraldev", "admiralci", "admiral.test", "pharmaversesdtm", getwd()))] +} + +options(renv.snapshot.filter = .get_dependencies) + +.renv_profile <- paste(R.version$major, substr(R.version$minor, 1, 1), sep = ".") +if (!file.exists("./renv/profile")) { + if (.renv_profile %in% c("4.1", "4.2", "4.3")) { + message("Set renv profile to `", .renv_profile, "`") + Sys.setenv("RENV_PROFILE" = .renv_profile) } else { message("This repository do not contains the renv profile for your R version.") } - source("renv/activate.R") } else { - options(repos = c(CRAN = "https://cran.rstudio.com")) + message( + "Using renv profile from `renv/profile` file.\n", + "The `", readLines("./renv/profile"), "` profile will be used." + ) +} + +if (Sys.getenv("GITHUB_ACTIONS") != "") { + options(repos = c(CRAN = "https://packagemanager.posit.co/cran/latest")) + Sys.setenv("RENV_AUTOLOADER_ENABLED" = FALSE) } +Sys.setenv("RENV_CONFIG_SANDBOX_ENABLED" = FALSE) +Sys.setenv("RENV_CONFIG_AUTO_SNAPSHOT" = FALSE) +source("renv/activate.R") diff --git a/.devcontainer/4.1/devcontainer.json b/.devcontainer/4.1/devcontainer.json new file mode 100644 index 0000000000..1d05f7fdf1 --- /dev/null +++ b/.devcontainer/4.1/devcontainer.json @@ -0,0 +1,76 @@ +{ + // https://containers.dev/implementors/json_reference/ + "name": "Admiral R-4.1 (RStudio) container", + "image": "ghcr.io/pharmaverse/admiralci-4.1:latest", + // Install Dev Container Features. More info: https://containers.dev/features + "containerEnv": { + "ROOT": "true", + "PASSWORD": "rstudio", + "DISABLE_AUTH": "true", + "RENV_AUTOLOADER_ENABLED": "false" + }, + "features": { + "ghcr.io/rocker-org/devcontainer-features/r-rig:1": { + "version": "none", + "vscodeRSupport": "full", + "installRadian": true, + "installVscDebugger": true + }, + "ghcr.io/rocker-org/devcontainer-features/renv-cache:latest": {}, + "ghcr.io/devcontainers/features/common-utils:2": { + "installZsh": true, + "configureZshAsDefaultShell": false, + "installOhMyZsh": true, + "username": "rstudio", + "upgradePackages": false + }, + "ghcr.io/mikaello/devcontainer-features/modern-shell-utils:1": {} + }, + "init": true, + "overrideCommand": false, + + "postCreateCommand": "bash ./.devcontainer/postCreateCommand.sh", + + "postAttachCommand": "$BROWSER \"https://${CODESPACE_NAME}-8787.${GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN}/\"", + + "customizations": { + "vscode": { + "settings": { + "r.rterm.linux": "/usr/local/bin/radian", + "r.bracketedPaste": true, + "editor.bracketPairColorization.enabled": true, + "editor.guides.bracketPairs": "active" + }, + "extensions": [ + "vsls-contrib.codetour", + "GitHub.copilot", + "GitHub.copilot-chat", + // R extensions + "ikuyadeu.r", + "REditorSupport.r-lsp", + // Extra extension + "streetsidesoftware.code-spell-checker", + "eamodio.gitlens", + "cweijan.vscode-office", + "donjayamanne.githistory", + "GitHub.vscode-github-actions", + "GitHub.vscode-pull-request-github", + "GitHub.remotehub", + "alefragnani.Bookmarks", + "vscode-icons-team.vscode-icons" + ] + } + }, + + // RStudio ports + "forwardPorts": [8787], + "portsAttributes": { + "8787": { + "label": "Rstudio", + "requireLocalPort": true, + "onAutoForward": "openBrowser" + } + }, + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root + "remoteUser": "rstudio" +} diff --git a/.devcontainer/4.2/devcontainer.json b/.devcontainer/4.2/devcontainer.json new file mode 100644 index 0000000000..f30486e0d8 --- /dev/null +++ b/.devcontainer/4.2/devcontainer.json @@ -0,0 +1,76 @@ +{ + // https://containers.dev/implementors/json_reference/ + "name": "Admiral R-4.2 (RStudio) container", + "image": "ghcr.io/pharmaverse/admiralci-4.2:latest", + // Install Dev Container Features. More info: https://containers.dev/features + "containerEnv": { + "ROOT": "true", + "PASSWORD": "rstudio", + "DISABLE_AUTH": "true", + "RENV_AUTOLOADER_ENABLED": "false" + }, + "features": { + "ghcr.io/rocker-org/devcontainer-features/r-rig:1": { + "version": "none", + "vscodeRSupport": "full", + "installRadian": true, + "installVscDebugger": true + }, + "ghcr.io/rocker-org/devcontainer-features/renv-cache:latest": {}, + "ghcr.io/devcontainers/features/common-utils:2": { + "installZsh": true, + "configureZshAsDefaultShell": false, + "installOhMyZsh": true, + "username": "rstudio", + "upgradePackages": false + }, + "ghcr.io/mikaello/devcontainer-features/modern-shell-utils:1": {} + }, + "init": true, + "overrideCommand": false, + + "postCreateCommand": "bash ./.devcontainer/postCreateCommand.sh", + + "postAttachCommand": "$BROWSER \"https://${CODESPACE_NAME}-8787.${GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN}/\"", + + "customizations": { + "vscode": { + "settings": { + "r.rterm.linux": "/usr/local/bin/radian", + "r.bracketedPaste": true, + "editor.bracketPairColorization.enabled": true, + "editor.guides.bracketPairs": "active" + }, + "extensions": [ + "vsls-contrib.codetour", + "GitHub.copilot", + "GitHub.copilot-chat", + // R extensions + "ikuyadeu.r", + "REditorSupport.r-lsp", + // Extra extension + "streetsidesoftware.code-spell-checker", + "eamodio.gitlens", + "cweijan.vscode-office", + "donjayamanne.githistory", + "GitHub.vscode-github-actions", + "GitHub.vscode-pull-request-github", + "GitHub.remotehub", + "alefragnani.Bookmarks", + "vscode-icons-team.vscode-icons" + ] + } + }, + + // RStudio ports + "forwardPorts": [8787], + "portsAttributes": { + "8787": { + "label": "Rstudio", + "requireLocalPort": true, + "onAutoForward": "openBrowser" + } + }, + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root + "remoteUser": "rstudio" +} diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000000..4f49db8fe5 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,76 @@ +{ + // https://containers.dev/implementors/json_reference/ + "name": "Admiral R-4.3 (RStudio) container", + "image": "ghcr.io/pharmaverse/admiralci-4.3:latest", + // Install Dev Container Features. More info: https://containers.dev/features + "containerEnv": { + "ROOT": "true", + "PASSWORD": "rstudio", + "DISABLE_AUTH": "true", + "RENV_AUTOLOADER_ENABLED": "false" + }, + "features": { + "ghcr.io/rocker-org/devcontainer-features/r-rig:1": { + "version": "none", + "vscodeRSupport": "full", + "installRadian": true, + "installVscDebugger": true + }, + "ghcr.io/rocker-org/devcontainer-features/renv-cache:latest": {}, + "ghcr.io/devcontainers/features/common-utils:2": { + "installZsh": true, + "configureZshAsDefaultShell": false, + "installOhMyZsh": true, + "username": "rstudio", + "upgradePackages": false + }, + "ghcr.io/mikaello/devcontainer-features/modern-shell-utils:1": {} + }, + "init": true, + "overrideCommand": false, + + "postCreateCommand": "bash ./.devcontainer/postCreateCommand.sh", + + "postAttachCommand": "$BROWSER \"https://${CODESPACE_NAME}-8787.${GITHUB_CODESPACES_PORT_FORWARDING_DOMAIN}/\"", + + "customizations": { + "vscode": { + "settings": { + "r.rterm.linux": "/usr/local/bin/radian", + "r.bracketedPaste": true, + "editor.bracketPairColorization.enabled": true, + "editor.guides.bracketPairs": "active" + }, + "extensions": [ + "vsls-contrib.codetour", + "GitHub.copilot", + "GitHub.copilot-chat", + // R extensions + "ikuyadeu.r", + "REditorSupport.r-lsp", + // Extra extension + "streetsidesoftware.code-spell-checker", + "eamodio.gitlens", + "cweijan.vscode-office", + "donjayamanne.githistory", + "GitHub.vscode-github-actions", + "GitHub.vscode-pull-request-github", + "GitHub.remotehub", + "alefragnani.Bookmarks", + "vscode-icons-team.vscode-icons" + ] + } + }, + + // RStudio ports + "forwardPorts": [8787], + "portsAttributes": { + "8787": { + "label": "Rstudio", + "requireLocalPort": true, + "onAutoForward": "openBrowser" + } + }, + // Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root + "remoteUser": "rstudio" +} diff --git a/.devcontainer/postCreateCommand.sh b/.devcontainer/postCreateCommand.sh new file mode 100644 index 0000000000..9b9db23af9 --- /dev/null +++ b/.devcontainer/postCreateCommand.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +R -q -e 'renv::restore(lockfile = file.path("renv", "profiles", paste(R.version$major, substr(R.version$minor, 1, 1), sep = "."), "renv.lock")); staged.dependencies::install_deps(staged.dependencies::dependency_table(project = ".", verbose = 1), verbose = 1);' + +jq --arg folder "$(pwd)/" '. + { "initial_working_directory": $folder }' .devcontainer/rstudio-prefs.json > ~/.config/rstudio/rstudio-prefs.json diff --git a/.devcontainer/rstudio-prefs.json b/.devcontainer/rstudio-prefs.json new file mode 100644 index 0000000000..2d5cce8464 --- /dev/null +++ b/.devcontainer/rstudio-prefs.json @@ -0,0 +1,8 @@ +{ + "save_workspace": "never", + "always_save_history": false, + "reuse_sessions_for_project_links": true, + "posix_terminal_shell": "bash", + "initial_working_directory": "/workspaces", + "show_hidden_files": true +} diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..f703101ad3 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,15 @@ +# This a CODEOWNERS file, where you can establish code owners. +# Code owners are automatically requested for review when someone opens a pull request +# that modifies code that they own. +# +# Lab related files for Gordon Miller +vignettes/lab_grading.Rmd @millerg23 +inst/adlb_grading/* @millerg23 +R/derive_var_atoxgr.R @millerg23 +data/atoxgr_criteria_ctcv5.rda @millerg23 + +# PKPD related files for Jeff Dickinson +inst/templates/ad_adppk.R @jeffreyad +inst/templates/ad_adpc.R @jeffreyad +R/compute_kidney.R @jeffreyad +vignettes/pk_adnca.Rmd @jeffreyad diff --git a/.github/workflows/cran-status.yml b/.github/workflows/cran-status.yml index c1802ff19f..504680a914 100644 --- a/.github/workflows/cran-status.yml +++ b/.github/workflows/cran-status.yml @@ -17,7 +17,7 @@ jobs: with: # Whom should the issue be assigned to if errors are encountered # in the CRAN status checks? - issue-assignees: "bundfussr,esimms999-gsk,thomas-neitmann,bms63" + issue-assignees: "bundfussr,esimms999-gsk,manciniedoardo,bms63" # Create an issue if one or more of the following # statuses are reported on the check report. statuses: "WARN,ERROR,NOTE" diff --git a/.github/workflows/stale-bot.yml b/.github/workflows/stale-bot.yml new file mode 100644 index 0000000000..d25d15ba91 --- /dev/null +++ b/.github/workflows/stale-bot.yml @@ -0,0 +1,25 @@ +# https://github.com/actions/stale + +name: Close Inactive Issues and Pull Requests +on: + schedule: + - cron: "30 1 * * *" + +jobs: + close-issues: + runs-on: ubuntu-latest + permissions: + issues: write + pull-requests: write + steps: + - uses: actions/stale@v8 + with: + days-before-issue-stale: 90 + days-before-issue-close: -1 + stale-issue-label: "stale" + stale-issue-message: "This issue is stale because it has been open for 90 days with no activity." + days-before-pr-stale: 15 + days-before-pr-close: -1 + stale-pr-label: "stale" + stale-pr-message: "This Pull Request is stale because it has not been worked on in 15 days." + repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/templates.yml b/.github/workflows/templates.yml index 9abed5e849..c693311d52 100644 --- a/.github/workflows/templates.yml +++ b/.github/workflows/templates.yml @@ -3,13 +3,15 @@ name: Check Templates on: workflow_dispatch: - pull_request_review: - types: [submitted] + pull_request: + branches: + - main + - devel jobs: templates: name: Check Templates uses: pharmaverse/admiralci/.github/workflows/check-templates.yml@main - if: github.event.review.state == 'approved' + if: github.event_name == 'pull_request' with: r-version: "4.1" diff --git a/.gitignore b/.gitignore index 6887dd7f14..aedad7715d 100644 --- a/.gitignore +++ b/.gitignore @@ -40,7 +40,6 @@ vignettes/*.pdf # website documents /docs/* -!/docs/pkgdown.yml doc Meta admiral.Rcheck/ diff --git a/.lycheeignore b/.lycheeignore index 7dbdbcd3c2..5774d2a153 100644 --- a/.lycheeignore +++ b/.lycheeignore @@ -3,4 +3,3 @@ https://github.com/pharmaverse/admiral/blob/main/ https://github.com/pharmaverse/admiral/blob/main/inst/templates/ad_adxx.R irongut/CodeCoverageSummary@v1.2.0 https://packagemanager.rstudio.com/cran/__linux__/focal/latest -https://pharmaverse.github.io/admiral/articles/higher_order.html diff --git a/DESCRIPTION b/DESCRIPTION index 2b13b8beb4..5f9482beab 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,65 +1,25 @@ Package: admiral Type: Package Title: ADaM in R Asset Library -Version: 0.11.1 +Version: 0.12.0 Authors@R: c( person("Ben", "Straub", email = "ben.x.straub@gsk.com", role = c("aut", "cre")), person("Stefan", "Bundfuss", role = "aut"), - person("Thomas", "Neitmann", role = "aut"), - person("Samia", "Kabi", role = "aut"), - person("Gordon", "Miller", role = "aut"), - person("Teckla", "Akinyi", role = "aut"), - person("Andrew", "Smith", role = "aut"), - person("Konstantina", "Koukourikou", role = "aut"), - person("Ross", "Farrugia", role = "aut"), - person("Eric", "Simms", role = "aut"), - person("Annie", "Yang", role = "aut"), - person("Robin", "Koeger", role = "aut"), - person("Sophie", "Shapcott", role = "aut"), - person("Ojesh", "Upadhyay", role = "aut"), - person("Jack", "McGavigan", role = "aut"), - person("Kamila", "Duniec", role = "aut"), - person("Gayatri", "G", role = "aut"), - person("Alana", "Harris", role = "aut"), - person("Mahdi", "About", role = "aut"), - person("Pooja", "Kumari", role = "aut"), - person("Claudia", "Carlucci", role = "aut"), - person("Daniil", "Stefonishin", role = "aut"), - person("Sadchla", "Mascary", role = "aut"), - person("Zelos", "Zhu", role = "aut"), person("Jeffrey", "Dickinson", role = "aut"), - person("Ania", "Golab", role = "aut"), - person("Kangjie", "Zhang", role = "aut"), - person("Daphne", "Grasselly", role = "aut"), + person("Ross", "Farrugia", role = "aut"), person("Adam", "Forys", role = "aut"), + person("Daphne", "Grasselly", role = "aut"), + person("Dinakar", "Kulkarni", role = "aut"), person("Edoardo", "Mancini", role = "aut"), + person("Sadchla", "Mascary", role = "aut"), + person("Gordon", "Miller", role = "aut"), + person("Sophie", "Shapcott", role = "aut"), + person("Eric", "Simms", role = "aut"), person("Stefan", "Thoma", role = "aut"), - person("Michael", "Thorpe", role = "ctb"), - person("Declan", "Hodges", role = "ctb"), - person("Jaxon", "Abercrombie", role = "ctb"), - person("Nick", "Ramirez", role = "ctb"), - person("Pavan", "Kumar", role = "ctb"), - person("Hamza", "Rahal", role = "ctb"), - person("Yohann", "Omnes", role = "ctb"), - person("Alice", "Ehmann", role = "ctb"), - person("Tom", "Ratford", role = "ctb"), - person("Vignesh", "Thanikachalam", role = "ctb"), - person("Ondrej", "Slama", role = "ctb"), - person("Shimeng", "Huang", role = "ctb"), - person("James", "Kim", role = "ctb"), - person("Shan", "Lee", role = "ctb"), - person("Bill", "Denney", role = "ctb"), - person("Syed", "Mubasheer", role = "ctb"), - person("Wenyi", "Liu", role = "ctb"), - person("Dinakar", "Kulkarni", role = "ctb"), - person("Franciszek", "Walkowiak", role = "ctb"), - person("Tamara", "Senior", role = "ctb"), - person("Jordanna", "Morrish", role = "ctb"), - person("Anthony", "Howard", role = "ctb"), - person("Barbara", "O'Reilly", role = "ctb"), - person("John", "Kirkpatrick", role = "ctb"), - person("James", "Black", role = "ctb"), - person("Leena", "Khatri", role = "ctb"), + person("Kangjie", "Zhang", role = "aut"), + person("Zelos", "Zhu", role = "aut"), + person("G", "Gayatri", role = "ctb"), + person("Thomas", "Neitmann", role = "ctb"), person("F. Hoffmann-La Roche AG", role = c("cph", "fnd")), person("GlaxoSmithKline LLC", role = c("cph", "fnd")) ) @@ -91,21 +51,14 @@ Imports: tidyr (>= 1.0.2), tidyselect (>= 1.1.0) Suggests: - admiral.test (>= 0.6.0), - covr, - devtools, + pharmaversesdtm, DT, diffdf, knitr, - lintr, + rmarkdown, methods, - pkgdown, readxl, - rmarkdown, - roxygen2, - spelling, testthat (>= 3.0.0), - tibble, - usethis + tibble VignetteBuilder: knitr Config/testthat/edition: 3 diff --git a/NAMESPACE b/NAMESPACE index cc45836698..e8b78072f6 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -87,7 +87,6 @@ export(derive_var_base) export(derive_var_basetype) export(derive_var_chg) export(derive_var_confirmation_flag) -export(derive_var_disposition_status) export(derive_var_dthcaus) export(derive_var_extreme_dt) export(derive_var_extreme_dtm) @@ -107,10 +106,8 @@ export(derive_var_relative_flag) export(derive_var_shift) export(derive_var_trtdurd) export(derive_var_trtemfl) -export(derive_var_worst_flag) export(derive_vars_aage) export(derive_vars_atc) -export(derive_vars_disposition_reason) export(derive_vars_dt) export(derive_vars_dtm) export(derive_vars_dtm_to_dt) @@ -128,6 +125,7 @@ export(desc) export(dose_freq_lookup) export(dthcaus_source) export(event) +export(event_joined) export(event_source) export(exprs) export(extend_source_datasets) @@ -139,8 +137,6 @@ export(filter_extreme) export(filter_joined) export(filter_not_exist) export(filter_relative) -export(format_eoxxstt_default) -export(format_reason_default) export(get_admiral_option) export(get_duplicates_dataset) export(get_many_to_one_dataset) diff --git a/NEWS.md b/NEWS.md index 5c60c0ed9e..e87c1e454f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,129 @@ + +# admiral 0.12.0 + +## New Features + +- `event_joined()` events were added. They can be specified for the `events` +argument in `derive_extreme_event()`. This allows to define events based on more +than one observation, e.g., events which need to be confirmed by a second +assessment. (#1960) + +- `atoxgr_criteria_daids.rda` added, which holds metadata for [Division of AIDS (DAIDS) Table for Grading the Severity of Adult and Pediatric Adverse Events](https://rsc.niaid.nih.gov/sites/default/files/daidsgradingcorrectedv21.pdf). You can find additional documentation here `atoxgr_criteria_daids()` + +## Updates of Existing Functions + +- The functions `derive_param_bmi()` and `derive_param_bsa()` are updated to have the option of producing more values at visits when only weight is collected (#1228). +- The functions `derive_var_age_years()` and `compute_age_years()` are updated to return an `NA` age in the case that the age unit is missing. (#2001) The argument `unit` for `derive_vars_aage()` is also changed to `age_unit` for consistency between these age-related functions. (#2025) +- The `derive_var_ontrtfl()` function has been updated to allow for the column passed in `ref_end_date` to contain `NA` values. Previously, if the end date was `NA`, the row would never be flagged. Now, an `NA` value is interpreted as the treatment being ongoing, for example. (#1984) + +- The function `derive_var_extreme_flag()` has a new function argument, `flag_all` that additionally flags all records if the first or last record is not unique. (#1979) + +- The function `derive_param_computed()` was enhanced: (#1968) + + - The `analysis_value` and `analysis_var` arguments were deprecated in favor of + `set_values_to`. This enables users to compute more than one variable. + - The `keep_nas` argument was added. If it is set to `TRUE`, observations are + created even if values contributing to the computed values are `NA`. + +- The function `derive_vars_dy()` is updated to avoid potential error when the input `dataset` with columns ending with `temp`. (#2012) +- Argument `keep_source_vars` was added to `derive_extreme_records()` which +specifies which variables in the new observations should be kept. (#1697) + +- Templates, vignettes, and other uses of `{admiral.test}` SDTM data are updated to use `{pharmaversesdtm}` instead. (#2040) + +- The `traceability_vars` argument in `date_source()` and `dthcaus_source` were deprecated in favor of `set_values_to`. The `date_source()` function creates a date_source object as input for `derive_var_extreme_dt()` and `derive_var_extreme_dtm()`,users can now define the traceability variables by assigning those variables to the `set_values_to`argument.Similarly, the `dthcaus_source` creates a dthcaus_source Object. (#2068) + + +- `derive_extreme_event()` was enhanced (#1960): + + - `event_joined()` events can be specified for the `events` argument. This + allows to define events based on more than one observation, e.g., events + which need to be confirmed by a second assessment. + + - The `source_datasets` argument was added to the function and the + `dataset_name` field to `event()`. It can be used to define events based on + a different dataset than the input dataset. + + - The `keep_source_vars` argument was added to the function and the + `keep_source_vars` field to `event()`. It allows to select which variables + should be kept for the selected observations. + + - The `mode` and `order` field were added to `event()`. They allow to select + the first or last observation per by group if there are multiple observation + fulfilling the event condition. + + - The `ignore_event_order` argument was added. + + - The `description` field was added to `event()`. It can be used to provide + a description of the event in plain language. + +- `derive_var_atoxgr_dir()` was enhanced (#1859): + + - Can now select `atoxgr_criteria_daids` in argument `meta_criteria` to create `ATOXGRL` and `ATOXGRH` based on [Division of AIDS (DAIDS) Table for Grading the Severity of Adult and Pediatric Adverse Events](https://rsc.niaid.nih.gov/sites/default/files/daidsgradingcorrectedv21.pdf) + + - New argument `signif_dig` added to control the number of significant digits to use when comparing 2 numeric values. + (https://github.com/pharmaverse/admiral/pull/2060) + +## Breaking Changes +- The `compute_duration(type)` argument added the `"duration"` type calculation, and this is the new default (previously `"interval"` differences were returned). See function help file for details on the difference between `"duration"` and `"interval"` calculations. (#1875) + +- The following functions, which were deprecated in previous `{admiral}` versions, have been removed: (#1950) + + - `derive_var_disposition_status()` + - `derive_vars_disposition_reason()` + - `format_eoxxstt_default()` + - `format_reason_default()` + - `derive_var_worst_flag()` + +- The following functions have been deprecated from previous `{admiral}` versions using the next phase of the deprecation process: (#1950) + + - `derive_param_extreme_event()` + - `derive_vars_last_dose()` + - `derive_var_last_dose_amt()` + - `derive_var_last_dose_date()` + - `derive_var_last_dose_grp()` + - `derive_var_basetype()` + - `derive_var_merged_cat()` + - `derive_var_merged_character()` + +- The arguments `dataset_adsl` in the function `derive_param_exist_flag()` and +`subject_keys` have been deprecated versions using the next phase of the deprecation process. (#1950) + +- The argument `wt` in the function `compute_egfr()` was deprecated in favor of `weight` using the first phase of the deprecation process. (#2020) + +- The `filter` argument in `derive_extreme_records()` was deprecated in favor of +the `filter_add` using the next phase of the deprecation process. (#1950) + +- The `analysis_value` and `analysis_var` arguments in `derive_param_computed()` +were deprecated in favor of `set_values_to` (#1968). + +- The `na_val` argument in `derive_var_shift()` has been deprecated in favor of +`missing_value` using the first phase of the deprecation process. (#2014) + +- The `dataset_expected_obs` argument in `derive_expected_records()` and `derive_locf_records()` +has been deprecated in favor of `dataset_ref`. (#2037) + +- The `span_period` argument in `derive_var_ontrtfl()` has been updated to only accept +`TRUE` or `FALSE`, where is previously accepted `"Y"` and `NULL`. (#2033) + +## Documentation + +- Non-exported utility and print functions were previously listed on the admiral website reference page. They have been removed. (#2049, #2050) + +- The description of the argument `reference_date` in the function `derive_vars_dy()` +has been clarified to make it agnostic to start/end selection. (#2027) + +- Date and Time Imputation User Guide/Vignette has section on preserving partial +dates updated (#2028) + +## Various + +- The list of package authors/contributors has been reformatted so that those who are actively maintaining the code base are now marked as *authors*, whereas those who made a significant contribution in the past are now down as *contributors*. All other acknowledgements have been moved to README section (#1941). + +- `derive_vars_joined()` had two bugs with regards to duplicates messaging and when `new_vars` was set to `NULL` that have now been addressed (#1966). + +- `compute_dtf()` had a bug with regards to imputing days to full date-time character strings. (#2042) + # admiral 0.11.1 - Fix bug in `derive_param_tte()`. (#1962) @@ -70,6 +196,7 @@ now. This affects `derive_param_tte()`. (#1727) - The `analysis_value` argument was enhanced such that any variable of the form `.` can be used, e.g., `QSORRES.CHSF13`. + ## Breaking Changes - `create_query_data()` and `derive_vars_query()` updated to rename variables in diff --git a/R/call_derivation.R b/R/call_derivation.R index 78e2e3283f..6afa0c5b80 100644 --- a/R/call_derivation.R +++ b/R/call_derivation.R @@ -118,7 +118,7 @@ call_derivation <- function(dataset = NULL, derivation, variable_params, ...) { } all_params <- union(unlist(map(variable_params, names)), names(fixed_params)) - assert_function_param(deparse(substitute(derivation)), all_params) + assert_function(derivation, all_params) for (i in seq_along(variable_params)) { fixed_params_ <- fixed_params[names(fixed_params) %notin% names(variable_params[[i]])] diff --git a/R/compute_age_years.R b/R/compute_age_years.R index 10afc698bb..529a864fad 100644 --- a/R/compute_age_years.R +++ b/R/compute_age_years.R @@ -14,10 +14,12 @@ #' as `"years"` and `"Years"`). #' #' Permitted Values: `"years"`, `"months"`, `"weeks"`, `"days"`, `"hours"`, `"minutes"`, -#' `"seconds"`. +#' `"seconds"`, `NA_character_`. #' -#' @details Returns a numeric vector of ages in years as doubles. Note, underlying -#' computations assume an equal number of days in each year (365.25). +#' @details Returns a numeric vector of ages in years as doubles. Note +#' that passing `NA_character_` as a unit will result in an `NA` value for the outputted +#' age. Also note, underlying computations assume an equal number of days in each +#' year (365.25). #' #' @return The ages contained in `age` converted to years. #' @@ -34,8 +36,8 @@ #' ) #' #' compute_age_years( -#' age = c(10, 520, 3650), -#' age_unit = c("YEARS", "WEEKS", "DAYS") +#' age = c(10, 520, 3650, 1000), +#' age_unit = c("YEARS", "WEEKS", "DAYS", NA_character_) #' ) #' compute_age_years <- function(age, @@ -57,9 +59,16 @@ compute_age_years <- function(age, )) } + if (length(age_unit) == 1) { + age_unit_rep <- rep(age_unit, length(age)) + } else { + age_unit_rep <- age_unit + } + age_years <- time_length( - duration(age, - units = tolower(age_unit) + duration( + num = if_else(is.na(age_unit_rep), NA_real_, age), + units = if_else(is.na(age_unit_rep), "years", tolower(age_unit_rep)) ), unit = "years" ) diff --git a/R/compute_duration.R b/R/compute_duration.R index 8e7e9bf3f8..3289d16ff4 100644 --- a/R/compute_duration.R +++ b/R/compute_duration.R @@ -66,10 +66,38 @@ #' #' Permitted Values: `TRUE`, `FALSE` #' +#' @param type lubridate duration type. +#' +#' See below for details. +#' +#' Default: `"duration"` +#' +#' Permitted Values: `"duration"`, `"interval"` +#' #' @details The output is a numeric vector providing the duration as time from #' start to end date in the specified unit. If the end date is before the start #' date, the duration is negative. #' +#' @section Duration Type: +#' +#' The [lubridate](https://lubridate.tidyverse.org/) package calculates two +#' types of spans between two dates: duration and interval. +#' While these calculations are largely the same, when the unit of the time period +#' is month or year the result can be slightly different. +#' +#' The difference arises from the ambiguity in the length of `"1 month"` or +#' `"1 year"`. +#' Months may have 31, 30, 28, or 29 days, and years are 365 days and 366 during leap years. +#' Durations and intervals help solve the ambiguity in these measures. +#' +#' The **interval** between `2000-02-01` and `2000-03-01` is `1` (i.e. one month). +#' The **duration** between these two dates is `0.95`, which accounts for the fact +#' that the year 2000 is a leap year, February has 29 days, and the average month +#' length is `30.4375`, i.e. `29 / 30.4375 = 0.95`. +#' +#' For additional details, review the +#' [lubridate time span reference page](https://lubridate.tidyverse.org/reference/timespan.html). +#' #' #' @return The duration between the two date in the specified unit #' @@ -79,6 +107,8 @@ #' #' @export #' +#' @seealso [derive_vars_duration()] +#' #' @examples #' library(lubridate) #' @@ -119,11 +149,13 @@ compute_duration <- function(start_date, out_unit = "days", floor_in = TRUE, add_one = TRUE, - trunc_out = FALSE) { + trunc_out = FALSE, + type = "duration") { # Checks assert_date_vector(start_date) assert_date_vector(end_date) assert_character_scalar(in_unit, values = valid_time_units()) + assert_character_scalar(type, values = c("interval", "duration")) assert_character_scalar(out_unit, values = c( valid_time_units(), "weeks", "min", "sec" @@ -155,7 +187,13 @@ compute_duration <- function(start_date, } # derive the duration in the output unit - duration <- time_length(start_date %--% end_date, unit = out_unit) + duration <- + switch(type, + "interval" = start_date %--% end_date, + "duration" = lubridate::as.duration(start_date %--% end_date) + ) %>% + time_length(unit = out_unit) + if (add_one) { # add one unit of the input unit (converted to the output unit), e.g., if # input unit is days and output unit is hours, 24 hours are added diff --git a/R/compute_kidney.R b/R/compute_kidney.R index ab0a687859..3d06062b56 100644 --- a/R/compute_kidney.R +++ b/R/compute_kidney.R @@ -20,7 +20,7 @@ #' #' A numeric vector is expected. #' -#' @param wt Weight (kg) +#' @param weight Weight (kg) #' #' A numeric vector is expected if `method = "CRCL"` #' @@ -42,6 +42,8 @@ #' #' Expected Values: `"CRCL"`, `"CKD-EPI"`, `"MDRD"` #' +#' @param wt *Deprecated*, please use `weight` instead. +#' #' @details #' #' Calculates an estimate of Glomerular Filtration Rate (eGFR) @@ -92,7 +94,7 @@ #' #' @examples #' compute_egfr( -#' creat = 90, creatu = "umol/L", age = 53, wt = 85, sex = "M", method = "CRCL" +#' creat = 90, creatu = "umol/L", age = 53, weight = 85, sex = "M", method = "CRCL" #' ) #' #' compute_egfr( @@ -120,19 +122,27 @@ #' base %>% #' dplyr::mutate( #' CRCL_CG = compute_egfr( -#' creat = CREATBL, creatu = CREATBLU, age = AGE, wt = WTBL, sex = SEX, +#' creat = CREATBL, creatu = CREATBLU, age = AGE, weight = WTBL, sex = SEX, #' method = "CRCL" #' ), #' EGFR_EPI = compute_egfr( -#' creat = CREATBL, creatu = CREATBLU, age = AGE, wt = WTBL, sex = SEX, +#' creat = CREATBL, creatu = CREATBLU, age = AGE, weight = WTBL, sex = SEX, #' method = "CKD-EPI" #' ), #' EGFR_MDRD = compute_egfr( -#' creat = CREATBL, creatu = CREATBLU, age = AGE, wt = WTBL, sex = SEX, +#' creat = CREATBL, creatu = CREATBLU, age = AGE, weight = WTBL, sex = SEX, #' race = RACE, method = "MDRD" #' ), #' ) -compute_egfr <- function(creat, creatu = "SI", age, wt, sex, race = NULL, method) { +compute_egfr <- function(creat, creatu = "SI", age, weight, sex, race = NULL, method, wt) { + ### BEGIN DEPRECATION + if (!missing(wt)) { + deprecate_warn("0.12.0", "compute_egfr(old_param = 'wt')", "compute_egfr(new_param = 'weight')") + # old_param is given using exprs() + weight <- wt + } + ### END DEPRECATION + assert_numeric_vector(creat) assert_character_vector(creatu, values = c( "SI", "CV", "mg/dL", "umol/L", NA_character_, @@ -164,15 +174,15 @@ compute_egfr <- function(creat, creatu = "SI", age, wt, sex, race = NULL, method sex == "M" ~ 175 * (scr^-1.154) * (age^-0.203) ) } else if (method == "CRCL") { - assert_numeric_vector(wt) + assert_numeric_vector(weight) egfr <- case_when( tolower(creatu) %in% c("cv", "mg/dl") & sex == "F" ~ - ((140 - age) * wt * 0.85) / (creat * 72), + ((140 - age) * weight * 0.85) / (creat * 72), tolower(creatu) %in% c("cv", "mg/dl") & sex == "M" ~ - ((140 - age) * wt) / (creat * 72), - sex == "F" ~ ((140 - age) * wt * 1.04) / creat, - sex == "M" ~ ((140 - age) * wt * 1.23) / creat + ((140 - age) * weight) / (creat * 72), + sex == "F" ~ ((140 - age) * weight * 1.04) / creat, + sex == "M" ~ ((140 - age) * weight * 1.23) / creat ) } else if (method == "CKD-EPI") { kappa <- case_when( diff --git a/R/create_query_data.R b/R/create_query_data.R index 29531eed09..0b272a8ba4 100644 --- a/R/create_query_data.R +++ b/R/create_query_data.R @@ -106,7 +106,7 @@ #' @examples #' library(tibble) #' library(dplyr, warn.conflicts = FALSE) -#' library(admiral.test) +#' library(pharmaversesdtm) #' library(admiral) #' #' # creating a query dataset for a customized query @@ -145,11 +145,11 @@ #' ) #' ) #' -#' # The get_terms function from admiral.test is used for this example. +#' # The get_terms function from pharmaversesdtm is used for this example. #' # In a real application a company-specific function must be used. #' create_query_data( #' queries = list(pregsmq, bilismq), -#' get_terms_fun = admiral.test:::get_terms, +#' get_terms_fun = pharmaversesdtm:::get_terms, #' version = "20.1" #' ) #' @@ -164,16 +164,16 @@ #' ) #' ) #' -#' # The get_terms function from admiral.test is used for this example. +#' # The get_terms function from pharmaversesdtm is used for this example. #' # In a real application a company-specific function must be used. #' create_query_data( #' queries = list(sdg), -#' get_terms_fun = admiral.test:::get_terms, +#' get_terms_fun = pharmaversesdtm:::get_terms, #' version = "2019-09" #' ) #' #' # creating a query dataset for a customized query including SMQs -#' # The get_terms function from admiral.test is used for this example. +#' # The get_terms function from pharmaversesdtm is used for this example. #' # In a real application a company-specific function must be used. #' create_query_data( #' queries = list( @@ -190,7 +190,7 @@ #' ) #' ) #' ), -#' get_terms_fun = admiral.test:::get_terms, +#' get_terms_fun = pharmaversesdtm:::get_terms, #' version = "20.1" #' ) create_query_data <- function(queries, diff --git a/R/data.R b/R/data.R index af62b3de70..d18679a327 100644 --- a/R/data.R +++ b/R/data.R @@ -131,3 +131,41 @@ #' @keywords metadata #' @family metadata "atoxgr_criteria_ctcv5" + +#' Metadata Holding Grading Criteria for DAIDs +#' +#' @details +#' This metadata has its origin in the ADLB Grading Spec Excel file which ships with `{admiral}` +#' and can be accessed using `system.file("adlb_grading/adlb_grading_spec.xlsx", package = "admiral")` +#' in sheet = "DAIDS". +#' The dataset contained in there has the following columns: +#' - `SOC`: variable to hold the SOC of the lab test criteria. +#' - `TERM`: variable to hold the term describing the criteria applied to a particular lab test, +#' eg. 'Anemia' or 'INR Increased'. Note: the variable is case insensitive. +#' - `SUBGROUP` : Description of sub-group of subjects were grading will be applied (i.e. >= 18 years) +#' - `Grade 1`: Criteria defining lab value as Grade 1. +#' - `Grade 2`: Criteria defining lab value as Grade 2. +#' - `Grade 3`: Criteria defining lab value as Grade 3. +#' - `Grade 4`: Criteria defining lab value as Grade 4. +#' - `Grade 5`: Criteria defining lab value as Grade 5. +#' - `Definition`: Holds the definition of the lab test abnormality. +#' - `FILTER` : `admiral` code to apply the filter based on SUBGROUP column. +#' - `GRADE_CRITERIA_CODE`: variable to hold code that creates grade based on defined criteria. +#' - `SI_UNIT_CHECK`: variable to hold unit of particular lab test. Used to check against input data +#' if criteria is based on absolute values. +#' - `VAR_CHECK`: List of variables required to implement lab grade criteria. Use to check against +#' input data. +#' - `DIRECTION`: variable to hold the direction of the abnormality of a particular lab test +#' value. 'L' is for LOW values, 'H' is for HIGH values. Note: the variable is case insensitive. +#' - `COMMENT`: Holds any information regarding rationale behind implementation of grading criteria. +#' +#' Note: Variables `SOC`, `TERM`, `SUBGROUP`, `Grade 1`, `Grade 2`,`Grade 3`,`Grade 4`,`Grade 5`, `Definition` +#' are from the source document on DAIDS website defining the grading criteria. +#' [Division of AIDS (DAIDS) Table for Grading the Severity of Adult and Pediatric Adverse Events +#' From these variables only 'TERM' is used in the {admiral} code, the rest are for information and +#' traceability only. +#' +#' +#' @keywords metadata +#' @family metadata +"atoxgr_criteria_daids" diff --git a/R/derive_adeg_params.R b/R/derive_adeg_params.R index f7a238e88c..05ae271421 100644 --- a/R/derive_adeg_params.R +++ b/R/derive_adeg_params.R @@ -47,11 +47,12 @@ #' #' Permitted Values: A variable of the input dataset or a function call #' +#' @inheritParams derive_param_map +#' #' @inheritParams derive_param_computed #' #' @seealso [compute_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`. #' @@ -61,6 +62,8 @@ #' #' @export #' +#' @seealso [compute_qtc()] +#' #' @examples #' library(tibble) #' @@ -151,12 +154,14 @@ derive_param_qtc <- function(dataset, filter = !!filter, parameters = c(qt_code, rr_code), by_vars = by_vars, - analysis_value = compute_qtc( - qt = !!sym(paste0("AVAL.", qt_code)), - rr = !!sym(paste0("AVAL.", rr_code)), - method = !!method - ), - set_values_to = set_values_to + set_values_to = exprs( + AVAL = compute_qtc( + qt = !!sym(paste0("AVAL.", qt_code)), + rr = !!sym(paste0("AVAL.", rr_code)), + method = !!method + ), + !!!set_values_to + ) ) } @@ -176,6 +181,8 @@ derive_param_qtc <- function(dataset, #' @family der_prm_bds_findings #' @keywords der_prm_bds_findings #' +#' @seealso [derive_param_qtc()] +#' #' @examples #' default_qtc_paramcd("Sagie") default_qtc_paramcd <- function(method) { @@ -219,6 +226,8 @@ default_qtc_paramcd <- function(method) { #' #' @export #' +#' @seealso [derive_param_qtc()] +#' #' @examples #' compute_qtc(qt = 350, rr = 56.54, method = "Bazett") #' @@ -264,6 +273,8 @@ compute_qtc <- function(qt, rr, method) { #' #' Permitted Values: character value #' +#' @inheritParams derive_param_map +#' #' @inheritParams derive_param_computed #' #' @inheritParams derive_param_qtc @@ -277,6 +288,8 @@ compute_qtc <- function(qt, rr, method) { #' #' @export #' +#' @seealso [compute_rr()] +#' #' @examples #' library(tibble) #' @@ -332,8 +345,10 @@ derive_param_rr <- function(dataset, filter = !!filter, parameters = c(hr_code), by_vars = by_vars, - analysis_value = compute_rr(!!sym(paste0("AVAL.", hr_code))), - set_values_to = set_values_to + set_values_to = exprs( + AVAL = compute_rr(!!sym(paste0("AVAL.", hr_code))), + !!!set_values_to + ) ) } @@ -358,6 +373,8 @@ derive_param_rr <- function(dataset, #' #' @export #' +#' @seealso [derive_param_rr()] +#' #' @examples #' compute_rr(hr = 70.14) compute_rr <- function(hr) { diff --git a/R/derive_advs_params.R b/R/derive_advs_params.R index 1c269ea56f..881db1b92f 100644 --- a/R/derive_advs_params.R +++ b/R/derive_advs_params.R @@ -20,21 +20,29 @@ #' The observations where `PARAMCD` equals the specified value are considered #' as the systolic blood pressure assessments. #' -#' Permitted Values: character value +#' *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 +#' *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 +#' *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 #' @@ -58,11 +66,13 @@ #' #' @export #' +#' @seealso [compute_map()] +#' #' @examples #' library(tibble) #' library(dplyr, warn.conflicts = FALSE) #' -#' advs <- tribble( +#' 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", @@ -146,8 +156,10 @@ derive_param_map <- function(dataset, filter = !!filter, parameters = c(sysbp_code, diabp_code, hr_code), by_vars = by_vars, - analysis_value = !!analysis_value, - set_values_to = set_values_to + set_values_to = exprs( + AVAL = !!analysis_value, + !!!set_values_to + ) ) } @@ -186,6 +198,8 @@ derive_param_map <- function(dataset, #' #' @export #' +#' @seealso [derive_param_map()] +#' #' @examples #' # Compute MAP based on diastolic and systolic blood pressure #' compute_map(diabp = 51, sysbp = 121) @@ -239,21 +253,35 @@ compute_map <- function(diabp, sysbp, hr = NULL) { #' #' Takahira: `0.007241 * height ^ 0.725 * weight ^ 0.425` #' -#' Permitted Values: character value +#' *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 +#' *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 +#' *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. +#' +#' *Permitted Values:* list of variables +#' +#' @inheritParams derive_param_map #' #' @inheritParams derive_param_computed #' @@ -269,10 +297,13 @@ compute_map <- function(diabp, sysbp, hr = NULL) { #' #' @export #' +#' @seealso [compute_bsa()] +#' #' @examples #' library(tibble) #' -#' advs <- tribble( +#' # 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", @@ -292,7 +323,8 @@ compute_map <- function(diabp, sysbp, hr = NULL) { #' PARAMCD = "BSA", #' PARAM = "Body Surface Area (m^2)" #' ), -#' get_unit_expr = extract_unit(PARAM) +#' get_unit_expr = extract_unit(PARAM), +#' constant_by_vars = exprs(USUBJID) #' ) #' #' derive_param_bsa( @@ -303,6 +335,44 @@ compute_map <- function(diabp, sysbp, hr = NULL) { #' 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, @@ -312,7 +382,8 @@ derive_param_bsa <- function(dataset, height_code = "HEIGHT", weight_code = "WEIGHT", get_unit_expr, - filter = NULL) { + filter = NULL, + constant_by_vars = NULL) { assert_vars(by_vars) assert_data_frame(dataset, required_vars = exprs(!!!by_vars, PARAMCD, AVAL)) assert_character_scalar( @@ -328,6 +399,7 @@ derive_param_bsa <- function(dataset, 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, @@ -350,13 +422,25 @@ derive_param_bsa <- function(dataset, ) ) + 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) + } + derive_param_computed( dataset, filter = !!filter, - parameters = c(height_code, weight_code), + parameters = parameters, by_vars = by_vars, - analysis_value = !!bsa_formula, - set_values_to = set_values_to + set_values_to = exprs( + AVAL = !!bsa_formula, + !!!set_values_to + ), + constant_parameters = constant_parameters, + constant_by_vars = constant_by_vars ) } @@ -368,13 +452,13 @@ derive_param_bsa <- function(dataset, #' #' It is expected that HEIGHT is in cm. #' -#' Permitted Values: numeric vector +#' *Permitted Values:* numeric vector #' #' @param weight WEIGHT value #' #' It is expected that WEIGHT is in kg. #' -#' Permitted Values: numeric vector +#' *Permitted Values:* numeric vector #' #' @param method Derivation method to use: #' @@ -392,7 +476,7 @@ derive_param_bsa <- function(dataset, #' #' Takahira: 0.007241 * height ^ 0.725 * weight ^ 0.425 #' -#' Permitted Values: character value +#' *Permitted Values:* character value #' #' #' @details Usually this computation function can not be used with `%>%`. @@ -405,6 +489,8 @@ derive_param_bsa <- function(dataset, #' #' @export #' +#' @seealso [derive_param_bsa()] +#' #' @examples #' # Derive BSA by the Mosteller method #' compute_bsa( @@ -477,14 +563,30 @@ compute_bsa <- function(height = height, #' 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 +#' *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:* 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. +#' +#' *Permitted Values:* list of variables +#' +#' @inheritParams derive_param_map #' #' @inheritParams derive_param_computed #' @@ -504,19 +606,21 @@ compute_bsa <- function(height = height, #' #' @export #' +#' @seealso [compute_bmi()] +#' #' @examples -#' library(tibble) #' -#' advs <- 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" +#' # 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( @@ -528,6 +632,46 @@ compute_bsa <- function(height = height, #' 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, @@ -536,7 +680,8 @@ derive_param_bmi <- function(dataset, weight_code = "WEIGHT", height_code = "HEIGHT", get_unit_expr, - filter = NULL) { + 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") @@ -545,6 +690,8 @@ derive_param_bmi <- function(dataset, 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, @@ -559,16 +706,32 @@ derive_param_bmi <- function(dataset, 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) + } + derive_param_computed( dataset, filter = !!filter, - parameters = c(weight_code, height_code), + parameters = parameters, by_vars = by_vars, - analysis_value = compute_bmi( - height = !!sym(paste0("AVAL.", height_code)), - weight = !!sym(paste0("AVAL.", weight_code)) + set_values_to = exprs( + AVAL = !!bmi_formula, + !!!set_values_to ), - set_values_to = set_values_to + constant_parameters = constant_parameters, + constant_by_vars = constant_by_vars ) } @@ -580,13 +743,13 @@ derive_param_bmi <- function(dataset, #' #' It is expected that HEIGHT is in cm. #' -#' Permitted Values: numeric vector +#' *Permitted Values:* numeric vector #' #' @param weight WEIGHT value #' #' It is expected that WEIGHT is in kg. #' -#' Permitted Values: numeric vector +#' *Permitted Values:* numeric vector #' #' #' @details Usually this computation function can not be used with `%>%`. @@ -599,6 +762,8 @@ derive_param_bmi <- function(dataset, #' #' @export #' +#' @seealso [derive_param_bmi()] +#' #' @examples #' compute_bmi(height = 170, weight = 75) compute_bmi <- function(height, weight) { diff --git a/R/derive_basetype_records.R b/R/derive_basetype_records.R index 64fb271ac0..ef81d4cab4 100644 --- a/R/derive_basetype_records.R +++ b/R/derive_basetype_records.R @@ -96,7 +96,7 @@ #' count(bds_with_basetype, BASETYPE, name = "Number of Records") derive_basetype_records <- function(dataset, basetypes) { assert_data_frame(dataset) - assert_named_exprs(basetypes) + assert_expr_list(basetypes, named = TRUE) records_with_basetype <- map2(names(basetypes), basetypes, function(label, condition) { dataset %>% diff --git a/R/derive_date_vars.R b/R/derive_date_vars.R index c43e8dd38a..fd59df5145 100644 --- a/R/derive_date_vars.R +++ b/R/derive_date_vars.R @@ -330,8 +330,7 @@ impute_dtc_dtm <- function(dtc, #' #' #' @family utils_impute -#' -#' @keywords utils_impute +#' @keywords internal dtm_level <- function(level) { out <- factor( @@ -361,7 +360,7 @@ dtm_level <- function(level) { #' #' @family utils_impute #' -#' @keywords utils_impute +#' @keywords internal #' #' @seealso [impute_dtc_dtm()], [impute_dtc_dt()] get_partialdatetime <- function(dtc) { @@ -419,7 +418,7 @@ get_partialdatetime <- function(dtc) { #' #' @family utils_impute #' -#' @keywords utils_impute +#' @keywords internal #' #' @seealso [impute_dtc_dtm()], [impute_dtc_dt()] get_imputation_target_date <- function(date_imputation, @@ -468,7 +467,7 @@ get_imputation_target_date <- function(date_imputation, #' #' @family utils_impute #' -#' @keywords utils_impute +#' @keywords internal #' #' @seealso [impute_dtc_dtm()] get_imputation_target_time <- function(time_imputation) { @@ -507,7 +506,7 @@ get_imputation_target_time <- function(time_imputation) { #' #' @family utils_impute #' -#' @keywords utils_impute +#' @keywords internal #' #' @seealso [impute_dtc_dtm()], [impute_dtc_dt()] restrict_imputed_dtc_dtm <- function(dtc, @@ -704,7 +703,7 @@ restrict_imputed_dtc_dtm <- function(dtc, #' highest_imputation = "M" #' ) #' # Same as above -#' impute_dtc_dtm( +#' impute_dtc_dt( #' dtc = dates, #' highest_imputation = "M", #' date_imputation = "01-01" @@ -859,10 +858,8 @@ impute_dtc_dt <- function(dtc, #' @details A `dt_level` object is an ordered factor, i.e., two objects can be #' compared. #' -#' #' @family utils_impute -#' @keywords utils_impute -#' +#' @keywords internal dt_level <- function(level) { out <- factor( @@ -891,7 +888,7 @@ dt_level <- function(level) { #' #' @family utils_impute #' -#' @keywords utils_impute +#' @keywords internal #' #' @seealso [impute_dtc_dtm()], [impute_dtc_dt()] restrict_imputed_dtc_dt <- function(dtc, @@ -1140,6 +1137,10 @@ convert_date_to_dtm <- function(dt, #' @examples #' compute_dtf(dtc = "2019-07", dt = as.Date("2019-07-18")) #' compute_dtf(dtc = "2019", dt = as.Date("2019-07-18")) +#' compute_dtf(dtc = "--06-01T00:00", dt = as.Date("2022-06-01")) +#' compute_dtf(dtc = "2022-06--T00:00", dt = as.Date("2022-06-01")) +#' compute_dtf(dtc = "2022---01T00:00", dt = as.Date("2022-06-01")) +#' compute_dtf(dtc = "2022----T00:00", dt = as.Date("2022-06-01")) compute_dtf <- function(dtc, dt) { assert_character_vector(dtc) assert_date_vector(dt) @@ -1149,12 +1150,24 @@ compute_dtf <- function(dtc, dt) { valid_dtc <- is_valid_dtc(dtc) warn_if_invalid_dtc(dtc, valid_dtc) + # Find date portion + date_portion <- ifelse(grepl("T", dtc), + gsub("T", "", substr(dtc, 1, str_locate(dtc, "T")[, 1])), + substr(dtc, 1, 10) + ) + n_chr_date_portion <- nchar(date_portion) + + # Location of the first instance of the double hyphen to determine if its month/day imputation + location_of_double_hyphen <- str_locate(date_portion, "--")[, 1] + case_when( - (!is_na & n_chr >= 10 & valid_dtc) | is_na | !valid_dtc ~ NA_character_, - n_chr < 4 | is.na(dtc) ~ "Y", - n_chr == 4 ~ "M", - n_chr == 7 ~ "D", - n_chr == 9 ~ "M" # dates like "2019---07" + (!is_na & n_chr >= 10 & n_chr_date_portion == 10 & valid_dtc) | is_na | !valid_dtc ~ NA_character_, # nolint + n_chr_date_portion < 4 | is.na(dtc) ~ "Y", + n_chr_date_portion < 10 & location_of_double_hyphen == 1 ~ "Y", # dates like "--07-07" + n_chr_date_portion == 4 ~ "M", + n_chr_date_portion < 10 & location_of_double_hyphen == 5 ~ "M", # dates like "2019---07" + n_chr_date_portion == 7 ~ "D", + n_chr_date_portion < 10 & location_of_double_hyphen == 8 ~ "D", # dates like "2019-07--" ) } diff --git a/R/derive_expected_records.R b/R/derive_expected_records.R index c9a753fedc..f61cf2dab9 100644 --- a/R/derive_expected_records.R +++ b/R/derive_expected_records.R @@ -5,17 +5,19 @@ #' #' @param dataset Input dataset #' -#' A data frame, the columns from `dataset_expected_obs` and specified by the +#' A data frame, the columns from `dataset_ref` and specified by the #' `by_vars` parameter are expected. #' -#' @param dataset_expected_obs Expected observations dataset +#' @param dataset_expected_obs *Deprecated*, please use `dataset_ref` instead. +#' +#' @param dataset_ref Expected observations dataset #' #' Data frame with the expected observations, e.g., all the expected #' combinations of `PARAMCD`, `PARAM`, `AVISIT`, `AVISITN`, ... #' #' @param by_vars Grouping variables #' -#' For each group defined by `by_vars` those observations from `dataset_expected_obs` +#' For each group defined by `by_vars` those observations from `dataset_ref` #' are added to the output dataset which do not have a corresponding observation #' in the input dataset. #' @@ -31,7 +33,7 @@ #' "TDOSE", PARCAT1 = "OVERALL")`. #' #' @details For each group (the variables specified in the `by_vars` parameter), -#' those records from `dataset_expected_obs` that are missing in the input +#' those records from `dataset_ref` that are missing in the input #' dataset are added to the output dataset. #' #' @return The input dataset with the missed expected observations added for each @@ -63,7 +65,7 @@ #' #' derive_expected_records( #' dataset = adqs, -#' dataset_expected_obs = parm_visit_ref, +#' dataset_ref = parm_visit_ref, #' by_vars = exprs(USUBJID, PARAMCD), #' set_values_to = exprs(DTYPE = "DERIVED") #' ) @@ -78,35 +80,46 @@ #' #' derive_expected_records( #' dataset = adqs, -#' dataset_expected_obs = parm_visit_ref, +#' dataset_ref = parm_visit_ref, #' by_vars = exprs(USUBJID, PARAMCD), #' set_values_to = exprs(DTYPE = "DERIVED") #' ) #' derive_expected_records <- function(dataset, dataset_expected_obs, + dataset_ref, by_vars = NULL, set_values_to = NULL) { + if (!missing(dataset_expected_obs)) { + deprecate_warn( + "0.12.0", + "derive_expected_records(dataset_expected_obs = )", + "derive_expected_records(dataset_ref = )" + ) + assert_data_frame(dataset_expected_obs) + dataset_ref <- dataset_expected_obs + } + # Check input parameters assert_vars(by_vars, optional = TRUE) - assert_data_frame(dataset_expected_obs) + assert_data_frame(dataset_ref) assert_data_frame( dataset, - required_vars = expr_c(by_vars, chr2vars(colnames(dataset_expected_obs))) + required_vars = expr_c(by_vars, chr2vars(colnames(dataset_ref))) ) assert_varval_list(set_values_to, optional = TRUE) # Derive expected records - ## ids: Variables from by_vars but not in dataset_expected_obs + ## ids: Variables from by_vars but not in dataset_ref ids <- dataset %>% - select(!!!setdiff(by_vars, chr2vars(colnames(dataset_expected_obs)))) %>% + select(!!!setdiff(by_vars, chr2vars(colnames(dataset_ref)))) %>% distinct() if (ncol(ids) > 0) { exp_obsv <- ids %>% - crossing(dataset_expected_obs) + crossing(dataset_ref) } else { - exp_obsv <- dataset_expected_obs + exp_obsv <- dataset_ref } # tmp workaround, update after using tidyr 1.2.0 exp_obs_vars <- exp_obsv %>% diff --git a/R/derive_extreme_event.R b/R/derive_extreme_event.R index e81dadfd86..aa4d01038c 100644 --- a/R/derive_extreme_event.R +++ b/R/derive_extreme_event.R @@ -3,10 +3,21 @@ #' Add the first available record from `events` for each by group as new #' records, all variables of the selected observation are kept. It can be used #' for selecting the extreme observation from a series of user-defined events. -#' This distinguish `derive_extreme_event()` from `derive_extreme_records()`, +#' This distinguishes `derive_extreme_event()` from `derive_extreme_records()`, #' where extreme records are derived based on certain order of existing #' variables. #' +#' @param events Conditions and new values defining events +#' +#' A list of `event()` or `event_joined()` objects is expected. Only +#' observations listed in the `events` are considered for deriving extreme +#' event. If multiple records meet the filter `condition`, take the first +#' record sorted by `order`. The data is grouped by `by_vars`, i.e., summary +#' functions like `all()` or `any()` can be used in `condition`. +#' +#' For `event_joined()` events the observations are selected by calling +#' `filter_joined`. The `condition` field is passed to the `filter` argument. +#' #' @param order Sort order #' #' If a particular event from `events` has more than one observation, within @@ -23,20 +34,51 @@ #' #' *Permitted Values:* `"first"`, `"last"` #' -#' @param events Conditions and new values defining events +#' @param source_datasets Source datasets +#' +#' A named list of datasets is expected. The `dataset_name` field of `event()` +#' and `event_joined()` refers to the dataset provided in the list. +#' +#' @param ignore_event_order Ignore event order +#' +#' If the argument is set to `TRUE`, all events defined by `events` are +#' considered equivalent. If there is more than one observation per by group +#' the first or last (with respect to `mode` and `order`) is select without +#' taking the order of the events into account. #' -#' A list of `event()` objects is expected. Only observations listed in the -#' `events` are considered for deriving extreme event. If multiple records -#' meet the filter `condition`, take the first record sorted by `order`. +#' *Permitted Values:* `TRUE`, `FALSE` +#' +#' @param keep_source_vars Variables to keep from the source dataset +#' +#' For each event the specified variables are kept from the selected +#' observations. The variables specified for `by_vars` and created by +#' `set_values_to` are always kept. +#' +#' *Permitted Values*: A list of expressions where each element is +#' a symbol or a tidyselect expression, e.g., `exprs(VISIT, VISITNUM, +#' starts_with("RS"))`. #' #' @inheritParams filter_extreme #' @inheritParams derive_summary_records #' #' @details -#' 1. Construct a dataset based on `events`: apply the filter `condition` and -#' `set_values_to` to the input dataset. +#' 1. For each event select the observations to consider: +#' +#' 1. If the event is of class `event`, the observations of the source dataset +#' are restricted by `condition` and then the first or last (`mode`) +#' observation per by group (`by_vars`) is selected. +#' +#' If the event is of class `event_joined`, `filter_joined()` is called to +#' select the observations. +#' +#' 1. The variables specified by the `set_values_to` field of the event +#' are added to the selected observations. +#' 1. Only the variables specified for the `keep_source_vars` field of the +#' event, and the by variables (`by_vars`) and the variables created by +#' `set_values_to` are kept. #' 1. For each group (with respect to the variables specified for the -#' `by_vars` parameter) the first or last observation (with respect to the +#' `by_vars` parameter) the first event is selected. If there is more than one +#' observation per event the first or last observation (with respect to the #' order specified for the `order` parameter and the mode specified for the #' `mode` parameter) is selected. #' 1. The variables specified by the `set_values_to` parameter are added to @@ -50,10 +92,14 @@ #' @family der_prm_bds_findings #' @keywords der_prm_bds_findings #' +#' @seealso [event()], [event_joined()] +#' #' @export #' #' @examples #' library(tibble) +#' library(dplyr) +#' library(lubridate) #' #' adqs <- tribble( #' ~USUBJID, ~PARAMCD, ~AVALC, ~ADY, @@ -102,22 +148,214 @@ #' PARAM = "Worst Sleeping Problems" #' ) #' ) +#' +#' # Use different mode by event +#' adhy <- tribble( +#' ~USUBJID, ~AVISITN, ~CRIT1FL, +#' "1", 1, "Y", +#' "1", 2, "Y", +#' "2", 1, "Y", +#' "2", 2, NA_character_, +#' "2", 3, "Y", +#' "2", 4, NA_character_ +#' ) %>% +#' mutate( +#' PARAMCD = "ALKPH", +#' PARAM = "Alkaline Phosphatase (U/L)" +#' ) +#' +#' derive_extreme_event( +#' adhy, +#' by_vars = exprs(USUBJID), +#' events = list( +#' event( +#' condition = is.na(CRIT1FL), +#' set_values_to = exprs(AVALC = "N") +#' ), +#' event( +#' condition = CRIT1FL == "Y", +#' mode = "last", +#' set_values_to = exprs(AVALC = "Y") +#' ) +#' ), +#' order = exprs(AVISITN), +#' mode = "first", +#' keep_source_vars = exprs(AVISITN), +#' set_values_to = exprs( +#' PARAMCD = "ALK2", +#' PARAM = "ALKPH <= 2 times ULN" +#' ) +#' ) +#' +#' # Derive confirmed best overall response (using event_joined()) +#' # CR - complete response, PR - partial response, SD - stable disease +#' # NE - not evaluable, PD - progressive disease +#' adsl <- tribble( +#' ~USUBJID, ~TRTSDTC, +#' "1", "2020-01-01", +#' "2", "2019-12-12", +#' "3", "2019-11-11", +#' "4", "2019-12-30", +#' "5", "2020-01-01", +#' "6", "2020-02-02", +#' "7", "2020-02-02", +#' "8", "2020-02-01" +#' ) %>% +#' mutate(TRTSDT = ymd(TRTSDTC)) +#' +#' adrs <- tribble( +#' ~USUBJID, ~ADTC, ~AVALC, +#' "1", "2020-01-01", "PR", +#' "1", "2020-02-01", "CR", +#' "1", "2020-02-16", "NE", +#' "1", "2020-03-01", "CR", +#' "1", "2020-04-01", "SD", +#' "2", "2020-01-01", "SD", +#' "2", "2020-02-01", "PR", +#' "2", "2020-03-01", "SD", +#' "2", "2020-03-13", "CR", +#' "4", "2020-01-01", "PR", +#' "4", "2020-03-01", "NE", +#' "4", "2020-04-01", "NE", +#' "4", "2020-05-01", "PR", +#' "5", "2020-01-01", "PR", +#' "5", "2020-01-10", "PR", +#' "5", "2020-01-20", "PR", +#' "6", "2020-02-06", "PR", +#' "6", "2020-02-16", "CR", +#' "6", "2020-03-30", "PR", +#' "7", "2020-02-06", "PR", +#' "7", "2020-02-16", "CR", +#' "7", "2020-04-01", "NE", +#' "8", "2020-02-16", "PD" +#' ) %>% +#' mutate( +#' ADT = ymd(ADTC), +#' PARAMCD = "OVR", +#' PARAM = "Overall Response by Investigator" +#' ) %>% +#' derive_vars_merged( +#' dataset_add = adsl, +#' by_vars = exprs(USUBJID), +#' new_vars = exprs(TRTSDT) +#' ) +#' +#' derive_extreme_event( +#' adrs, +#' by_vars = exprs(USUBJID), +#' order = exprs(ADT), +#' mode = "first", +#' source_datasets = list(adsl = adsl), +#' events = list( +#' event_joined( +#' description = paste( +#' "CR needs to be confirmed by a second CR at least 28 days later", +#' "at most one NE is acceptable between the two assessments" +#' ), +#' join_vars = exprs(AVALC, ADT), +#' join_type = "after", +#' first_cond = AVALC.join == "CR" & +#' ADT.join >= ADT + 28, +#' condition = AVALC == "CR" & +#' all(AVALC.join %in% c("CR", "NE")) & +#' count_vals(var = AVALC.join, val = "NE") <= 1, +#' set_values_to = exprs( +#' AVALC = "CR" +#' ) +#' ), +#' event_joined( +#' description = paste( +#' "PR needs to be confirmed by a second CR or PR at least 28 days later,", +#' "at most one NE is acceptable between the two assessments" +#' ), +#' join_vars = exprs(AVALC, ADT), +#' join_type = "after", +#' first_cond = AVALC.join %in% c("CR", "PR") & +#' ADT.join >= ADT + 28, +#' condition = AVALC == "PR" & +#' all(AVALC.join %in% c("CR", "PR", "NE")) & +#' count_vals(var = AVALC.join, val = "NE") <= 1, +#' set_values_to = exprs( +#' AVALC = "PR" +#' ) +#' ), +#' event( +#' description = paste( +#' "CR, PR, or SD are considered as SD if occurring at least 28", +#' "after treatment start" +#' ), +#' condition = AVALC %in% c("CR", "PR", "SD") & ADT >= TRTSDT + 28, +#' set_values_to = exprs( +#' AVALC = "SD" +#' ) +#' ), +#' event( +#' condition = AVALC == "PD", +#' set_values_to = exprs( +#' AVALC = "PD" +#' ) +#' ), +#' event( +#' condition = AVALC %in% c("CR", "PR", "SD", "NE"), +#' set_values_to = exprs( +#' AVALC = "NE" +#' ) +#' ), +#' event( +#' description = "set response to MISSING for patients without records in ADRS", +#' dataset_name = "adsl", +#' condition = TRUE, +#' set_values_to = exprs( +#' AVALC = "MISSING" +#' ), +#' keep_source_vars = exprs(TRTSDT) +#' ) +#' ), +#' set_values_to = exprs( +#' PARAMCD = "CBOR", +#' PARAM = "Best Confirmed Overall Response by Investigator" +#' ) +#' ) %>% +#' filter(PARAMCD == "CBOR") +#' derive_extreme_event <- function(dataset, by_vars = NULL, events, order, mode, + source_datasets = NULL, + ignore_event_order = FALSE, check_type = "warning", - set_values_to) { + set_values_to, + keep_source_vars = exprs(everything())) { # Check input parameters assert_vars(by_vars, optional = TRUE) - assert_list_of(events, "event") + assert_list_of(events, "event_def") assert_expr_list(order) assert_data_frame( dataset, required_vars = by_vars ) mode <- assert_character_scalar(mode, values = c("first", "last"), case_sensitive = FALSE) + assert_list_of(source_datasets, "data.frame") + source_names <- names(source_datasets) + events_to_check <- events[map_lgl(events, ~ !is.null(.x$dataset_name))] + if (length(events_to_check) > 0) { + assert_list_element( + list = events_to_check, + element = "dataset_name", + condition = dataset_name %in% source_names, + source_names = source_names, + message_text = paste0( + "The dataset names must be included in the list specified for the ", + "`source_datasets` parameter.\n", + "Following names were provided by `source_datasets`:\n", + enumerate(source_names, quote_fun = squote) + ) + ) + } + + assert_logical_scalar(ignore_event_order) check_type <- assert_character_scalar( check_type, @@ -125,33 +363,77 @@ derive_extreme_event <- function(dataset, case_sensitive = FALSE ) assert_varval_list(set_values_to) + keep_source_vars <- assert_expr_list(keep_source_vars) # Create new observations ## Create a dataset (selected_records) from `events` - condition_ls <- map(events, "condition") - set_values_to_ls <- map(events, "set_values_to") - event_order <- map(seq_len(length(events)), function(x) x) - tmp_event_no <- get_new_tmp_var(dataset, prefix = "tmp_event_no") + event_index <- as.list(seq_along(events)) + if (ignore_event_order) { + tmp_event_no <- NULL + } else { + tmp_event_no <- get_new_tmp_var(dataset, prefix = "tmp_event_no") + } - selected_records_ls <- pmap( - list(condition_ls, set_values_to_ls, event_order), - function(x, y, z) { - dataset %>% - group_by(!!!by_vars) %>% - filter(!!enexpr(x)) %>% - mutate(!!!y, !!tmp_event_no := z) %>% - ungroup() + selected_records_ls <- map2( + events, + event_index, + function(event, index) { + if (is.null(event$dataset_name)) { + data_source <- dataset + } else { + data_source <- source_datasets[[event$dataset_name]] + } + if (is.null(event$order)) { + event_order <- order + } else { + event_order <- event$order + } + if (inherits(event, "event")) { + data_events <- data_source %>% + group_by(!!!by_vars) %>% + filter_if(event$condition) %>% + ungroup() + if (!is.null(event$mode)) { + data_events <- filter_extreme( + data_source, + by_vars = by_vars, + order = event_order, + mode = event$mode + ) + } + } else { + data_events <- filter_joined( + data_source, + by_vars = by_vars, + join_vars = event$join_vars, + join_type = event$join_type, + first_cond = !!event$first_cond, + order = event_order, + filter = !!event$condition + ) + } + if (is.null(event$keep_source_vars)) { + event_keep_source_vars <- keep_source_vars + } else { + event_keep_source_vars <- event$keep_source_vars + } + if (!ignore_event_order) { + data_events <- mutate(data_events, !!tmp_event_no := index) + } + data_events %>% + process_set_values_to(set_values_to = event$set_values_to) %>% + select(!!!event_keep_source_vars, !!tmp_event_no, !!!by_vars, names(event$set_values_to)) } ) selected_records <- bind_rows(selected_records_ls) ## tmp obs number within by_vars and a type of event tmp_obs <- get_new_tmp_var(selected_records) - selected_records_obs <- selected_records %>% + selected_records <- selected_records %>% derive_var_obs_number( new_var = !!tmp_obs, order = order, - by_vars = expr_c(by_vars, expr(!!tmp_event_no)), + by_vars = expr_c(by_vars, tmp_event_no), check_type = check_type ) @@ -161,10 +443,10 @@ derive_extreme_event <- function(dataset, } else { tmp_obs_expr <- expr(desc(!!tmp_obs)) } - new_obs <- selected_records_obs %>% + new_obs <- selected_records %>% filter_extreme( by_vars = by_vars, - order = expr_c(expr(!!tmp_event_no), tmp_obs_expr), + order = expr_c(tmp_event_no, tmp_obs_expr), mode = "first", check_type = check_type ) %>% @@ -180,32 +462,179 @@ derive_extreme_event <- function(dataset, #' The `event` object is used to define events as input for the #' `derive_extreme_event()` function. #' +#' @param dataset_name Dataset name of the dataset to be used as input for the +#' event. The name refers to the dataset specified for `source_datasets` in +#' `derive_extreme_event()`. If the argument is not specified, the input +#' dataset (`dataset`) of `derive_extreme_event()` is used. +#' #' @param condition An unquoted condition for selecting the observations, which -#' will contribute to the extreme event. +#' will contribute to the extreme event. If the condition contains summary +#' functions like `all()`, they are evaluated for each by group separately. +#' +#' *Permitted Values*: an unquoted condition +#' +#' @param mode If specified, the first or last observation with respect to `order` is +#' selected for each by group. +#' +#' *Permitted Values*: `"first"`, `"last"`, `NULL` +#' +#' @param order The specified variables or expressions are used to select the +#' first or last observation if `mode` is specified. +#' +#' *Permitted Values*: list of expressions created by `exprs()`, e.g., +#' `exprs(ADT, desc(AVAL))` or `NULL` #' #' @param set_values_to A named list returned by `exprs()` defining the variables -#' to be set for the extreme answer, e.g. `exprs(PARAMCD = "WSP", -#' PARAM = "Worst Sleeping Problems"`. The values must be a symbol, a -#' character string, a numeric value, or `NA`. +#' to be set for the event, e.g. `exprs(PARAMCD = "WSP", +#' PARAM = "Worst Sleeping Problems")`. The values can be a symbol, a +#' character string, a numeric value, `NA` or an expression. +#' +#' @param keep_source_vars Variables to keep from the source dataset +#' +#' The specified variables are kept for the selected observations. The +#' variables specified for `by_vars` (of `derive_extreme_event()`) and created +#' by `set_values_to` are always kept. +#' +#' *Permitted Values*: A list of expressions where each element is +#' a symbol or a tidyselect expression, e.g., `exprs(VISIT, VISITNUM, +#' starts_with("RS"))`. #' +#' @param description Description of the event +#' +#' The description does not affect the derivations where the event is used. It +#' is intended for documentation only. #' #' @keywords source_specifications #' @family source_specifications #' -#' @seealso [derive_extreme_event()] +#' @seealso [derive_extreme_event()], [event_joined()] #' #' @export #' #' @return An object of class `event` -event <- function(condition, - set_values_to = NULL) { +event <- function(dataset_name = NULL, + condition = NULL, + mode = NULL, + order = NULL, + set_values_to = NULL, + keep_source_vars = NULL, + description = NULL) { out <- list( + description = assert_character_scalar(description, optional = TRUE), + dataset_name = assert_character_scalar(dataset_name, optional = TRUE), condition = assert_filter_cond(enexpr(condition), optional = TRUE), - set_values_to = assert_varval_list( + mode = assert_character_scalar( + mode, + values = c("first", "last"), + case_sensitive = FALSE, + optional = TRUE + ), + order = assert_expr_list(order, optional = TRUE), + set_values_to = assert_expr_list( set_values_to, + named = TRUE, optional = TRUE - ) + ), + keep_source_vars = assert_expr_list(keep_source_vars, optional = TRUE) + ) + class(out) <- c("event", "event_def", "source", "list") + out +} + +#' Create a `event_joined` Object +#' +#' @description +#' +#' The `event_joined` object is used to define events as input for the +#' `derive_extreme_event()` function. This object should be used if the event +#' does not depend on a single observation of the source dataset but on multiple +#' observations. For example, if the event needs to be confirmed by a second +#' observation of the source dataset. +#' +#' The events are selected by calling `filter_joined()`. See its documentation +#' for more details. +#' +#' @param dataset_name Dataset name of the dataset to be used as input for the +#' event. The name refers to the dataset specified for `source_datasets` in +#' `derive_extreme_event()`. If the argument is not specified, the input +#' dataset (`dataset`) of `derive_extreme_event()` is used. +#' +#' @param condition An unquoted condition for selecting the observations, which +#' will contribute to the extreme event. +#' +#' *Permitted Values*: an unquoted condition +#' +#' @param join_vars Variables to keep from joined dataset +#' +#' The variables needed from the other observations should be specified for +#' this parameter. The specified variables are added to the joined dataset +#' with suffix ".join". For example to select all observations with `AVALC == +#' "Y"` and `AVALC == "Y"` for at least one subsequent visit `join_vars = +#' exprs(AVALC, AVISITN)` and `filter = AVALC == "Y" & AVALC.join == "Y" & +#' AVISITN < AVISITN.join` could be specified. +#' +#' The `*.join` variables are not included in the output dataset. +#' +#' @param join_type Observations to keep after joining +#' +#' The argument determines which of the joined observations are kept with +#' respect to the original observation. For example, if `join_type = +#' "after"` is specified all observations after the original observations are +#' kept. +#' +#' *Permitted Values:* `"before"`, `"after"`, `"all"` +#' +#' @param first_cond Condition for selecting range of data +#' +#' If this argument is specified, the other observations are restricted up to +#' the first observation where the specified condition is fulfilled. If the +#' condition is not fulfilled for any of the subsequent observations, all +#' observations are removed. +#' +#' @param order If specified, the specified variables or expressions are used to +#' select the first observation. +#' +#' *Permitted Values*: list of expressions created by `exprs()`, e.g., +#' `exprs(ADT, desc(AVAL))` or `NULL` +#' +#' @inheritParams event +#' +#' @keywords source_specifications +#' @family source_specifications +#' +#' @seealso [derive_extreme_event()], [event()] +#' +#' @export +#' +#' @return An object of class `event_joined` +event_joined <- function(dataset_name = NULL, + condition, + order = NULL, + join_vars, + join_type, + first_cond = NULL, + set_values_to = NULL, + keep_source_vars = NULL, + description = NULL) { + out <- list( + description = assert_character_scalar(description, optional = TRUE), + dataset_name = assert_character_scalar(dataset_name, optional = TRUE), + condition = assert_filter_cond(enexpr(condition), optional = TRUE), + order = assert_expr_list(order, optional = TRUE), + join_vars = assert_vars(join_vars), + join_type = assert_character_scalar( + join_type, + values = c("before", "after", "all"), + case_sensitive = FALSE + ), + first_cond = assert_filter_cond(enexpr(first_cond), optional = TRUE), + set_values_to = assert_expr_list( + set_values_to, + named = TRUE, + optional = TRUE + ), + keep_source_vars = assert_expr_list(keep_source_vars, optional = TRUE) ) - class(out) <- c("event", "source", "list") + class(out) <- c("event_joined", "event_def", "source", "list") out } diff --git a/R/derive_extreme_records.R b/R/derive_extreme_records.R index a637ee4674..6f46196df0 100644 --- a/R/derive_extreme_records.R +++ b/R/derive_extreme_records.R @@ -95,6 +95,14 @@ #' #' *Permitted Values*: a condition #' +#' @param keep_source_vars Variables to be kept in the new records +#' +#' A named list or tidyselect expressions created by `exprs()` defining the +#' variables to be kept for the new records. The variables specified for +#' `by_vars` and `set_values_to` need not be specified here as they are kept +#' automatically. +#' +#' #' @inheritParams filter_extreme #' @inheritParams derive_summary_records #' @@ -109,6 +117,9 @@ #' but not in the selected records are added. #' 1. The variables specified by the `set_values_to` argument are added to #' the selected observations. +#' 1. The variables specified by the `keep_source_vars` argument are selected +#' along with the variables specified in `by_vars` and `set_values_to` +#' arguments. #' 1. The observations are added to input dataset. #' #' @@ -138,12 +149,14 @@ #' # Add a new record for each USUBJID storing the minimum value (first AVAL). #' # If multiple records meet the minimum criterion, take the first value by #' # AVISITN. Set AVISITN = 97 and DTYPE = MINIMUM for these new records. +#' # Specify the variables that need to be kept in the new records. #' derive_extreme_records( #' adlb, #' by_vars = exprs(USUBJID), #' order = exprs(AVAL, AVISITN), #' mode = "first", #' filter_add = !is.na(AVAL), +#' keep_source_vars = exprs(AVAL), #' set_values_to = exprs( #' AVISITN = 97, #' DTYPE = "MINIMUM" @@ -254,10 +267,11 @@ derive_extreme_records <- function(dataset = NULL, exist_flag = NULL, true_value = "Y", false_value = "N", + keep_source_vars = exprs(everything()), set_values_to, filter) { if (!missing(filter)) { - deprecate_warn( + deprecate_stop( "0.11.0", "derive_extreme_records(filter = )", "derive_extreme_records(filter_add = )" @@ -268,6 +282,8 @@ derive_extreme_records <- function(dataset = NULL, # Check input arguments assert_vars(by_vars, optional = is.null(dataset_ref)) assert_expr_list(order, optional = TRUE) + assert_expr_list(keep_source_vars, optional = TRUE) + assert_data_frame( dataset, required_vars = expr_c( @@ -333,10 +349,12 @@ derive_extreme_records <- function(dataset = NULL, new_obs <- new_add_obs } - new_obs <- process_set_values_to( - new_obs, - set_values_to = set_values_to - ) + new_obs <- new_obs %>% + process_set_values_to( + set_values_to = set_values_to + ) %>% + select(!!!by_vars, names(set_values_to), !!!keep_source_vars) + # Create output dataset bind_rows(dataset, new_obs) diff --git a/R/derive_joined.R b/R/derive_joined.R index ef6c58aa4b..1e0f5cff48 100644 --- a/R/derive_joined.R +++ b/R/derive_joined.R @@ -353,6 +353,19 @@ derive_vars_joined <- function(dataset, if (is.null(new_vars)) { new_vars <- chr2vars(colnames(dataset_add)) } + preexisting_vars <- chr2vars(colnames(dataset)) + preexisting_vars_no_by_vars <- preexisting_vars[which(!(preexisting_vars %in% by_vars))] + duplicates <- intersect(replace_values_by_names(new_vars), preexisting_vars_no_by_vars) + if (length(duplicates) > 0) { + err_msg <- sprintf( + paste( + "The following columns in `dataset_add` have naming conflicts with `dataset`,\n", + "please make the appropriate modifications to `new_vars`, with respect to:\n%s" + ), + enumerate(vars2chr(duplicates)) + ) + abort(err_msg) + } # number observations of the input dataset to get a unique key # (by_vars and tmp_obs_nr) @@ -371,7 +384,7 @@ derive_vars_joined <- function(dataset, filter_if(filter_add) %>% select( !!!by_vars, - !!!chr2vars(names(order)), + !!!replace_values_by_names(extract_vars(order)), !!!replace_values_by_names(join_vars), !!!intersect(unname(extract_vars(new_vars)), chr2vars(colnames(dataset_add))) ) @@ -410,6 +423,7 @@ derive_vars_joined <- function(dataset, by_vars = exprs(!!!by_vars_left, !!tmp_obs_nr), new_vars = add_suffix_to_vars(new_vars, vars = common_vars, suffix = ".join"), missing_values = missing_values, + check_type = check_type, duplicate_msg = paste( paste( "After applying `filter_join` the joined dataset contains more", diff --git a/R/derive_locf_records.R b/R/derive_locf_records.R index e4a2e6ca2c..ad13927788 100644 --- a/R/derive_locf_records.R +++ b/R/derive_locf_records.R @@ -8,14 +8,17 @@ #' The columns specified by the `by_vars`, `analysis_var`, `order`, #' `keep_vars` parameters are expected. #' -#' @param dataset_expected_obs Expected observations dataset +#' @param dataset_expected_obs *Deprecated*, please use `dataset_ref` instead. +#' +#' @param dataset_ref Expected observations dataset #' #' Data frame with all the combinations of `PARAMCD`, `PARAM`, `AVISIT`, #' `AVISITN`, ... which are expected in the dataset is expected. #' +#' #' @param by_vars Grouping variables #' -#' For each group defined by `by_vars` those observations from `dataset_expected_obs` +#' For each group defined by `by_vars` those observations from `dataset_ref` #' are added to the output dataset which do not have a corresponding observation #' in the input dataset or for which `analysis_var` is `NA` for the corresponding observation #' in the input dataset. @@ -40,7 +43,7 @@ #' @author G Gayatri #' #' @details For each group (with respect to the variables specified for the -#' by_vars parameter) those observations from dataset_expected_obs are added to +#' by_vars parameter) those observations from `dataset_ref` are added to #' the output dataset #' - which do not have a corresponding observation in the input dataset or #' - for which `analysis_var` is NA for the corresponding observation in the input dataset. @@ -101,8 +104,8 @@ #' ) #' #' derive_locf_records( -#' data = advs, -#' dataset_expected_obs = advs_expected_obsv, +#' dataset = advs, +#' dataset_ref = advs_expected_obsv, #' by_vars = exprs(STUDYID, USUBJID, PARAMCD), #' order = exprs(AVISITN, AVISIT), #' keep_vars = exprs(PARAMN) @@ -110,10 +113,21 @@ #' derive_locf_records <- function(dataset, dataset_expected_obs, + dataset_ref, by_vars, analysis_var = AVAL, order, keep_vars = NULL) { + if (!missing(dataset_expected_obs)) { + deprecate_warn( + "0.12.0", + "derive_locf_records(dataset_expected_obs = )", + "derive_locf_records(dataset_ref = )" + ) + assert_data_frame(dataset_expected_obs) + dataset_ref <- dataset_expected_obs + } + #### Input Checking #### analysis_var <- assert_symbol(enexpr(analysis_var)) @@ -123,27 +137,27 @@ derive_locf_records <- function(dataset, assert_expr_list(order) # Check by_vars and order variables in input datasets - assert_data_frame(dataset_expected_obs) + assert_data_frame(dataset_ref) assert_data_frame( dataset, required_vars = expr_c( by_vars, analysis_var, extract_vars(order), keep_vars, - chr2vars(colnames(dataset_expected_obs)) + chr2vars(colnames(dataset_ref)) ) ) - #### Prepping 'dataset_expected_obs' #### + #### Prepping 'dataset_ref' #### # Get the IDs from input dataset for which the expected observations are to be added ids <- dataset %>% - select(!!!setdiff(by_vars, chr2vars(colnames(dataset_expected_obs)))) %>% + select(!!!setdiff(by_vars, chr2vars(colnames(dataset_ref)))) %>% distinct() exp_obsv <- ids %>% - crossing(dataset_expected_obs) + crossing(dataset_ref) diff --git a/R/derive_merged.R b/R/derive_merged.R index 0b46d62e29..428209efaa 100644 --- a/R/derive_merged.R +++ b/R/derive_merged.R @@ -456,67 +456,6 @@ derive_vars_merged <- function(dataset, #' #' @export #' -#' @examples -#' library(dplyr, warn.conflicts = FALSE) -#' -#' vs <- tribble( -#' ~STUDYID, ~DOMAIN, ~USUBJID, ~VISIT, ~VSTESTCD, ~VSSTRESN, ~VSSEQ, ~VSDTC, -#' "PILOT01", "VS", "04-1127", "SCREENING", "HEIGHT", 165.1, 43, "2013-09-16", -#' "PILOT01", "VS", "04-1127", "SCREENING", "WEIGHT", 42.87, 142, "2013-09-16", -#' "PILOT01", "VS", "04-1127", "BASELINE", "WEIGHT", 41.05, 143, "2013-10-02", -#' "PILOT01", "VS", "04-1127", "WEEK 2", "WEIGHT", 42.64, 144, "2013-10-16", -#' "PILOT01", "VS", "04-1127", "WEEK 4", "WEIGHT", 41.73, 145, "2013-10-30", -#' "PILOT01", "VS", "04-1127", "WEEK 26", "WEIGHT", 43.09, 152, "2014-03-31", -#' "PILOT01", "VS", "06-1049", "SCREENING", "HEIGHT", 167.64, 28, "2013-04-30", -#' "PILOT01", "VS", "06-1049", "SCREENING", "WEIGHT", 57.61, 92, "2013-04-30", -#' "PILOT01", "VS", "06-1049", "BASELINE", "WEIGHT", 57.83, 93, "2013-05-14", -#' "PILOT01", "VS", "06-1049", "WEEK 2", "WEIGHT", 58.29, 94, "2013-05-28", -#' "PILOT01", "VS", "06-1049", "WEEK 4", "WEIGHT", 58.97, 95, "2013-06-11" -#' ) -#' -#' dm <- tribble( -#' ~STUDYID, ~DOMAIN, ~USUBJID, ~AGE, ~AGEU, -#' "PILOT01", "DM", "01-1057", 59, "YEARS", -#' "PILOT01", "DM", "04-1127", 84, "YEARS", -#' "PILOT01", "DM", "06-1049", 60, "YEARS" -#' ) -#' wgt_cat <- function(wgt) { -#' case_when( -#' wgt < 50 ~ "low", -#' wgt > 90 ~ "high", -#' TRUE ~ "normal" -#' ) -#' } -#' -#' derive_var_merged_cat( -#' dm, -#' dataset_add = vs, -#' by_vars = exprs(STUDYID, USUBJID), -#' order = exprs(VSDTC, VSSEQ), -#' filter_add = VSTESTCD == "WEIGHT" & substr(VISIT, 1, 9) == "SCREENING", -#' new_var = WGTBLCAT, -#' source_var = VSSTRESN, -#' cat_fun = wgt_cat, -#' mode = "last" -#' ) %>% -#' select(STUDYID, USUBJID, AGE, AGEU, WGTBLCAT) -#' -#' -#' -#' # defining a value for missing VS data -#' derive_var_merged_cat( -#' dm, -#' dataset_add = vs, -#' by_vars = exprs(STUDYID, USUBJID), -#' order = exprs(VSDTC, VSSEQ), -#' filter_add = VSTESTCD == "WEIGHT" & substr(VISIT, 1, 9) == "SCREENING", -#' new_var = WGTBLCAT, -#' source_var = VSSTRESN, -#' cat_fun = wgt_cat, -#' mode = "last", -#' missing_value = "MISSING" -#' ) %>% -#' select(STUDYID, USUBJID, AGE, AGEU, WGTBLCAT) derive_var_merged_cat <- function(dataset, dataset_add, by_vars, @@ -527,22 +466,7 @@ derive_var_merged_cat <- function(dataset, filter_add = NULL, mode = NULL, missing_value = NA_character_) { - deprecate_warn("0.11.0", "derive_var_merged_cat()", "derive_vars_merged()") - new_var <- assert_symbol(enexpr(new_var)) - source_var <- assert_symbol(enexpr(source_var)) - filter_add <- assert_filter_cond(enexpr(filter_add), optional = TRUE) - assert_data_frame(dataset_add, required_vars = expr_c(by_vars, source_var)) - - derive_vars_merged( - dataset, - dataset_add = dataset_add, - filter_add = !!filter_add, - by_vars = by_vars, - order = order, - new_vars = exprs(!!new_var := {{ cat_fun }}(!!source_var)), - mode = mode, - missing_values = exprs(!!new_var := !!missing_value) - ) + deprecate_stop("0.11.0", "derive_var_merged_cat()", "derive_vars_merged()") } #' Merge an Existence Flag @@ -782,40 +706,7 @@ derive_var_merged_character <- function(dataset, filter_add = NULL, mode = NULL, missing_value = NA_character_) { - deprecate_warn("0.11.0", "derive_var_merged_character()", "derive_vars_merged()") - - new_var <- assert_symbol(enexpr(new_var)) - source_var <- assert_symbol(enexpr(source_var)) - case <- - assert_character_scalar( - case, - values = c("lower", "upper", "title"), - case_sensitive = FALSE, - optional = TRUE - ) - filter_add <- assert_filter_cond(enexpr(filter_add), optional = TRUE) - assert_data_frame(dataset_add, required_vars = expr_c(by_vars, source_var)) - assert_character_scalar(missing_value) - - if (is.null(case)) { - trans <- expr(!!source_var) - } else if (case == "lower") { - trans <- expr(str_to_lower(!!source_var)) - } else if (case == "upper") { - trans <- expr(str_to_upper(!!source_var)) - } else if (case == "title") { - trans <- expr(str_to_title(!!source_var)) - } - derive_vars_merged( - dataset, - dataset_add = dataset_add, - by_vars = by_vars, - order = order, - new_vars = exprs(!!new_var := !!trans), - filter_add = !!filter_add, - mode = mode, - missing_values = exprs(!!new_var := !!missing_value) - ) + deprecate_stop("0.11.0", "derive_var_merged_character()", "derive_vars_merged()") } diff --git a/R/derive_param_computed.R b/R/derive_param_computed.R index 85cfc6ba18..ac5b43314c 100644 --- a/R/derive_param_computed.R +++ b/R/derive_param_computed.R @@ -59,6 +59,8 @@ #' #' @param analysis_var Analysis variable #' +#' `r lifecycle::badge("deprecated")` Please use `set_values_to` instead. +#' #' The specified variable is set to the value of `analysis_value` for the new #' observations. #' @@ -105,6 +107,8 @@ #' #' @param analysis_value Definition of the analysis value #' +#' `r lifecycle::badge("deprecated")` Please use `set_values_to` instead. +#' #' An expression defining the analysis value (`AVAL`) of the new parameter is #' expected. The values of variables of the parameters specified by #' `parameters` can be accessed using `.`, @@ -117,21 +121,35 @@ #' @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. +#' observations. The values of variables of the parameters specified by +#' `parameters` can be accessed using `.`. For +#' example +#' ``` +#' exprs( +#' AVAL = (AVAL.SYSBP + 2 * AVAL.DIABP) / 3, +#' PARAMCD = "MAP" +#' ) +#' ``` +#' defines the analysis value and parameter code for the new parameter. +#' +#' Variable names in the expression must not contain more than one dot. #' #' *Permitted Values:* List of variable-value pairs #' +#' @param keep_nas Keep observations with `NA`s +#' +#' If the argument is set to `TRUE`, observations are added even if some of +#' the values contributing to the computed value are `NA`. +#' #' @details For each group (with respect to the variables specified for the #' `by_vars` parameter) an observation is added to the output dataset if the #' filtered input dataset (`dataset`) or the additional dataset #' (`dataset_add`) contains exactly one observation for each parameter code #' specified for `parameters`. #' -#' For the new observations `AVAL` is set to the value specified by -#' `analysis_value` and the variables specified for `set_values_to` are set to -#' the provided values. The values of the other variables of the input dataset -#' are set to `NA`. +#' For the new observations the variables specified for `set_values_to` are +#' set to the provided values. The values of the other variables of the input +#' dataset are set to `NA`. #' #' @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`. @@ -144,6 +162,8 @@ #' #' @examples #' library(tibble) +#' library(dplyr) +#' library(lubridate) #' #' # Example 1: Derive MAP #' advs <- tribble( @@ -162,8 +182,8 @@ #' advs, #' by_vars = exprs(USUBJID, VISIT), #' parameters = c("SYSBP", "DIABP"), -#' analysis_value = (AVAL.SYSBP + 2 * AVAL.DIABP) / 3, #' set_values_to = exprs( +#' AVAL = (AVAL.SYSBP + 2 * AVAL.DIABP) / 3, #' PARAMCD = "MAP", #' PARAM = "Mean Arterial Pressure (mmHg)", #' AVALU = "mmHg" @@ -187,8 +207,8 @@ #' advs, #' by_vars = exprs(USUBJID, VISIT), #' parameters = "WEIGHT", -#' analysis_value = AVAL.WEIGHT / (AVAL.HEIGHT / 100)^2, #' set_values_to = exprs( +#' AVAL = AVAL.WEIGHT / (AVAL.HEIGHT / 100)^2, #' PARAMCD = "BMI", #' PARAM = "Body Mass Index (kg/m^2)", #' AVALU = "kg/m^2" @@ -198,7 +218,7 @@ #' ) #' #' # Example 3: Using data from an additional dataset and other variables than AVAL -#' qs <- tibble::tribble( +#' qs <- tribble( #' ~USUBJID, ~AVISIT, ~QSTESTCD, ~QSORRES, ~QSSTRESN, #' "1", "WEEK 2", "CHSF112", NA, 1, #' "1", "WEEK 2", "CHSF113", "Yes", NA, @@ -208,29 +228,58 @@ #' "1", "WEEK 4", "CHSF114", NA, 1 #' ) #' -#' adchsf <- tibble::tribble( -#' ~USUBJID, ~AVISIT, ~PARAMCD, ~QSORRES, ~QSSTRESN, ~AVAL, -#' "1", "WEEK 2", "CHSF12", NA, 1, 6, -#' "1", "WEEK 2", "CHSF14", NA, 1, 6, -#' "1", "WEEK 4", "CHSF12", NA, 2, 12, -#' "1", "WEEK 4", "CHSF14", NA, 1, 6 -#' ) +#' adchsf <- tribble( +#' ~USUBJID, ~AVISIT, ~PARAMCD, ~QSSTRESN, ~AVAL, +#' "1", "WEEK 2", "CHSF12", 1, 6, +#' "1", "WEEK 2", "CHSF14", 1, 6, +#' "1", "WEEK 4", "CHSF12", 2, 12, +#' "1", "WEEK 4", "CHSF14", 1, 6 +#' ) %>% +#' mutate(QSORRES = NA_character_) #' #' derive_param_computed( #' adchsf, #' dataset_add = qs, #' by_vars = exprs(USUBJID, AVISIT), #' parameters = exprs(CHSF12, CHSF13 = QSTESTCD %in% c("CHSF113", "CHSF213"), CHSF14), -#' analysis_value = case_when( -#' QSORRES.CHSF13 == "Not applicable" ~ 0, -#' QSORRES.CHSF13 == "Yes" ~ 38, -#' QSORRES.CHSF13 == "No" ~ if_else( -#' QSSTRESN.CHSF12 > QSSTRESN.CHSF14, -#' 25, -#' 0 -#' ) +#' set_values_to = exprs( +#' AVAL = case_when( +#' QSORRES.CHSF13 == "Not applicable" ~ 0, +#' QSORRES.CHSF13 == "Yes" ~ 38, +#' QSORRES.CHSF13 == "No" ~ if_else( +#' QSSTRESN.CHSF12 > QSSTRESN.CHSF14, +#' 25, +#' 0 +#' ) +#' ), +#' PARAMCD = "CHSF13" +#' ) +#' ) +#' +#' # Example 4: Computing more than one variable +#' adlb_tbilialk <- tribble( +#' ~USUBJID, ~PARAMCD, ~AVALC, ~ADTM, ~ADTF, +#' "1", "ALK2", "Y", "2021-05-13", NA_character_, +#' "1", "TBILI2", "Y", "2021-06-30", "D", +#' "2", "ALK2", "Y", "2021-12-31", "M", +#' "2", "TBILI2", "N", "2021-11-11", NA_character_, +#' "3", "ALK2", "N", "2021-04-03", NA_character_, +#' "3", "TBILI2", "N", "2021-04-04", NA_character_ +#' ) %>% +#' mutate(ADTM = ymd(ADTM)) +#' +#' derive_param_computed( +#' dataset_add = adlb_tbilialk, +#' by_vars = exprs(USUBJID), +#' parameters = c("ALK2", "TBILI2"), +#' set_values_to = exprs( +#' AVALC = if_else(AVALC.TBILI2 == "Y" & AVALC.ALK2 == "Y", "Y", "N"), +#' ADTM = pmax(ADTM.TBILI2, ADTM.ALK2), +#' ADTF = if_else(ADTM == ADTM.TBILI2, ADTF.TBILI2, ADTF.ALK2), +#' PARAMCD = "TB2AK2", +#' PARAM = "TBILI > 2 times ULN and ALKPH <= 2 times ULN" #' ), -#' set_values_to = exprs(PARAMCD = "CHSF13") +#' keep_nas = TRUE #' ) derive_param_computed <- function(dataset = NULL, dataset_add = NULL, @@ -241,9 +290,9 @@ derive_param_computed <- function(dataset = NULL, set_values_to, filter = NULL, constant_by_vars = NULL, - constant_parameters = NULL) { + constant_parameters = NULL, + keep_nas = FALSE) { assert_vars(by_vars) - analysis_var <- assert_symbol(enexpr(analysis_var)) assert_vars(constant_by_vars, optional = TRUE) assert_data_frame(dataset, required_vars = by_vars, optional = TRUE) assert_data_frame(dataset_add, optional = TRUE) @@ -252,7 +301,26 @@ derive_param_computed <- function(dataset = NULL, if (!is.null(set_values_to$PARAMCD) && !is.null(dataset)) { assert_param_does_not_exist(dataset, set_values_to$PARAMCD) } - analysis_value <- enexpr(analysis_value) + assert_logical_scalar(keep_nas) + ### BEGIN DEPRECATION + if (!missing(analysis_var)) { + deprecate_warn( + "0.12.0", + "derive_param_computed(analysis_var = )", + "derive_param_computed(set_values_to = )" + ) + } + analysis_var <- assert_symbol(enexpr(analysis_var)) + + if (!missing(analysis_value)) { + deprecate_warn( + "0.12.0", + "derive_param_computed(analysis_value = )", + "derive_param_computed(set_values_to = )" + ) + set_values_to <- exprs(!!analysis_var := !!enexpr(analysis_value), !!!set_values_to) + } + ### END DEPRECATION parameters <- assert_parameters_argument(parameters) constant_parameters <- assert_parameters_argument(constant_parameters, optional = TRUE) @@ -270,7 +338,7 @@ derive_param_computed <- function(dataset = NULL, data_source, by_vars = by_vars, parameters = parameters, - analysis_value = !!analysis_value, + set_values_to = set_values_to, filter = !!filter ) hori_data <- hori_return[["hori_data"]] @@ -284,7 +352,7 @@ derive_param_computed <- function(dataset = NULL, data_source, by_vars = constant_by_vars, parameters = constant_parameters, - analysis_value = !!analysis_value, + set_values_to = set_values_to, filter = !!filter )[["hori_data"]] @@ -296,13 +364,17 @@ derive_param_computed <- function(dataset = NULL, } # add analysis value (AVAL) and parameter variables, e.g., PARAMCD - hori_data <- hori_data %>% + if (!keep_nas) { # keep only observations where all analysis values are available - filter(!!!parse_exprs(map_chr( - analysis_vars_chr, - ~ str_c("!is.na(", .x, ")") - ))) %>% - process_set_values_to(exprs(!!analysis_var := !!analysis_value)) %>% + hori_data <- filter( + hori_data, + !!!parse_exprs(map_chr( + analysis_vars_chr, + ~ str_c("!is.na(", .x, ")") + )) + ) + } + hori_data <- hori_data %>% process_set_values_to(set_values_to) %>% select(-all_of(analysis_vars_chr[str_detect(analysis_vars_chr, "\\.")])) @@ -323,8 +395,7 @@ derive_param_computed <- function(dataset = NULL, #' @return The `parameters` argument (converted to a list of symbol, if it is a #' character vector) #' -#' @keywords other_advanced -#' @family other_advanced +#' @keywords internal assert_parameters_argument <- function(parameters, optional = TRUE) { assert_logical_scalar(optional) if (optional && is.null(parameters)) { @@ -370,14 +441,14 @@ assert_parameters_argument <- function(parameters, optional = TRUE) { #' #' *Permitted Values:* A character vector of `PARAMCD` values or a list of expressions #' -#' @param analysis_value +#' @param set_values_to #' #' All variables of the form `.` like `AVAL.WEIGHT` are #' added to the input dataset. They are set to the value of the variable for #' the parameter. E.g., `AVAL.WEIGHT` is set to the value of `AVAL` where #' `PARAMCD == "WEIGHT"`. #' -#' *Permitted Values:* An unquoted expression +#' *Permitted Values:* A list of expressions #' #' @param filter Filter condition used for restricting the input dataset #' @@ -390,17 +461,16 @@ assert_parameters_argument <- function(parameters, optional = TRUE) { #' variables specified for `by_vars` and all variables of the form #' `.` occurring in `analysis_value`. #' -#' @keywords other_advanced -#' @family other_advanced +#' @keywords internal get_hori_data <- function(dataset, by_vars, parameters, - analysis_value, + set_values_to, filter) { assert_vars(by_vars) assert_data_frame(dataset, required_vars = by_vars) parameters <- assert_parameters_argument(parameters) - analysis_value <- enexpr(analysis_value) + assert_expr_list(set_values_to) filter <- assert_filter_cond(enexpr(filter), optional = TRUE) # determine parameter values @@ -468,13 +538,13 @@ get_hori_data <- function(dataset, ) # horizontalize data, e.g., AVAL for PARAMCD = "PARAMx" -> AVAL.PARAMx - analysis_vars <- extract_vars(analysis_value) + analysis_vars <- flatten(map(unname(set_values_to), extract_vars)) analysis_vars_chr <- vars2chr(analysis_vars) multi_dot_names <- str_count(analysis_vars_chr, "\\.") > 1 if (any(multi_dot_names)) { abort( paste( - "The `analysis_value` argument contains variable names with more than on dot:", + "The `set_values_to` argument contains variable names with more than on dot:", enumerate(analysis_vars_chr[multi_dot_names]), sep = "\n" ) @@ -507,6 +577,6 @@ get_hori_data <- function(dataset, list( hori_data = bind_rows(hori_data) %>% select(!!!by_vars, any_of(analysis_vars_chr)), - analysis_vars_chr = analysis_vars_chr + analysis_vars_chr = analysis_vars_chr[str_detect(analysis_vars_chr, "\\.")] ) } diff --git a/R/derive_param_doseint.R b/R/derive_param_doseint.R index 82ec6a5384..016af0088b 100644 --- a/R/derive_param_doseint.R +++ b/R/derive_param_doseint.R @@ -63,6 +63,8 @@ #' 2. If the planned dose (`tpadm_code`) is 0 and the administered dose #' (`tadm_code`) is > 0, 100 is returned. #' +#' @inheritParams derive_param_map +#' #' @inheritParams derive_param_computed #' #' @@ -129,6 +131,8 @@ derive_param_doseint <- function(dataset, aval_tadm <- sym(paste0("AVAL.", tadm_code)) aval_tpdm <- sym(paste0("AVAL.", tpadm_code)) + analysis_value <- exprs(AVAL = !!aval_tadm / !!aval_tpdm * 100) + # handle 0 doses planned if needed if (zero_doses == "100") { update_aval <- exprs( @@ -149,7 +153,6 @@ derive_param_doseint <- function(dataset, filter = !!filter, parameters = c(tadm_code, tpadm_code), by_vars = by_vars, - analysis_value = (!!aval_tadm / !!aval_tpdm * 100), - set_values_to = expr_c(set_values_to, update_aval) + set_values_to = expr_c(set_values_to, analysis_value, update_aval) ) } diff --git a/R/derive_param_exist_flag.R b/R/derive_param_exist_flag.R index 786c4ec7ef..cd5a044202 100644 --- a/R/derive_param_exist_flag.R +++ b/R/derive_param_exist_flag.R @@ -184,21 +184,17 @@ derive_param_exist_flag <- function(dataset = NULL, subject_keys) { ### BEGIN DEPRECATION if (!missing(dataset_adsl)) { - deprecate_warn( + deprecate_stop( "0.11.0", "derive_param_exist_flag(dataset_adsl = )", "derive_param_exit_flag(dataset_ref = )" ) - # assign deprecated argument to new variable - dataset_ref <- dataset_adsl } if (!missing(subject_keys)) { - deprecate_warn( + deprecate_stop( "0.11.0", "derive_param_exist_flag(subject_keys = )", "derive_param_exit_flag(by_vars = )" ) - # assign deprecated argument to new variable - by_vars <- subject_keys } ### END DEPRECATION @@ -223,12 +219,11 @@ derive_param_exist_flag <- function(dataset = NULL, if (!missing(aval_fun)) { assert_function(aval_fun) - deprecate_warn( + deprecate_stop( "0.11.0", "derive_param_exist_flag(aval_fun = )", "derive_param_exist_flag(set_values_to = )" ) - set_values_to <- exprs(!!!set_values_to, AVAL = aval_fun(AVALC)) } # Create new observations diff --git a/R/derive_param_extreme_event.R b/R/derive_param_extreme_event.R index 0c240264c0..0b3048e61c 100644 --- a/R/derive_param_extreme_event.R +++ b/R/derive_param_extreme_event.R @@ -124,47 +124,5 @@ derive_param_extreme_event <- function(dataset = NULL, subject_keys = get_admiral_option("subject_keys"), set_values_to, check_type = "warning") { - deprecate_warn("0.11.0", "derive_param_extreme_event()", "derive_extreme_records()") - - # Check input arguments - filter_source <- assert_filter_cond(enexpr(filter_source)) - assert_vars(subject_keys) - assert_expr_list(order, optional = TRUE) - assert_data_frame(dataset_source, - required_vars = exprs(!!!subject_keys, !!!extract_vars(order)) - ) - new_var <- assert_symbol(enexpr(new_var), optional = TRUE) - assert_same_type(true_value, false_value) - assert_data_frame(dataset, optional = TRUE) - assert_data_frame(dataset_adsl, required_vars = subject_keys) - check_type <- - assert_character_scalar( - check_type, - values = c("none", "warning", "error"), - case_sensitive = FALSE - ) - mode <- assert_character_scalar( - mode, - values = c("first", "last"), - case_sensitive = FALSE - ) - assert_varval_list(set_values_to, required_elements = "PARAMCD") - if (!is.null(set_values_to$PARAMCD) && !is.null(dataset)) { - assert_param_does_not_exist(dataset, set_values_to$PARAMCD) - } - - derive_extreme_records( - dataset, - dataset_add = dataset_source, - dataset_ref = dataset_adsl, - by_vars = subject_keys, - order = order, - mode = mode, - filter_add = !!filter_source, - check_type = check_type, - exist_flag = !!new_var, - true_value = true_value, - false_value = false_value, - set_values_to = set_values_to - ) + deprecate_stop("0.11.0", "derive_param_extreme_event()", "derive_extreme_records()") } diff --git a/R/derive_param_framingham.R b/R/derive_param_framingham.R index e14d9610b0..7f10bb234f 100644 --- a/R/derive_param_framingham.R +++ b/R/derive_param_framingham.R @@ -271,7 +271,9 @@ derive_param_framingham <- function(dataset, diabetfl, trthypfl ), - analysis_value = !!analysis_value, - set_values_to = set_values_to + set_values_to = exprs( + AVAL = !!analysis_value, + !!!set_values_to + ) ) } diff --git a/R/derive_param_tte.R b/R/derive_param_tte.R index bbc9526fad..9b5069813d 100644 --- a/R/derive_param_tte.R +++ b/R/derive_param_tte.R @@ -8,7 +8,7 @@ #' #' @param dataset_adsl ADSL input dataset #' -#' The variables specified for `start_date`, `start_imputation_flag`, and +#' The variables specified for `start_date`, and #' `subject_keys` are expected. #' #' @param source_datasets Source datasets @@ -35,9 +35,6 @@ #' If the event or censoring date is before the origin date, `ADT` is set to #' the origin date. #' -#' If the specified variable is imputed, the corresponding date imputation -#' flag must specified for `start_imputation_flag`. -#' #' @param event_conditions Sources and conditions defining events #' #' A list of `event_source()` objects is expected. @@ -112,8 +109,8 @@ #' selected. Otherwise the censoring observation is selected. #' #' Finally: -#' 1. The variables specified for `start_date` and `start_imputation_flag` are -#' joined from the ADSL dataset. Only subjects in both datasets are kept, +#' 1. The variable specified for `start_date` is joined from the +#' ADSL dataset. Only subjects in both datasets are kept, #' i.e., subjects with both an event or censoring and an observation in #' `dataset_adsl`. #' 1. The variables as defined by the `set_values_to` parameter are added. diff --git a/R/derive_param_wbc_abs.R b/R/derive_param_wbc_abs.R index 01c96ff572..60ec791326 100644 --- a/R/derive_param_wbc_abs.R +++ b/R/derive_param_wbc_abs.R @@ -159,8 +159,10 @@ derive_param_wbc_abs <- function(dataset, diff_code ), by_vars = by_vars, - analysis_value = !!analysis_value, - set_values_to = set_values_to + set_values_to = exprs( + AVAL = !!analysis_value, + !!!set_values_to + ) ) %>% filter(PARAMCD == !!set_values_to$PARAMCD) %>% select(-starts_with("temp_")) diff --git a/R/derive_var_atoxgr.R b/R/derive_var_atoxgr.R index d2ae8d5309..1addcf86f2 100644 --- a/R/derive_var_atoxgr.R +++ b/R/derive_var_atoxgr.R @@ -15,14 +15,15 @@ #' #' @param meta_criteria Metadata data set holding the criteria (normally a case statement) #' -#' Permitted Values: atoxgr_criteria_ctcv4, atoxgr_criteria_ctcv5 +#' Permitted Values: `atoxgr_criteria_ctcv4`, `atoxgr_criteria_ctcv5`, `atoxgr_criteria_daids` #' -#' {admiral} metadata data set `atoxgr_criteria_ctcv4` implements -#' [Common Terminology Criteria for Adverse Events (CTCAE) +#' - `atoxgr_criteria_ctcv4` implements [Common Terminology Criteria for Adverse Events (CTCAE) #' v4.0](https://ctep.cancer.gov/protocoldevelopment/electronic_applications/ctc.htm) -#' {admiral} metadata data set `atoxgr_criteria_ctcv5` implements -#' [Common Terminology Criteria for Adverse Events (CTCAE) +#' - `atoxgr_criteria_ctcv5` implements [Common Terminology Criteria for Adverse Events (CTCAE) #' v5.0](https://ctep.cancer.gov/protocoldevelopment/electronic_applications/ctc.htm) +#' - `atoxgr_criteria_daids` implements +#' [Division of AIDS (DAIDS) Table for Grading the Severity of Adult and Pediatric Adverse +#' Events](https://rsc.niaid.nih.gov/sites/default/files/daidsgradingcorrectedv21.pdf) #' #' The metadata should have the following variables: #' @@ -35,6 +36,8 @@ #' - `VAR_CHECK`: variable to hold comma separated list of variables used in criteria. Used to check #' against input data that variables exist. #' - `GRADE_CRITERIA_CODE`: variable to hold code that creates grade based on defined criteria. +#' - `FILTER`: Required only for DAIDS grading, specifies `admiral` code to filter the lab data +#' based on a subset of subjects (e.g. AGE > 18 YEARS) #' #' @param criteria_direction Direction (L= Low, H = High) of toxicity grade. #' @@ -49,6 +52,11 @@ #' for example, `get_unit_expr = extract_unit(PARAM)`. #' #' +#' @param signif_dig Number of significant digits to use when comparing a lab value against another +#' value. +#' +#' Significant digits used to avoid floating point discrepancies when comparing numeric values. +#' #' @details #' `new_var` is derived with values NA, "0", "1", "2", "3", "4", where "4" is the most #' severe grade @@ -72,37 +80,35 @@ #' library(tibble) #' #' data <- tribble( -#' ~ATOXDSCL, ~AVAL, ~ANRLO, ~ANRHI, ~PARAM, -#' "Hypoglycemia", 119, 4, 7, "Glucose (mmol/L)", -#' "Hypoglycemia", 120, 4, 7, "Glucose (mmol/L)", -#' "Anemia", 129, 120, 180, "Hemoglobin (g/L)", -#' "White blood cell decreased", 10, 5, 20, "White blood cell (10^9/L)", -#' "White blood cell decreased", 15, 5, 20, "White blood cell (10^9/L)", -#' "Anemia", 140, 120, 180, "Hemoglobin (g/L)" +#' ~ATOXDSCL, ~AVAL, ~ANRLO, ~ANRHI, ~PARAM, +#' "Hypoglycemia", 119, 4, 7, "Glucose (mmol/L)", +#' "Lymphocyte count decreased", 0.7, 1, 4, "Lymphocytes Abs (10^9/L)", +#' "Anemia", 129, 120, 180, "Hemoglobin (g/L)", +#' "White blood cell decreased", 10, 5, 20, "White blood cell (10^9/L)", +#' "White blood cell decreased", 15, 5, 20, "White blood cell (10^9/L)", +#' "Anemia", 140, 120, 180, "Hemoglobin (g/L)" #' ) #' #' derive_var_atoxgr_dir(data, #' new_var = ATOXGRL, #' tox_description_var = ATOXDSCL, -#' meta_criteria = atoxgr_criteria_ctcv4, +#' meta_criteria = atoxgr_criteria_ctcv5, #' criteria_direction = "L", #' get_unit_expr = extract_unit(PARAM) #' ) #' #' data <- tribble( #' ~ATOXDSCH, ~AVAL, ~ANRLO, ~ANRHI, ~PARAM, -#' "Hyperglycemia", 119, 4, 7, "Glucose (mmol/L)", -#' "Hyperglycemia", 120, 4, 7, "Glucose (mmol/L)", -#' "GGT increased", 129, 0, 30, "Gamma Glutamyl Transferase (U/L)", +#' "CPK increased", 129, 0, 30, "Creatine Kinase (U/L)", #' "Lymphocyte count increased", 4, 1, 4, "Lymphocytes Abs (10^9/L)", #' "Lymphocyte count increased", 2, 1, 4, "Lymphocytes Abs (10^9/L)", -#' "GGT increased", 140, 120, 180, "Gamma Glutamyl Transferase (U/L)" +#' "CPK increased", 140, 120, 180, "Creatine Kinase (U/L)" #' ) #' #' derive_var_atoxgr_dir(data, #' new_var = ATOXGRH, #' tox_description_var = ATOXDSCH, -#' meta_criteria = atoxgr_criteria_ctcv4, +#' meta_criteria = atoxgr_criteria_ctcv5, #' criteria_direction = "H", #' get_unit_expr = extract_unit(PARAM) #' ) @@ -111,7 +117,8 @@ derive_var_atoxgr_dir <- function(dataset, tox_description_var, meta_criteria, criteria_direction, - get_unit_expr) { + get_unit_expr, + signif_dig = 15) { new_var <- assert_symbol(enexpr(new_var)) tox_description_var <- assert_symbol(enexpr(tox_description_var)) get_unit_expr <- assert_expr(enexpr(get_unit_expr)) @@ -122,10 +129,13 @@ derive_var_atoxgr_dir <- function(dataset, # Check Grade description variable exists on input data set assert_data_frame(dataset, required_vars = exprs(!!tox_description_var)) + # Add FILTER to metadata if not there already (FILTER used for DAIDS grading) + if (!"FILTER" %in% colnames(meta_criteria)) meta_criteria[["FILTER"]] <- NA_character_ + # Check metadata data set has required variables assert_data_frame( meta_criteria, - required_vars = exprs(TERM, GRADE_CRITERIA_CODE, DIRECTION, SI_UNIT_CHECK, VAR_CHECK) + required_vars = exprs(TERM, GRADE_CRITERIA_CODE, FILTER, DIRECTION, SI_UNIT_CHECK, VAR_CHECK) ) # check DIRECTION has expected values L or H assert_character_vector(meta_criteria$DIRECTION, values = c("L", "H")) @@ -135,7 +145,7 @@ derive_var_atoxgr_dir <- function(dataset, # L = low (Hypo) H = high (Hyper) atoxgr_dir <- meta_criteria %>% filter(!is.na(GRADE_CRITERIA_CODE) & toupper(DIRECTION) == toupper(criteria_direction)) %>% - select(TERM, DIRECTION, SI_UNIT_CHECK, GRADE_CRITERIA_CODE, VAR_CHECK) %>% + select(TERM, DIRECTION, SI_UNIT_CHECK, FILTER, GRADE_CRITERIA_CODE, VAR_CHECK) %>% mutate( TERM_UPPER = toupper(TERM), SI_UNIT_UPPER = toupper(SI_UNIT_CHECK) @@ -171,33 +181,59 @@ derive_var_atoxgr_dir <- function(dataset, meta_this_term <- atoxgr_dir %>% filter(TERM_UPPER == list_of_terms$TERM_UPPER[i]) - # Put list of variables required for criteria in a vector - list_of_vars <- gsub("\\s+", "", unlist(strsplit(meta_this_term$VAR_CHECK, ","))) - - # filter lab data on term and apply criteria to derive grade grade_this_term <- to_be_graded %>% filter(!!tox_description_var == list_of_terms$TERM[i]) - # check variables required in criteria exist on data - assert_data_frame(grade_this_term, required_vars = exprs(!!!syms(list_of_vars))) - # apply criteria when SI unit matches - grade_this_term <- grade_this_term %>% - mutate( - temp_flag = meta_this_term$SI_UNIT_UPPER == toupper(!!get_unit_expr) | - is.na(meta_this_term$SI_UNIT_UPPER), - !!new_var := if_else( - temp_flag, eval(parse(text = meta_this_term$GRADE_CRITERIA_CODE)), NA_character_ - ) - ) %>% - select(-temp_flag) + # Within each TERM check if there are FILTERs to be applied + # if FILTER not missing then loop through each FILTER for the TERM already specified + for (j in seq_along(meta_this_term$FILTER)) { + # subset using FILTER if its not empty + if (!is.na(meta_this_term$FILTER[j])) { + meta_this_filter <- meta_this_term %>% + filter(FILTER == meta_this_term$FILTER[j]) + } else { + meta_this_filter <- meta_this_term + } + + # Put list of variables required for criteria in a vector + list_of_vars <- gsub("\\s+", "", unlist(strsplit(meta_this_filter$VAR_CHECK, ","))) + + if (!is.na(meta_this_filter$FILTER)) { + # filter lab data using FILTER from metadata + grade_this_filter <- grade_this_term %>% + filter(eval(parse(text = meta_this_filter$FILTER))) + } else { + grade_this_filter <- grade_this_term + } - # remove lab data just graded from data still to be graded + # check variables required in criteria exist on data + assert_data_frame(grade_this_filter, required_vars = exprs(!!!syms(list_of_vars))) + + # apply criteria when SI unit matches + grade_this_filter <- grade_this_filter %>% + mutate( + temp_flag = meta_this_filter$SI_UNIT_UPPER == toupper(!!get_unit_expr) | + is.na(meta_this_filter$SI_UNIT_UPPER), + !!new_var := if_else( + temp_flag, eval(parse(text = meta_this_filter$GRADE_CRITERIA_CODE)), NA_character_ + ) + ) %>% + select(-temp_flag) + + # add data just graded to data already processed + out_data <- bind_rows(out_data, grade_this_filter) + + if (!is.na(meta_this_filter$FILTER)) { + # remove lab data just graded from data still to be graded for the specified TERM + grade_this_term <- grade_this_term %>% + filter(!(eval(parse(text = meta_this_filter$FILTER)))) + } + } + + # remove lab data with TERM just graded from data still to be graded to_be_graded <- to_be_graded %>% filter(!!tox_description_var != list_of_terms$TERM[i]) - - # append lab data just graded to output data - out_data <- bind_rows(out_data, grade_this_term) } out_data @@ -219,7 +255,7 @@ derive_var_atoxgr_dir <- function(dataset, #' for low values, eg. "Anemia" #' #' @param hitox_description_var Variable containing the toxicity grade description -#' for low values, eg. "Hemoglobin Increased". +#' for high values, eg. "Hemoglobin Increased". #' #' @details #' Created variable `ATOXGR` will contain values "-4", "-3", "-2", "-1" for low values diff --git a/R/derive_var_basetype.R b/R/derive_var_basetype.R index d78e170ae0..5c4714593b 100644 --- a/R/derive_var_basetype.R +++ b/R/derive_var_basetype.R @@ -42,10 +42,5 @@ #' #' @export derive_var_basetype <- function(dataset, basetypes) { - deprecate_warn("0.11.0", "derive_var_basetype()", "derive_basetype_records()") - - derive_basetype_records( - dataset = dataset, - basetypes = basetypes - ) + deprecate_stop("0.11.0", "derive_var_basetype()", "derive_basetype_records()") } diff --git a/R/derive_var_disposition_status.R b/R/derive_var_disposition_status.R deleted file mode 100644 index 19a7be04bd..0000000000 --- a/R/derive_var_disposition_status.R +++ /dev/null @@ -1,121 +0,0 @@ -#' Default Format for Disposition Status -#' -#' @description -#' `r lifecycle::badge("deprecated")` -#' -#' This function is *deprecated*. This function is a default for `derive_var_disposition_status()` -#' for the `format_new_var` argument. Please define your own function and use that as input for the -#' `cat_fun` argument in `derive_var_merged_cat()` instead. -#' -#' Define a function to map the disposition status. To be used as an input for -#' `derive_var_disposition_status()`. -#' -#' @param status the disposition variable used for the mapping (e.g. `DSDECOD`). -#' -#' @return A `character` vector derived based on the values given in `status`: -#' "NOT STARTED" if `status` is "SCREEN FAILURE" or "SCREENING NOT COMPLETED", -#' "COMPLETED" if `status` is "COMPLETED", -#' "DISCONTINUED" if `status` is not in ("COMPLETED","SCREEN FAILURE", -#' "SCREENING NOT COMPLETED") nor NA, -#' "ONGOING" otherwise. -#' -#' @details Usually this function can not be used with `%>%`. -#' @export -#' @family deprecated -#' @keywords deprecated -format_eoxxstt_default <- function(status) { - ### DEPRECATION - deprecate_stop("0.10.0", - "format_eoxxstt_default()", - details = paste( - "This function is deprecated", - "Please define your own function and use that as input for the - `cat_fun` argument in `derive_var_merged_cat()` instead" - ) - ) -} - -#' Derive a Disposition Status at a Specific Timepoint -#' -#' @description -#' `r lifecycle::badge("deprecated")` -#' -#' This function is *deprecated*, Please define your own function and use that as input for the -#' `cat_fun` argument in `derive_var_merged_cat()` instead. -#' -#' Derive a disposition status from the the relevant records in the disposition domain. -#' -#' @param dataset Input dataset. -#' -#' @param dataset_ds Dataset containing the disposition information (e.g.: ds). -#' -#' It must contain: -#' - `STUDYID`, `USUBJID`, -#' - The variable(s) specified in the `status_var` -#' - The variables used in `filter_ds`. -#' -#' @param new_var Name of the disposition status variable. -#' -#' A variable name is expected (e.g. `EOSSTT`). -#' -#' @param status_var The variable used to derive the disposition status. -#' -#' A variable name is expected (e.g. `DSDECOD`). -#' -#' @param format_new_var The format used to derive the status. -#' -#' Default: `format_eoxxstt_default()` defined as: -#' ``` {r echo=TRUE, eval=FALSE} -#' format_eoxxstt_default <- function(status) { -#' case_when( -#' status %in% c("SCREEN FAILURE", "SCREENING NOT COMPLETED") ~ "NOT STARTED", -#' status == "COMPLETED" ~ "COMPLETED", -#' !status %in% c("COMPLETED", "SCREEN FAILURE", "SCREENING NOT COMPLETED") -#' & !is.na(status) ~ "DISCONTINUED", -#' TRUE ~ "ONGOING" -#' ) -#' } -#' ``` -#' where `status` is the `status_var.` -#' -#' @param filter_ds Filter condition for the disposition data. -#' -# 'It is expected that the filter restricts `dataset_ds` such that there is at most -#' one observation per patient. An error is issued otherwise. -#' -#' Permitted Values: logical expression. -#' -#' @param subject_keys Variables to uniquely identify a subject -#' -#' A list of expressions where the expressions are symbols as returned by -#' `exprs()` is expected. -#' -#' @return The input dataset with the disposition status (`new_var`) added. -#' `new_var` is derived based on the values given in `status_var` and according to the format -#' defined by `format_new_var` (e.g. when the default format is used, the function will derive -#' `new_var` as: -#' "NOT STARTED" if `status` is "SCREEN FAILURE" or "SCREENING NOT COMPLETED", -#' "COMPLETED" if `status_var` == "COMPLETED", -#' "DISCONTINUED" if `status` is not in ("COMPLETED","SCREEN FAILURE", -#' "SCREENING NOT COMPLETED") nor NA, -#' "ONGOING" otherwise). -#' -#' @family deprecated -#' @keywords deprecated -#' -#' -#' @export -#' -derive_var_disposition_status <- function(dataset, - dataset_ds, - new_var, - status_var, - format_new_var = format_eoxxstt_default, - filter_ds, - subject_keys = get_admiral_option("subject_keys")) { - ### DEPRECATION - deprecate_stop("0.10.0", - "derive_var_disposition_status()", - details = "Please use `derive_var_merged_cat()` instead" - ) -} diff --git a/R/derive_var_dthcaus.R b/R/derive_var_dthcaus.R index 3e730f39fd..c03c5366d5 100644 --- a/R/derive_var_dthcaus.R +++ b/R/derive_var_dthcaus.R @@ -81,7 +81,7 @@ #' date = convert_dtc_to_dt(AEDTHDTC), #' mode = "first", #' dthcaus = AEDECOD, -#' traceability_vars = exprs(DTHDOM = "AE", DTHSEQ = AESEQ) +#' set_values_to = exprs(DTHDOM = "AE", DTHSEQ = AESEQ) #' ) #' #' src_ds <- dthcaus_source( @@ -90,7 +90,7 @@ #' date = convert_dtc_to_dt(DSSTDTC), #' mode = "first", #' dthcaus = DSTERM, -#' traceability_vars = exprs(DTHDOM = "DS", DTHSEQ = DSSEQ) +#' set_values_to = exprs(DTHDOM = "DS", DTHSEQ = DSSEQ) #' ) #' #' derive_var_dthcaus(adsl, src_ae, src_ds, source_datasets = list(ae = ae, ds = ds)) @@ -102,7 +102,7 @@ #' date = convert_dtc_to_dt(AEDTHDTC), #' mode = "first", #' dthcaus = AEDECOD, -#' traceability_vars = exprs(DTHDOM = "AE", DTHSEQ = AESEQ) +#' set_values_to = exprs(DTHDOM = "AE", DTHSEQ = AESEQ) #' ) #' #' ds <- mutate( @@ -116,7 +116,7 @@ #' date = DSSTDT, #' mode = "first", #' dthcaus = DSTERM, -#' traceability_vars = exprs(DTHDOM = "DS", DTHSEQ = DSSEQ) +#' set_values_to = exprs(DTHDOM = "DS", DTHSEQ = DSSEQ) #' ) #' #' src_ds_post <- dthcaus_source( @@ -125,7 +125,7 @@ #' date = DSSTDT, #' mode = "first", #' dthcaus = "POST STUDY: UNKNOWN CAUSE", -#' traceability_vars = exprs(DTHDOM = "DS", DTHSEQ = DSSEQ) +#' set_values_to = exprs(DTHDOM = "DS", DTHSEQ = DSSEQ) #' ) #' #' derive_var_dthcaus( @@ -267,6 +267,7 @@ derive_var_dthcaus <- function(dataset, #' the results is assigned to `DTHCAUS`; if a string literal, e.g. `"Adverse #' Event"`, it is the fixed value to be assigned to `DTHCAUS`. #' +#' #' @param traceability_vars A named list returned by [`exprs()`] listing the #' traceability variables, e.g. `exprs(DTHDOM = "DS", DTHSEQ = DSSEQ)`. The #' left-hand side (names of the list elements) gives the names of the @@ -275,6 +276,10 @@ derive_var_dthcaus <- function(dataset, #' returned dataset. These can be either strings, numbers, symbols, or #' expressions referring to existing variables. #' +#' `r lifecycle::badge("deprecated")` Please use `set_values_to` instead. +#' +#' @param set_values_to Variables to be set to trace the source dataset +#' #' @keywords source_specifications #' @family source_specifications #' @@ -309,7 +314,17 @@ dthcaus_source <- function(dataset_name, order = NULL, mode = "first", dthcaus, + set_values_to = NULL, traceability_vars = NULL) { + if (!is.null(traceability_vars)) { + deprecate_warn( + "0.12.0", + "dthcaus_source(traceability_vars = )", + "dthcaus_source(set_values_to = )" + ) + set_values_to <- traceability_vars + } + out <- list( dataset_name = assert_character_scalar(dataset_name), filter = assert_filter_cond(enexpr(filter), optional = TRUE), @@ -317,7 +332,7 @@ dthcaus_source <- function(dataset_name, order = assert_expr_list(order, optional = TRUE), mode = assert_character_scalar(mode, values = c("first", "last"), case_sensitive = FALSE), dthcaus = assert_expr(enexpr(dthcaus)), - traceability = assert_expr_list(traceability_vars, named = TRUE, optional = TRUE) + traceability = assert_expr_list(set_values_to, named = TRUE, optional = TRUE) ) class(out) <- c("dthcaus_source", "source", "list") out diff --git a/R/derive_var_extreme_date.R b/R/derive_var_extreme_date.R index 176c0c2e2c..6cc7aab1a6 100644 --- a/R/derive_var_extreme_date.R +++ b/R/derive_var_extreme_date.R @@ -38,7 +38,7 @@ #' `date` element. If this is a date variable (rather than datetime), then the #' time is imputed as `"00:00:00"`. #' -#' 1. The variables specified by the `traceability_vars` element are added. +#' 1. The variables specified by the `set_values_to` element are added. #' #' 1. The selected observations of all source datasets are combined into a #' single dataset. @@ -177,7 +177,7 @@ #' ae_start <- date_source( #' dataset_name = "ae", #' date = convert_dtc_to_dtm(AESTDTC, highest_imputation = "M"), -#' traceability_vars = exprs( +#' set_values_to = exprs( #' LALVDOM = "AE", #' LALVSEQ = AESEQ, #' LALVVAR = "AESTDTC" @@ -187,7 +187,7 @@ #' ae_end <- date_source( #' dataset_name = "ae", #' date = convert_dtc_to_dtm(AEENDTC, highest_imputation = "M"), -#' traceability_vars = exprs( +#' set_values_to = exprs( #' LALVDOM = "AE", #' LALVSEQ = AESEQ, #' LALVVAR = "AEENDTC" @@ -196,7 +196,7 @@ #' lb_date <- date_source( #' dataset_name = "lb", #' date = convert_dtc_to_dtm(LBDTC), -#' traceability_vars = exprs( +#' set_values_to = exprs( #' LALVDOM = "LB", #' LALVSEQ = LBSEQ, #' LALVVAR = "LBDTC" @@ -206,7 +206,7 @@ #' adsl_date <- date_source( #' dataset_name = "adsl", #' date = TRTEDTM, -#' traceability_vars = exprs( +#' set_values_to = exprs( #' LALVDOM = "ADSL", #' LALVSEQ = NA_integer_, #' LALVVAR = "TRTEDTM" @@ -263,8 +263,8 @@ derive_var_extreme_dtm <- function(dataset, for (i in seq_along(sources)) { if (i > 1) { warn_if_inconsistent_list( - base = sources[[i - 1]]$traceability_vars, - compare = sources[[i]]$traceability_vars, + base = sources[[i - 1]]$set_values_to, + compare = sources[[i]]$set_values_to, list_name = "date_source()", i = i ) @@ -289,11 +289,11 @@ derive_var_extreme_dtm <- function(dataset, dataset_name = source_dataset_name ) - if (!is.null(sources[[i]]$traceability_vars)) { - warn_if_vars_exist(source_dataset, names(sources[[i]]$traceability_vars)) + if (!is.null(sources[[i]]$set_values_to)) { + warn_if_vars_exist(source_dataset, names(sources[[i]]$set_values_to)) assert_data_frame( source_dataset, - required_vars = get_source_vars(sources[[i]]$traceability_vars) + required_vars = get_source_vars(sources[[i]]$set_values_to) ) } @@ -310,7 +310,7 @@ derive_var_extreme_dtm <- function(dataset, add_data[[i]] <- transmute( add_data[[i]], !!!subject_keys, - !!!sources[[i]]$traceability_vars, + !!!sources[[i]]$set_values_to, !!new_var := convert_date_to_dtm(!!date_var) ) } @@ -350,7 +350,7 @@ derive_var_extreme_dtm <- function(dataset, #' 1. The new variable is set to the variable or expression specified by the #' `date` element. #' -#' 1. The variables specified by the `traceability_vars` element are added. +#' 1. The variables specified by the `set_values_to` element are added. #' #' 1. The selected observations of all source datasets are combined into a #' single dataset. @@ -489,7 +489,7 @@ derive_var_extreme_dtm <- function(dataset, #' ae_start <- date_source( #' dataset_name = "ae", #' date = convert_dtc_to_dt(AESTDTC, highest_imputation = "M"), -#' traceability_vars = exprs( +#' set_values_to = exprs( #' LALVDOM = "AE", #' LALVSEQ = AESEQ, #' LALVVAR = "AESTDTC" @@ -499,7 +499,7 @@ derive_var_extreme_dtm <- function(dataset, #' ae_end <- date_source( #' dataset_name = "ae", #' date = convert_dtc_to_dt(AEENDTC, highest_imputation = "M"), -#' traceability_vars = exprs( +#' set_values_to = exprs( #' LALVDOM = "AE", #' LALVSEQ = AESEQ, #' LALVVAR = "AEENDTC" @@ -509,7 +509,7 @@ derive_var_extreme_dtm <- function(dataset, #' lb_date <- date_source( #' dataset_name = "lb", #' date = convert_dtc_to_dt(LBDTC), -#' traceability_vars = exprs( +#' set_values_to = exprs( #' LALVDOM = "LB", #' LALVSEQ = LBSEQ, #' LALVVAR = "LBDTC" @@ -519,7 +519,7 @@ derive_var_extreme_dtm <- function(dataset, #' adsl_date <- date_source( #' dataset_name = "adsl", #' date = TRTEDT, -#' traceability_vars = exprs( +#' set_values_to = exprs( #' LALVDOM = "ADSL", #' LALVSEQ = NA_integer_, #' LALVVAR = "TRTEDT" @@ -578,6 +578,9 @@ derive_var_extreme_dt <- function(dataset, #' = "AESTDTC")`. The values must be a symbol, a character string, a numeric, #' an expression, or `NA`. #' +#' `r lifecycle::badge("deprecated")` Please use `set_values_to` instead. +#' +#' @param set_values_to Variables to be set #' #' @seealso [derive_var_extreme_dtm()], [derive_var_extreme_dt()] #' @@ -607,7 +610,7 @@ derive_var_extreme_dt <- function(dataset, #' death_date <- date_source( #' dataset_name = "adsl", #' date = DTHDT, -#' traceability_vars = exprs( +#' set_values_to = exprs( #' LALVDOM = "ADSL", #' LALVVAR = "DTHDT" #' ) @@ -615,12 +618,22 @@ derive_var_extreme_dt <- function(dataset, date_source <- function(dataset_name, filter = NULL, date, - traceability_vars = NULL) { + traceability_vars = NULL, + set_values_to = NULL) { + if (!is.null(traceability_vars)) { + deprecate_warn( + "0.12.0", + "date_source(traceability_vars = )", + "date_source(set_values_to = )" + ) + set_values_to <- traceability_vars + } + out <- list( dataset_name = assert_character_scalar(dataset_name), filter = assert_filter_cond(enexpr(filter), optional = TRUE), date = assert_expr(enexpr(date)), - traceability_vars = assert_expr_list(traceability_vars, named = TRUE, optional = TRUE) + set_values_to = assert_expr_list(set_values_to, named = TRUE, optional = TRUE) ) class(out) <- c("date_source", "source", "list") out diff --git a/R/derive_var_extreme_flag.R b/R/derive_var_extreme_flag.R index 109d118b9e..8cca038477 100644 --- a/R/derive_var_extreme_flag.R +++ b/R/derive_var_extreme_flag.R @@ -26,6 +26,11 @@ #' #' Permitted Values: `"first"`, `"last"` #' +#' @param flag_all Flag setting +#' +#' A logical value where if set to `TRUE`, all records are flagged +#' and no error or warning is issued if the first or last record is not unique. +#' #' @param by_vars Grouping variables #' #' Permitted Values: list of variables @@ -41,16 +46,15 @@ #' Permitted Values: `"none"`, `"warning"`, `"error"` #' #' @details For each group (with respect to the variables specified for the -#' `by_vars` parameter), `new_var` is set to "Y" for the first or last observation +#' `by_vars` parameter), `new_var` is set to `"Y"` for the first or last observation #' (with respect to the order specified for the `order` parameter and the flag mode -#' specified for the `mode` parameter). Only observations included by the `filter` parameter -#' are considered for flagging. +#' specified for the `mode` parameter). In the case where the user wants to flag multiple records +#' of a grouping, for example records that all happen on the same visit and time, the argument +#' `flag_all` can be set to `TRUE`. #' Otherwise, `new_var` is set to `NA`. Thus, the direction of "worst" is considered fixed for #' all parameters in the dataset depending on the `order` and the `mode`, i.e. for every #' parameter the first or last record will be flagged across the whole dataset. #' -#' @seealso [derive_var_worst_flag()] -#' #' #' @return The input dataset with the new flag variable added #' @@ -194,6 +198,22 @@ #' arrange(USUBJID, AESTDY, AESEQ) %>% #' select(USUBJID, AEDECOD, AESEV, AESTDY, AESEQ, AOCCIFL) #' +#' # Most severe AE first occurrence per patient (flag all cases) +#' example_ae %>% +#' mutate( +#' TEMP_AESEVN = +#' as.integer(factor(AESEV, levels = c("SEVERE", "MODERATE", "MILD"))) +#' ) %>% +#' derive_var_extreme_flag( +#' new_var = AOCCIFL, +#' by_vars = exprs(USUBJID), +#' order = exprs(TEMP_AESEVN, AESTDY), +#' mode = "first", +#' flag_all = TRUE +#' ) %>% +#' arrange(USUBJID, AESTDY) %>% +#' select(USUBJID, AEDECOD, AESEV, AESTDY, AOCCIFL) +#' #' # Most severe AE first occurrence per patient per body system #' example_ae %>% #' mutate( @@ -213,12 +233,14 @@ derive_var_extreme_flag <- function(dataset, order, new_var, mode, + flag_all = FALSE, check_type = "warning") { new_var <- assert_symbol(enexpr(new_var)) assert_vars(by_vars) assert_expr_list(order) assert_data_frame(dataset, required_vars = exprs(!!!by_vars, !!!extract_vars(order))) mode <- assert_character_scalar(mode, values = c("first", "last"), case_sensitive = FALSE) + flag_all <- assert_logical_scalar(flag_all) check_type <- assert_character_scalar( check_type, values = c("none", "warning", "error"), @@ -226,9 +248,15 @@ derive_var_extreme_flag <- function(dataset, ) # Create flag + if (flag_all) { + check_type <- "none" + } + + # Create observation number to identify the extreme record + tmp_obs_nr <- get_new_tmp_var(dataset, prefix = "tmp_obs_nr") data <- dataset %>% derive_var_obs_number( - new_var = temp_obs_nr, + new_var = !!tmp_obs_nr, order = order, by_vars = by_vars, check_type = check_type @@ -236,77 +264,24 @@ derive_var_extreme_flag <- function(dataset, if (mode == "first") { data <- data %>% - mutate(!!new_var := if_else(temp_obs_nr == 1, "Y", NA_character_)) + mutate(!!new_var := if_else(!!tmp_obs_nr == 1, "Y", NA_character_)) } else { data <- data %>% group_by(!!!by_vars) %>% - mutate(!!new_var := if_else(temp_obs_nr == n(), "Y", NA_character_)) %>% + mutate(!!new_var := if_else(!!tmp_obs_nr == n(), "Y", NA_character_)) %>% ungroup() } - # Remove temporary variable - data %>% select(-temp_obs_nr) -} + if (flag_all) { + flag_direction <- ifelse(mode == "first", "down", "up") + data <- data %>% + group_by(!!!by_vars, !!!order) %>% + fill(!!new_var, .direction = flag_direction) %>% + ungroup() + } -#' Adds a Variable Flagging the Maximal / Minimal Value Within a Group of Observations -#' @description -#' `r lifecycle::badge("deprecated")` -#' -#' This function is *deprecated*. Please use `slice_derivation()` / `derive_var_extreme_flag()` -#' to derive extreme flags and adjust the `order` argument. -#' -#' @inheritParams derive_var_extreme_flag -#' @param dataset Input dataset. -#' Variables specified by `by_vars`, `order`, `param_var`, and `analysis_var` are expected. -#' @param order Sort order. -#' Used to determine maximal / minimal observation if they are not unique, -#' see Details section for more information. -#' @param new_var Variable to add to the `dataset`. -#' It is set `"Y"` for the maximal / minimal observation of each group, -#' see Details section for more information. -#' @param param_var Variable with the parameter values for which the maximal / minimal -#' value is calculated. -#' @param analysis_var Variable with the measurement values for which the maximal / minimal -#' value is calculated. -#' @param worst_high Character with `param_var` values specifying the parameters -#' referring to "high". -#' Use `character(0)` if not required. -#' @param worst_low Character with `param_var` values specifying the parameters -#' referring to "low". -#' Use `character(0)` if not required. -#' -#' @details For each group with respect to the variables specified by the `by_vars` parameter, -#' the maximal / minimal observation of `analysis_var` -#' is labeled in the `new_var` column as `"Y"`, -#' if its `param_var` is in `worst_high` / `worst_low`. -#' Otherwise, it is assigned `NA`. -#' If there is more than one such maximal / minimal observation, -#' the first one with respect to the order specified by the `order` parameter is flagged. The -#' direction of "worst" depends on the definition of worst for a specified parameters in the -#' arguments `worst_high` / `worst_low`, i.e. for some parameters the highest value is the worst -#' and for others the worst is the lowest value. -#' -#' @seealso [derive_var_extreme_flag()] -#' -#' -#' @return The input dataset with the new flag variable added. -#' -#' @family deprecated -#' @keywords deprecated -#' -#' @export -derive_var_worst_flag <- function(dataset, - by_vars, - order, - new_var, - param_var, - analysis_var, - worst_high, - worst_low, - check_type = "warning") { - ### DEPRECATION - deprecate_stop("0.10.0", - "derive_var_worst_flag()", - details = "Please use `slice_derivation()` / `derive_var_extreme_flag()`" - ) + + # Remove temporary variable + data %>% + remove_tmp_vars() } diff --git a/R/derive_var_last_dose_amt.R b/R/derive_var_last_dose_amt.R index 7d6051d829..f16f027bbe 100644 --- a/R/derive_var_last_dose_amt.R +++ b/R/derive_var_last_dose_amt.R @@ -29,7 +29,6 @@ #' #' @export #' -#' @seealso [derive_vars_last_dose()], [create_single_dose_dataset()] derive_var_last_dose_amt <- function(dataset, dataset_ex, filter_ex = NULL, @@ -41,26 +40,5 @@ derive_var_last_dose_amt <- function(dataset, new_var, dose_var = EXDOSE, traceability_vars = NULL) { - deprecate_warn("0.11.0", "derive_var_last_dose_amt()", "derive_vars_joined()") - filter_ex <- assert_filter_cond(enexpr(filter_ex), optional = TRUE) - by_vars <- assert_vars(by_vars) - dose_id <- assert_vars(dose_id) - dose_date <- assert_symbol(enexpr(dose_date)) - analysis_date <- assert_symbol(enexpr(analysis_date)) - single_dose_condition <- assert_filter_cond(enexpr(single_dose_condition)) - new_var <- assert_symbol(enexpr(new_var)) - dose_var <- assert_symbol(enexpr(dose_var)) - - derive_vars_last_dose( - dataset = dataset, - dataset_ex = dataset_ex, - filter_ex = !!filter_ex, - by_vars = by_vars, - dose_id = dose_id, - dose_date = !!dose_date, - analysis_date = !!analysis_date, - single_dose_condition = !!single_dose_condition, - new_vars = exprs(!!new_var := !!dose_var), - traceability_vars = traceability_vars - ) + deprecate_stop("0.11.0", "derive_var_last_dose_amt()", "derive_vars_joined()") } diff --git a/R/derive_var_last_dose_date.R b/R/derive_var_last_dose_date.R index 126e568262..fe5152a354 100644 --- a/R/derive_var_last_dose_date.R +++ b/R/derive_var_last_dose_date.R @@ -33,7 +33,6 @@ #' #' @export #' -#' @seealso [derive_vars_last_dose()], [create_single_dose_dataset()] derive_var_last_dose_date <- function(dataset, dataset_ex, filter_ex = NULL, @@ -45,33 +44,5 @@ derive_var_last_dose_date <- function(dataset, new_var, output_datetime = TRUE, traceability_vars = NULL) { - deprecate_warn("0.11.0", "derive_var_last_dose_date()", "derive_vars_joined()") - filter_ex <- assert_filter_cond(enexpr(filter_ex), optional = TRUE) - by_vars <- assert_vars(by_vars) - dose_id <- assert_vars(dose_id) - dose_date <- assert_symbol(enexpr(dose_date)) - analysis_date <- assert_symbol(enexpr(analysis_date)) - single_dose_condition <- assert_filter_cond(enexpr(single_dose_condition)) - new_var <- assert_symbol(enexpr(new_var)) - assert_logical_scalar(output_datetime) - - res <- derive_vars_last_dose( - dataset = dataset, - dataset_ex = dataset_ex, - filter_ex = !!filter_ex, - by_vars = by_vars, - dose_id = dose_id, - dose_date = !!dose_date, - analysis_date = !!analysis_date, - single_dose_condition = !!single_dose_condition, - new_vars = exprs(!!new_var := !!dose_date), - traceability_vars = traceability_vars - ) - - # return either date or date-time variable - if (!output_datetime) { - res %>% mutate(!!new_var := as.Date(!!new_var)) - } else { - res %>% mutate(!!new_var := as.POSIXct(as.character(!!new_var), tz = "UTC")) - } + deprecate_stop("0.11.0", "derive_var_last_dose_date()", "derive_vars_joined()") } diff --git a/R/derive_var_last_dose_grp.R b/R/derive_var_last_dose_grp.R index b51d2370a4..23dbf86bb5 100644 --- a/R/derive_var_last_dose_grp.R +++ b/R/derive_var_last_dose_grp.R @@ -41,7 +41,6 @@ #' #' @export #' -#' @seealso [derive_vars_last_dose()], [cut()], [create_single_dose_dataset()] derive_var_last_dose_grp <- function(dataset, dataset_ex, filter_ex = NULL, @@ -57,38 +56,5 @@ derive_var_last_dose_grp <- function(dataset, right = TRUE, dose_var = EXDOSE, traceability_vars = NULL) { - deprecate_warn("0.11.0", "derive_var_last_dose_grp()", "derive_vars_joined()") - filter_ex <- assert_filter_cond(enexpr(filter_ex), optional = TRUE) - by_vars <- assert_vars(by_vars) - dose_date <- assert_symbol(enexpr(dose_date)) - analysis_date <- assert_symbol(enexpr(analysis_date)) - single_dose_condition <- assert_filter_cond(enexpr(single_dose_condition)) - new_var <- assert_symbol(enexpr(new_var)) - dose_var <- assert_symbol(enexpr(dose_var)) - - derive_vars_last_dose( - dataset = dataset, - dataset_ex = dataset_ex, - filter_ex = !!filter_ex, - by_vars = by_vars, - dose_id = dose_id, - dose_date = !!dose_date, - analysis_date = !!analysis_date, - single_dose_condition = !!single_dose_condition, - new_vars = exprs(!!dose_var), - traceability_vars = traceability_vars - ) %>% - mutate( - !!new_var := - as.character( - cut( - !!dose_var, - breaks = !!grp_brks, - include.lowest = include_lowest, - right = right, - labels = !!grp_lbls - ) - ) - ) %>% - select(-!!dose_var, !!new_var) + deprecate_stop("0.11.0", "derive_var_last_dose_grp()", "derive_vars_joined()") } diff --git a/R/derive_var_ontrtfl.R b/R/derive_var_ontrtfl.R index 6c3696d1d9..f5d53b1513 100644 --- a/R/derive_var_ontrtfl.R +++ b/R/derive_var_ontrtfl.R @@ -62,9 +62,9 @@ #' ref_start_date`, `filter_pre_timepoint` should be used to denote when the #' on-treatment flag should be set to null. Optional; default is `NULL`. #' -#' @param span_period A `"Y"` scalar character. If `"Y"`, events that started +#' @param span_period A logical scalar. If `TRUE`, events that started #' prior to the `ref_start_date`and are ongoing or end after the -#' `ref_start_date` are flagged as `"Y"`. Optional; default is `NULL`. +#' `ref_start_date` are flagged as `"Y"`. Optional; default is `FALSE`. #' #' @details On-Treatment is calculated by determining whether the assessment #' date or start/stop dates fall between 2 dates. The following logic is used @@ -84,7 +84,7 @@ #' `ONTRTFL` is set to `NULL`.This would be applicable to cases where the #' `start_date` is missing and `ONTRTFL` has been assigned as `"Y"` above. #' -#' If the `span_period` is specified as `"Y"`, this allows the user to assign +#' If the `span_period` is `TRUE`, this allows the user to assign #' `ONTRTFL` as `"Y"` to cases where the record started prior to the #' `ref_start_date` and was ongoing or ended after the `ref_start_date`. #' @@ -159,7 +159,7 @@ #' ref_start_date = TRTSDT, #' ref_end_date = TRTEDT, #' ref_end_window = 60, -#' span_period = "Y" +#' span_period = TRUE #' ) #' #' advs <- tribble( @@ -175,7 +175,7 @@ #' end_date = AENDT, #' ref_start_date = AP01SDT, #' ref_end_date = AP01EDT, -#' span_period = "Y" +#' span_period = TRUE #' ) derive_var_ontrtfl <- function(dataset, new_var = ONTRTFL, @@ -186,7 +186,17 @@ derive_var_ontrtfl <- function(dataset, ref_end_window = 0, ignore_time_for_ref_end_date = TRUE, filter_pre_timepoint = NULL, - span_period = NULL) { + span_period = FALSE) { + if (is.null(span_period) || span_period %in% c("Y", "y")) { + # replace span_period with lgl version + span_period <- !is.null(span_period) + deprecate_warn( + when = "0.12.0", + what = "admiral::derive_var_ontrtfl(span_period = 'must be TRUE or FALSE')", + details = + c(i = stringr::str_glue("Use `derive_var_ontrtfl(span_period={span_period})` instead.")) + ) + } new_var <- assert_symbol(enexpr(new_var)) start_date <- assert_symbol(enexpr(start_date)) end_date <- assert_symbol(enexpr(end_date), optional = TRUE) @@ -201,7 +211,7 @@ derive_var_ontrtfl <- function(dataset, ref_end_window <- assert_integer_scalar(ref_end_window, "non-negative") assert_logical_scalar(ignore_time_for_ref_end_date) filter_pre_timepoint <- assert_filter_cond(enexpr(filter_pre_timepoint), optional = TRUE) - assert_character_scalar(span_period, values = c("Y", "y"), optional = TRUE) + assert_logical_scalar(span_period) dataset <- mutate( dataset, @@ -236,9 +246,15 @@ derive_var_ontrtfl <- function(dataset, } else { # Scenario 2: Treatment end date is passed, window added above if (ignore_time_for_ref_end_date) { - end_cond <- expr(date(!!start_date) <= date(!!ref_end_date) + days(!!ref_end_window)) + end_cond <- expr( + (date(!!start_date) <= date(!!ref_end_date) + days(!!ref_end_window)) | + (!is.na(!!ref_start_date) & is.na(!!ref_end_date)) + ) } else { - end_cond <- expr(!!start_date <= !!ref_end_date + days(!!ref_end_window)) + end_cond <- expr( + (!!start_date <= !!ref_end_date + days(!!ref_end_window)) | + (!is.na(!!ref_start_date) & is.na(!!ref_end_date)) + ) } dataset <- mutate( dataset, @@ -265,7 +281,7 @@ derive_var_ontrtfl <- function(dataset, } # scenario 4: end_date and span_period are passed - if (!is.null(span_period)) { + if (span_period) { dataset <- mutate( dataset, !!new_var := if_else( diff --git a/R/derive_var_shift.R b/R/derive_var_shift.R index dcbe9904e0..1305cfa218 100644 --- a/R/derive_var_shift.R +++ b/R/derive_var_shift.R @@ -14,7 +14,9 @@ #' #' @param to_var Variable containing value to shift to. #' -#' @param na_val Character string to replace missing values in `from_var` or `to_var`. +#' @param na_val *Deprecated*, please use `missing_value` instead. +#' +#' @param missing_value Character string to replace missing values in `from_var` or `to_var`. #' #' Default: "NULL" #' @@ -24,7 +26,7 @@ #' #' @details `new_var` is derived by concatenating the values of `from_var` to values of `to_var` #' (e.g. "NORMAL to HIGH"). When `from_var` or `to_var` has missing value, the -#' missing value is replaced by `na_val` (e.g. "NORMAL to NULL"). +#' missing value is replaced by `missing_value` (e.g. "NORMAL to NULL"). #' #' #' @return The input dataset with the character shift variable added @@ -71,20 +73,28 @@ derive_var_shift <- function(dataset, new_var, from_var, to_var, - na_val = "NULL", + na_val, + missing_value = "NULL", sep_val = " to ") { + ### BEGIN DEPRECATION + if (!missing(na_val)) { + deprecate_warn("0.12.0", "derive_var_shift(na_val = )", "derive_var_shift(missing_value = )") + missing_value <- na_val + } + ### END DEPRECATION + new_var <- assert_symbol(enexpr(new_var)) from_var <- assert_symbol(enexpr(from_var)) to_var <- assert_symbol(enexpr(to_var)) - na_val <- assert_character_scalar(na_val) + missing_value <- assert_character_scalar(missing_value) sep_val <- assert_character_scalar(sep_val) assert_data_frame(dataset, required_vars = exprs(!!from_var, !!to_var)) # Derive shift variable. If from_var or to_var has missing value then set to na_val. dataset %>% mutate( - temp_from_var = if_else(is.na(!!from_var), !!na_val, as.character(!!from_var)), - temp_to_var = if_else(is.na(!!to_var), !!na_val, as.character(!!to_var)) + temp_from_var = if_else(is.na(!!from_var), !!missing_value, as.character(!!from_var)), + temp_to_var = if_else(is.na(!!to_var), !!missing_value, as.character(!!to_var)) ) %>% mutate( !!new_var := paste(temp_from_var, temp_to_var, sep = !!sep_val) diff --git a/R/derive_vars_aage.R b/R/derive_vars_aage.R index c8c041562c..575fecc10b 100644 --- a/R/derive_vars_aage.R +++ b/R/derive_vars_aage.R @@ -27,7 +27,7 @@ #' #' Default: `RANDDT` #' -#' @param unit Unit +#' @param age_unit Age unit #' #' The age is derived in the specified unit #' @@ -35,6 +35,8 @@ #' #' Permitted Values: 'years', 'months', 'weeks', 'days', 'hours', 'minutes', 'seconds' #' +#' @param unit *Deprecated*, please use `age_unit` instead. +#' #' @details The age is derived as the integer part of the duration from start to #' end date in the specified unit. When 'years' or 'months' are specified in the `out_unit` #' parameter, because of the underlying `lubridate::time_length()` function that is used @@ -64,12 +66,18 @@ derive_vars_aage <- function(dataset, start_date = BRTHDT, end_date = RANDDT, - unit = "years") { + unit = "years", + age_unit = "years") { + if (!missing(unit)) { + deprecate_warn("0.12.0", "derive_vars_aage(unit = )", "derive_vars_aage(age_unit = )") + age_unit <- unit + } + start_date <- assert_symbol(enexpr(start_date)) end_date <- assert_symbol(enexpr(end_date)) assert_data_frame(dataset, required_vars = expr_c(start_date, end_date)) assert_character_scalar( - unit, + age_unit, values = c("years", "months", "weeks", "days", "hours", "minutes", "seconds") ) @@ -79,7 +87,7 @@ derive_vars_aage <- function(dataset, new_var_unit = AAGEU, start_date = !!start_date, end_date = !!end_date, - out_unit = unit, + out_unit = age_unit, add_one = FALSE, trunc_out = TRUE ) diff --git a/R/derive_vars_disposition_reason.R b/R/derive_vars_disposition_reason.R deleted file mode 100644 index e99a8bdc82..0000000000 --- a/R/derive_vars_disposition_reason.R +++ /dev/null @@ -1,158 +0,0 @@ -#' Default Format for the Disposition Reason -#' -#' @description -#' `r lifecycle::badge("deprecated")` -#' -#' This function is *deprecated*. This function is a default for `derive_vars_disposition_reason()` -#' for the `format_new_vars` argument. Please use `derive_vars_merged()` and -#' specify the `filter_add` argument to derive the respective variables. -#' -#' Define a function to map the disposition reason, to be used as a parameter in -#' `derive_vars_disposition_reason()`. -#' -#' @param reason the disposition variable used for the mapping (e.g. `DSDECOD`). -#' @param reason_spe the disposition variable used for the mapping of the details -#' if required (e.g. `DSTERM`). -#' -#' @details -#' `format_reason_default(DSDECOD)` returns `DSDECOD` when `DSDECOD` is not `'COMPLETED'` nor `NA`. -#' \cr`format_reason_default(DSDECOD, DSTERM)` returns `DSTERM` when `DSDECOD` is -#' equal to `'OTHER'`. -#' \cr Usually this function can not be used with `%>%`. -#' -#' @return A `character` vector -#' -#' @export -#' @family deprecated -#' @keywords deprecated -#' @seealso [derive_vars_disposition_reason()] -format_reason_default <- function(reason, reason_spe = NULL) { - ### DEPRECATION - deprecate_stop("0.10.0", - "format_reason_default()", - details = paste( - "This function is a default for `derive_vars_disposition_reason() and is being deprecated`", - "Please use `derive_vars_merged()` and", - "specify the `filter_add` argument to derive the respective variables." - ) - ) -} - -#' Derive a Disposition Reason at a Specific Timepoint -#' -#' @description -#' `r lifecycle::badge("deprecated")` -#' -#' This function is *deprecated*. Please use `derive_vars_merged()` and -#' specify the `filter_add` argument to derive the respective variables. -#' -#' Derive a disposition reason from the the relevant records in the disposition domain. -#' -#' @param dataset Input dataset -#' -#' @param dataset_ds Dataset containing the disposition information (e.g. `ds`) -#' -#' The dataset must contain: -#' - `STUDYID`, `USUBJID`, -#' - The variable(s) specified in the `reason_var` (and `reason_var_spe`, if required) -#' - The variables used in `filter_ds`. -#' -#' @param new_var Name of the disposition reason variable -#' -#' A variable name is expected (e.g. `DCSREAS`). -#' -#' @param reason_var The variable used to derive the disposition reason -#' -#' A variable name is expected (e.g. `DSDECOD`). -#' -#' @param new_var_spe Name of the disposition reason detail variable -#' -#' A variable name is expected (e.g. `DCSREASP`). -#' If `new_var_spe` is specified, it is expected that `reason_var_spe` is also specified, -#' otherwise an error is issued. -#' -#' Default: NULL -#' -#' @param reason_var_spe The variable used to derive the disposition reason detail -#' -#' A variable name is expected (e.g. `DSTERM`). -#' If `new_var_spe` is specified, it is expected that `reason_var_spe` is also specified, -#' otherwise an error is issued. -#' -#' Default: NULL -#' -#' @param format_new_vars The function used to derive the reason(s) -#' -#' This function is used to derive the disposition reason(s) and must follow the below conventions -#' -#' - If only the main reason for discontinuation needs to be derived (i.e. `new_var_spe` is NULL), -#' the function must have at least one character vector argument, e.g. -#' `format_reason <- function(reason)` -#' and `new_var` will be derived as `new_var = format_reason(reason_var)`. -#' Typically, the content of the function would return `reason_var` or `NA` depending on the -#' value (e.g. `if_else ( reason != "COMPLETED" & !is.na(reason), reason, NA_character_)`). -#' `DCSREAS = format_reason(DSDECOD)` returns `DCSREAS = DSDECOD` -#' when `DSDECOD` is not `'COMPLETED'` nor `NA`, `NA` otherwise. -#' -#' - If both the main reason and the details needs to be derived (`new_var_spe` is specified) -#' the function must have two character vectors argument, e.g. -#' `format_reason2 <- function(reason, reason_spe)` and -#' `new_var` will be derived as `new_var = format_reason(reason_var)`, -#' `new_var_spe` will be derived as `new_var_spe = format_reason(reason_var, reason_var_spe)`. -#' Typically, the content of the function would return `reason_var_spe` or `NA` depending on the -#' `reason_var` value (e.g. `if_else ( reason == "OTHER", reason_spe, NA_character_)`). -#' `DCSREASP = format_reason(DSDECOD, DSTERM)` returns `DCSREASP = DSTERM` when -#' `DSDECOD` is equal to `'OTHER'`. -#' -#' Default: `format_reason_default`, see [`format_reason_default()`] for details. -#' -#' @param filter_ds Filter condition for the disposition data. -#' -#' Filter used to select the relevant disposition data. -#' It is expected that the filter restricts `dataset_ds` such that there is at most -#' one observation per patient. An error is issued otherwise. -#' -#' Permitted Values: logical expression. -#' -#' @param subject_keys Variables to uniquely identify a subject -#' -#' A list of expressions where the expressions are symbols as returned by -#' `exprs()` is expected. -#' -#' @return the input dataset with the disposition reason(s) (`new_var` and -#' if required `new_var_spe`) added. -#' -#' @details -#' This functions returns the main reason for discontinuation (e.g. `DCSREAS` or `DCTREAS`). -#' The reason for discontinuation is derived based on `reason_var` (e.g. `DSDECOD`) and -#' `format_new_vars`. -#' If `new_var_spe` is not NULL, then the function will also return the details associated -#' with the reason for discontinuation (e.g. `DCSREASP`). -#' The details associated with the reason for discontinuation are derived based on -#' `reason_var_spe` (e.g. `DSTERM`), `reason_var` and `format_new_vars`. -#' -#' @family deprecated -#' @seealso [format_reason_default()] -#' @keywords deprecated -#' -#' -#' @export -#' -derive_vars_disposition_reason <- function(dataset, - dataset_ds, - new_var, - reason_var, - new_var_spe = NULL, - reason_var_spe = NULL, - format_new_vars = format_reason_default, - filter_ds, - subject_keys = get_admiral_option("subject_keys")) { - ### DEPRECATION - deprecate_stop("0.10.0", - "derive_vars_disposition_reason()", - details = paste( - "Please use `derive_vars_merged()`", - "and specify the `filter_add` argument to derive the respective variables" - ) - ) -} diff --git a/R/derive_vars_dy.R b/R/derive_vars_dy.R index aa085c32eb..e6d2d515f3 100644 --- a/R/derive_vars_dy.R +++ b/R/derive_vars_dy.R @@ -8,9 +8,8 @@ #' The columns specified by the `reference_date` and the `source_vars` #' parameter are expected. #' -#' @param reference_date The start date column, e.g., date of first treatment -#' -#' A date or date-time object column is expected. +#' @param reference_date A date or date-time column, e.g., date of first treatment +#' or date-time of last exposure to treatment. #' #' Refer to `derive_vars_dt()` to impute and derive a date from a date #' character vector to a date object. @@ -102,31 +101,21 @@ derive_vars_dy <- function(dataset, abort(err_msg) } - dy_vars <- if_else( + # named vector passed to `.names` in `across()` to derive name of dy_vars + dy_vars <- set_names(if_else( source_names == "", str_replace_all(vars2chr(source_vars), "(DT|DTM)$", "DY"), source_names - ) + ), vars2chr(source_vars)) + warn_if_vars_exist(dataset, dy_vars) - if (n_vars > 1L) { - dataset %>% - mutate( - across( - .cols = vars2chr(unname(source_vars)), - .fns = list(temp = ~ - compute_duration(start_date = !!reference_date, end_date = .)) - ) - ) %>% - rename_with( - .cols = ends_with("temp"), - .fn = ~dy_vars + dataset %>% + mutate( + across( + .cols = vars2chr(unname(source_vars)), + .fns = ~ compute_duration(start_date = !!reference_date, end_date = .x), + .names = "{dy_vars}" ) - } else { - dataset %>% - mutate( - !!sym(dy_vars) := - compute_duration(start_date = !!reference_date, end_date = !!source_vars[[1]]) - ) - } + ) } diff --git a/R/derive_vars_last_dose.R b/R/derive_vars_last_dose.R index 77bc93fe9c..2164e1b0c5 100644 --- a/R/derive_vars_last_dose.R +++ b/R/derive_vars_last_dose.R @@ -81,9 +81,6 @@ #' @family deprecated #' @keywords deprecated #' -#' @seealso [derive_var_last_dose_amt()], [derive_var_last_dose_date()], -#' [derive_var_last_dose_grp()], [create_single_dose_dataset()] -#' #' @export derive_vars_last_dose <- function(dataset, dataset_ex, @@ -95,16 +92,5 @@ derive_vars_last_dose <- function(dataset, single_dose_condition = EXDOSFRQ == "ONCE", new_vars = NULL, traceability_vars = NULL) { - deprecate_warn("0.11.0", "derive_vars_last_dose()", "derive_vars_joined()") - derive_vars_joined( - dataset = dataset, - dataset_add = dataset_ex, - by_vars = by_vars, - order = expr_c(enexpr(dose_date), dose_id), - new_vars = expr_c({{ new_vars }}, {{ traceability_vars }}), - join_vars = expr_c(enexpr(dose_date), dose_id), - filter_add = {{ filter_ex }}, - filter_join = {{ dose_date }} <= {{ analysis_date }}, - mode = "last", - ) + deprecate_stop("0.11.0", "derive_vars_last_dose()", "derive_vars_joined()") } diff --git a/R/derive_vars_query.R b/R/derive_vars_query.R index 4063a0db21..6604ccf9bd 100644 --- a/R/derive_vars_query.R +++ b/R/derive_vars_query.R @@ -218,9 +218,9 @@ derive_vars_query <- function(dataset, dataset_queries) { #' assert_valid_queries(queries, "queries") assert_valid_queries <- function(queries, queries_name) { # check required columns - assert_has_variables( + assert_data_frame( queries, - c("PREFIX", "GRPNAME", "SRCVAR", "TERMNAME", "TERMID") + required_vars = exprs(PREFIX, GRPNAME, SRCVAR, TERMNAME, TERMID) ) # check duplicate rows diff --git a/R/duplicates.R b/R/duplicates.R index 04a51a85cf..43a48e9feb 100644 --- a/R/duplicates.R +++ b/R/duplicates.R @@ -129,7 +129,7 @@ signal_duplicate_records <- function(dataset, #' @return No return value, called for side effects #' #' -#' @keywords utils_print +#' @keywords internal #' @family utils_print #' #' @export diff --git a/R/filter_extreme.R b/R/filter_extreme.R index 63c919791d..8dab991b4f 100644 --- a/R/filter_extreme.R +++ b/R/filter_extreme.R @@ -111,12 +111,11 @@ filter_extreme <- function(dataset, values = c("none", "warning", "error"), case_sensitive = FALSE ) + assert_data_frame(dataset, required_vars = by_vars) # group and sort input dataset tmp_obs_nr <- get_new_tmp_var(dataset) if (!is.null(by_vars)) { - assert_has_variables(dataset, vars2chr(by_vars)) - data <- dataset %>% derive_var_obs_number( new_var = !!tmp_obs_nr, diff --git a/R/globals.R b/R/globals.R index 5488078113..d1e24ad67a 100644 --- a/R/globals.R +++ b/R/globals.R @@ -137,6 +137,7 @@ globalVariables(c( "ATOXGRH", "ATOXDSCL", "ATOXDSCH", + "FILTER", "GRADE_CRITERIA_CODE", "DIRECTION", "SI_UNIT_CHECK", @@ -144,6 +145,7 @@ globalVariables(c( "VAR_CHECK", "TERM", "SRCVAR", + "TERMID", "TERMNAME", "TERM_NAME_ID", "TERM_UPPER", diff --git a/R/slice_derivation.R b/R/slice_derivation.R index 7a8c3f650c..2a4eb39056 100644 --- a/R/slice_derivation.R +++ b/R/slice_derivation.R @@ -90,7 +90,7 @@ slice_derivation <- function(dataset, assert_function(derivation, params = c("dataset")) assert_s3_class(args, "params", optional = TRUE) if (!is.null(args)) { - assert_function_param(deparse(substitute(derivation)), names(args)) + assert_function(derivation, names(args)) } slices <- list2(...) assert_list_of(slices, "derivation_slice") diff --git a/R/user_helpers.R b/R/user_helpers.R index 91f228ea5e..bad0e6205c 100644 --- a/R/user_helpers.R +++ b/R/user_helpers.R @@ -112,7 +112,7 @@ list_all_templates <- function(package = "admiral") { #' #' @export #' -#' @keywords utils_print +#' @keywords internal #' @family utils_print #' #' @seealso [list_all_templates()] diff --git a/R/user_utils.R b/R/user_utils.R index 7eea0632c8..b08c25af8e 100644 --- a/R/user_utils.R +++ b/R/user_utils.R @@ -277,7 +277,7 @@ yn_to_numeric <- function(arg) { #' @return No return value, called for side effects #' #' -#' @keywords utils_print +#' @keywords internal #' @family utils_print #' #' @export @@ -306,7 +306,7 @@ print.source <- function(x, ...) { #' @return No return value, called for side effects #' #' -#' @keywords utils_print +#' @keywords internal #' @family utils_print #' #' @export @@ -327,16 +327,29 @@ print_named_list <- function(list, indent = 0) { print(list[[name]]) } else if (is.list(list[[name]])) { cat(strrep(" ", indent), name, ":\n", sep = "") - print_named_list(list[[name]], indent = indent + 2) + if (is_named(list[[name]])) { + print_named_list(list[[name]], indent = indent + 2) + } else { + for (item in list[[name]]) { + if (is.character(item)) { + chr_val <- dquote(item) + } else if (is_expression(item)) { + chr_val <- format(item) + } else { + chr_val <- item + } + cat(strrep(" ", indent + 2), paste0(chr_val, collapse = "\n"), "\n", sep = "") + } + } } else { if (is.character(list[[name]])) { chr_val <- dquote(list[[name]]) } else if (is_expression(list[[name]])) { - chr_val <- as_label(list[[name]]) + chr_val <- format(list[[name]]) } else { chr_val <- list[[name]] } - cat(strrep(" ", indent), name, ": ", chr_val, "\n", sep = "") + cat(strrep(" ", indent), name, ": ", paste0(chr_val, collapse = "\n"), "\n", sep = "") } } } diff --git a/README.md b/README.md index 72c7fb5192..a36098122c 100644 --- a/README.md +++ b/README.md @@ -26,28 +26,29 @@ if (!requireNamespace("remotes", quietly = TRUE)) { install.packages("remotes") } -remotes::install_github("pharmaverse/admiral.test", ref = "devel") # This is a required dependency of {admiral} -remotes::install_github("pharmaverse/admiraldev", ref = "devel") # This is a required dependency of {admiral} -remotes::install_github("pharmaverse/admiral", ref = "devel") +remotes::install_github("pharmaverse/pharmaversesdtm") # This is a required dependency of {admiral} +remotes::install_github("pharmaverse/admiraldev") # This is a required dependency of {admiral} +remotes::install_github("pharmaverse/admiral") ``` ## Release Schedule -`{admiral}` releases are targeted for the first Monday of the last month of each quarter. Pull Requests will be frozen the week before a release. -The `admiral` family has several downstream and upstream dependencies and so this release shall be done in three +[{admiral}](https://pharmaverse.github.io/admiral/cran-release/)` releases are targeted for the first Monday of the last month of each quarter. Pull Requests will be frozen the week before a release. +The {admiral} family has several downstream and upstream dependencies and so this release shall be done in three Phases: -* Phase 1 release is for `{admiraldev}`, `{admiral.test}`, and `{admiral}` core -* Phase 2 release is extension packages, e.g. `{admiralonco}`, `admiralophtha` +* Phase 1 release is for [{admiraldev}](https://pharmaverse.github.io/admiraldev/main/), [{pharmaversesdtm}](https://pharmaverse.github.io/pharmaversesdtm/main/), and [{admiral}](https://pharmaverse.github.io/admiral/cran-release/) core +* Phase 2 release is extension packages, e.g. [{admiralonco}](https://pharmaverse.github.io/admiralonco/main/), [{admiralophtha}](https://pharmaverse.github.io/admiralophtha/main/), [{admiralvaccine}](https://pharmaverse.github.io/admiralvaccine/main/) -| Release Schedule | Phase 1- Date and Packages | Phase 2- Date and Packages | -| ---------------- | ------------------------------- | -------------------------- | -| Q3-2023 | September 4th | September 11th | -| | `{admiraldev}` `{admiral.test}` | `{admiralonco}` | -| | `{admiral}` | `{admiralophtha}` | -| Q4-2023 | December 4th | December 11th | -| | `{admiraldev}` `{admiral.test}` | `{admiralonco}` | -| | `{admiral}` | `{admiralophtha}` | + +|Release Schedule | Phase 1- Date and Packages | Phase 2- Date and Packages | +|---------------- | -------------------------- | -------------------------- | +| Q4-2023 | December 4th | December 11th | +| | [{pharmaversesdtm}](https://pharmaverse.github.io/pharmaversesdtm/main/) | [{admiralonco}](https://pharmaverse.github.io/admiralonco/main/) | +| | [{admiraldev}](https://pharmaverse.github.io/admiraldev/main/) | [{admiralophtha}](https://pharmaverse.github.io/admiralophtha/main/) | +| | [{admiral}](https://pharmaverse.github.io/admiral/main/) | | + +The `{admiral}` Q4-2023 release will officially be `{admiral}`'s version 1.0.0 release, where we commit to increased package maturity and pivot towards focusing on maintenance rather than new content. This does not mean that there will never be any new content in `{admiral}`, rather it means we will be more mindful about introducing new functionality and/or breaking changes. The release schedule in 2024 and onward will also shift to twice-yearly, rather than quarterly, so that our users have ample time to react to any new content and changes that do make it onto `{admiral}`. ## Main Goal @@ -76,15 +77,13 @@ We will provide: * Functions that are comprehensively documented and tested, including example calls---these are all listed in the [Reference section](https://pharmaverse.github.io/admiral/cran-release/reference/index.html) * Vignettes on how to create ADSL, BDS and OCCDS datasets, including example scripts -* Vignettes for ADaM dataset specific functionality (i.e. dictionary coding, date imputation, - SMQs ...) +* Vignettes for ADaM dataset specific functionality (i.e. dictionary coding, date imputation, SMQs ...) ## Types of Packages There will be 3 foreseeable types of `{admiral}` packages: -* Core package---one package containing all core functions required to create ADaMs, - usable by any company (i.e. general derivations, utility functions and checks for ADSL, OCCDS and BDS) +* Core package---one package containing all core functions required to create ADaMs, usable by any company (i.e. general derivations, utility functions and checks for ADSL, OCCDS and BDS) * TA (Therapeutic Area) package extensions---one package per TA with functions that are specific to algorithms and requirements for that particular TA (e.g. [`{admiralonco}`](https://pharmaverse.github.io/admiralonco/)) * Company package extensions---specific needs and plug-ins for the company, such as access to metadata @@ -104,23 +103,15 @@ We have four design principles to achieve the main goal: All `{admiral}` functions should be easy to use. -* Documentation is an absolute priority. Each function reference page should cover the purpose, - descriptions of each argument with permitted values, the expected input and output, with clear real-life - examples---so that users don’t need to dig through code to find answers. -* Vignettes that complement the functional documentation to help users see how best the functions can be - applied to achieve ADaM requirements. -* Functions should be written and structured in a way that users are able to read, re-use or extend them - for study specific purposes if needed (see Readability below). +* Documentation is an absolute priority. Each function reference page should cover the purpose, descriptions of each argument with permitted values, the expected input and output, with clear real-life examples---so that users don’t need to dig through code to find answers. +* Vignettes that complement the functional documentation to help users see how best the functions can be applied to achieve ADaM requirements. +* Functions should be written and structured in a way that users are able to read, re-use or extend them for study specific purposes if needed (see Readability below). ### Simplicity All `{admiral}` functions have a clear purpose. -* We try not to ever design single functions that could achieve numerous very different derivations. For - example if you as a user pick up a function with >10 different arguments then chances are it is going to be - difficult to understand if this function could be applied for your specific need. The intention is that - arguments/parameters can influence how the output of a function is calculated, but not change the purpose of - the function. +* We try not to ever design single functions that could achieve numerous very different derivations. For example if you as a user pick up a function with >10 different arguments then chances are it is going to be difficult to understand if this function could be applied for your specific need. The intention is that arguments/parameters can influence how the output of a function is calculated, but not change the purpose of the function. * We try to combine similar tasks and algorithms into one function where applicable to reduce the amount of repetitive functions with similar algorithms and to group together similar functionality to increase usability (e.g. one study day calculation rather than a function per variable). @@ -128,20 +119,16 @@ All `{admiral}` functions have a clear purpose. * Functions should not allow expressions as arguments that are used as code snippets in function calls. -* We recommend to avoid copy and paste of complex computational algorithms or repetitive code like checks - and advise to wrap them into a function. However we would also like to avoid multi-layered functional nesting, - so this needs to be considered carefully to keep the nesting of 3-4 functions an exception rather than the rule. +* We recommend to avoid copy and paste of complex computational algorithms or repetitive code like checks and advise to wrap them into a function. However we would also like to avoid multi-layered functional nesting, so this needs to be considered carefully to keep the nesting of 3-4 functions an exception rather than the rule. ### Findability All `{admiral}` functions are easily findable. * In a growing code base, across a family of packages, we make every effort to make our functions easily findable. -* We use consistent naming conventions across all our functions, and provide vignettes and ADaM templates that - help users to get started and build familiarity. Each `{admiral}` family package website is searchable. +* We use consistent naming conventions across all our functions, and provide vignettes and ADaM templates that help users to get started and build familiarity. Each `{admiral}` family package website is searchable. * We avoid repetitive functions that will do similar tasks (as explained above with study day example). -* Each package extension is kept focused on the specific scope, e.g. features that are relevant across multiple - extension packages will be moved to the core `{admiral}` package. +* Each package extension is kept focused on the specific scope, e.g. features that are relevant across multiple extension packages will be moved to the core `{admiral}` package. ### Readability @@ -149,13 +136,10 @@ All `{admiral}` functions follow the [Programming Strategy](https://pharmaverse. that all our developers and contributors must follow, so that all our code has a high degree of consistency and readability. * We mandate use of tidyverse (e.g. dplyr) over similar functionality existing in base R. -* For sections of code that perform the actual derivations (e.g. besides assertions or basic utilities), - we try to limit nesting of too many dependencies or functions. +* For sections of code that perform the actual derivations (e.g. besides assertions or basic utilities), we try to limit nesting of too many dependencies or functions. * Modularity is a focus---we don’t try to achieve too many steps in one. * All code has to be well commented. -* We recognize that a user or a Health Authority reviewer may have the wish to delve into the code base (especially - given this open source setting), or users may need to extend/adapt the code for their study specific needs. We - therefore want any module to be understandable to all, not only the `{admiral}` developers. +* We recognize that a user or a Health Authority reviewer may have the wish to delve into the code base (especially given this open source setting), or users may need to extend/adapt the code for their study specific needs. We therefore want any module to be understandable to all, not only the `{admiral}` developers. ## References and Documentation @@ -166,16 +150,22 @@ that all our developers and contributors must follow, so that all our code has a * Please see the [Contribution Model](https://pharmaverse.github.io/admiral/cran-release/articles/contribution_model.html) for how to get involved with making contributions * Please see [FAQ: R and Package Versions](https://pharmaverse.github.io/admiral/cran-release/articles/faq.html#why-do-we-use-a-certain-r-version-and-package-versions-for-development) for why we develop with certain R and package versions. +## Pharmaverse Blog +If you are interested in R and Clinical Reporting, then visit the [pharmaverse blog](https://pharmaverse.github.io/blog/). This contains regular, bite-sized posts showcasing how `{admiral}` and other packages in the pharmaverse can be used to realize the vision of full end-to-end Clinical Reporting in R. + +We are also always looking for keen `{admiral}` users to publish their own blog posts about how they use the package. If this could be you, feel free make an issue in the [GitHub repo](https://github.com/pharmaverse/blog) and get started! + + ## Conference Presentations +* [Cross Industry Package Development](https://www.youtube.com/watch?v=M4L1PPMu0pU) (recording from R in Pharma 2022) * [Paving the way for clinical submissions in R](https://phuse.s3.eu-central-1.amazonaws.com/Archive/2023/SDE/EU/London/PRE_London09.pdf) (slides from PHUSE SDE in London) * [An Overview of {admiral}](https://phuse.s3.eu-central-1.amazonaws.com/Archive/2023/SDE/US/Summit/PRE_Summit03.pdf) (slides from PHUSE SDE in Summit, NJ) * [{admiralonco}](https://phuse.s3.eu-central-1.amazonaws.com/Archive/2023/Connect/US/Florida/REC_OS12.mp4) (recording for talk at PHUSE US Connect 2023, slides also available [here](https://phuse.s3.eu-central-1.amazonaws.com/Archive/2023/Connect/US/Florida/PRE_OS12.pdf)) * [Programming ADNCA using R and {admiral}](https://phuse.s3.eu-central-1.amazonaws.com/Archive/2023/Connect/US/Florida/REC_OS09.mp4) (recording of presentation from PHUSE US Connect 2023) * [Clinical Reporting in R](https://www.youtube.com/watch?v=9eod8MLF5ys\&list=PLMtxz1fUYA5AWYQHB5mZAs-yamNJ5Tm_8\&index=2) (recording of workshop at R in Pharma 2022) * [Introducing {admiral}](https://www.youtube.com/watch?v=N7Bw8c3D5fU) (recording of talk for R in Pharma 2021) -* [Pharmaverse workshop](https://github.com/pharmaverse/pharmaverse.workshop.phuseUS2022) (slides and materials from PHUSE US Connect 2022---including `{admiral}` - workshop slides from PHUSE EU Connect 2021) +* [Pharmaverse workshop](https://github.com/pharmaverse/pharmaverse.workshop.phuseUS2022) (slides and materials from PHUSE US Connect 2022---including `{admiral}` workshop slides from PHUSE EU Connect 2021) ## Contact @@ -183,3 +173,8 @@ We use the following for support and communications between user and developer c * [Slack](https://app.slack.com/client/T028PB489D3/C02M8KN8269)---for informal discussions, Q\&A and building our user community. If you don't have access, use this [link](https://join.slack.com/t/pharmaverse/shared_invite/zt-yv5atkr4-Np2ytJ6W_QKz_4Olo7Jo9A) to join the pharmaverse Slack workspace * [GitHub Issues](https://github.com/pharmaverse/admiral/issues)---for direct feedback, enhancement requests or raising bugs + +## Acknowledgments + +Along with the authors and contributors, thanks to the following people for their work on the package: +Jaxon Abercrombie, Mahdi About, Teckla Akinyi, James Black, Claudia Carlucci, Bill Denney, Kamila Duniec, Alice Ehmann, Ania Golab, Alana Harris, Declan Hodges, Anthony Howard, Shimeng Huang, Samia Kabi, James Kim, John Kirkpatrick, Leena Khatri, Robin Koeger, Konstantina Koukourikou, Pavan Kumar, Pooja Kumari, Shan Lee, Wenyi Liu, Jack McGavigan, Jordanna Morrish, Syed Mubasheer, Yohann Omnes, Barbara O'Reilly, Hamza Rahal, Nick Ramirez, Tom Ratford, Tamara Senior, Sophie Shapcott, Ondrej Slama, Andrew Smith, Daniil Stefonishin, Vignesh Thanikachalam, Michael Thorpe, Annie Yang, Ojesh Upadhyay and Franciszek Walkowiak. diff --git a/_pkgdown.yml b/_pkgdown.yml index bd9be56f12..8c52c88221 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -15,6 +15,14 @@ repo: news: cran_dates: true +authors: + before: "We define *authors* as those who are actively maintaining the code base, and *contributors* as those who made a significant contribution in the past. For all acknowledgements, see the eponymous section in the [Home Page](https://pharmaverse.github.io/admiral/cran-release/)." + footer: + roles: [aut, ctb, cre, fnd] + text: "Developed by" + sidebar: + roles: [aut] + reference: - title: Derivations for Adding Variables - subtitle: All ADaMs @@ -102,10 +110,6 @@ reference: contents: - has_keyword('utils_fil') -- subtitle: Utilities used for Date Imputation - contents: - - has_keyword('utils_impute') - - subtitle: Utilities for Quosures contents: - has_keyword('utils_quo') @@ -114,10 +118,6 @@ reference: contents: - has_keyword('utils_examples') -- subtitle: Utilities for Printing - contents: - - has_keyword('utils_print') - - title: Objects exported from other packages desc: | To maximize the user-friendliness of `{admiral}`, functions from other packages are provided @@ -145,7 +145,7 @@ navbar: components: getstarted: text: Get Started - href: articles/ + href: articles/admiral.html reference: text: Reference href: reference/ diff --git a/admiral.Rproj b/admiral.Rproj index 20ccb4388e..576c7085e4 100644 --- a/admiral.Rproj +++ b/admiral.Rproj @@ -19,5 +19,6 @@ LineEndingConversion: Posix BuildType: Package PackageUseDevtools: Yes PackageInstallArgs: --no-multiarch --with-keep.source +PackageRoxygenize: rd,collate,namespace SpellingDictionary: en_US diff --git a/data/atoxgr_criteria_ctcv4.rda b/data/atoxgr_criteria_ctcv4.rda index 4f9c022740..eee2737efb 100644 Binary files a/data/atoxgr_criteria_ctcv4.rda and b/data/atoxgr_criteria_ctcv4.rda differ diff --git a/data/atoxgr_criteria_ctcv5.rda b/data/atoxgr_criteria_ctcv5.rda index 9f426aef31..1671095608 100644 Binary files a/data/atoxgr_criteria_ctcv5.rda and b/data/atoxgr_criteria_ctcv5.rda differ diff --git a/data/atoxgr_criteria_daids.rda b/data/atoxgr_criteria_daids.rda new file mode 100644 index 0000000000..93cba5cc21 Binary files /dev/null and b/data/atoxgr_criteria_daids.rda differ diff --git a/docs/pkgdown.yml b/docs/pkgdown.yml deleted file mode 100644 index 8492dafdf7..0000000000 --- a/docs/pkgdown.yml +++ /dev/null @@ -1,26 +0,0 @@ -pandoc: 2.11.4 -pkgdown: 2.0.7 -pkgdown_sha: ~ -articles: - admiral: admiral.html - adsl: adsl.html - bds_exposure: bds_exposure.html - bds_finding: bds_finding.html - bds_tte: bds_tte.html - contribution_model: contribution_model.html - faq: faq.html - generic: generic.html - higher_order: higher_order.html - hys_law: hys_law.html - imputation: imputation.html - lab_grading: lab_grading.html - occds: occds.html - pk_adnca: pk_adnca.html - queries_dataset: queries_dataset.html - questionnaires: questionnaires.html - visits_periods: visits_periods.html -last_built: 2023-05-31T14:16Z -urls: - reference: https://pharmaverse.github.io/admiral/cran-release/reference - article: https://pharmaverse.github.io/admiral/cran-release/articles - diff --git a/inst/WORDLIST b/inst/WORDLIST index 9dc1141688..c8b09c2850 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -21,6 +21,7 @@ AELLTCD AENDTM AEs AFRLT +ANC ANRLO APRLT ARRLT @@ -31,8 +32,12 @@ ATC ATOXGR AVAL AVISITN +Abercrombie +Akinyi +Alkalosis Alanine Analyte +Ania Aspartate BDS BILI @@ -55,11 +60,16 @@ CTCAE CTCAEV CTCAEv CVD +Carlucci +Chemistries Chol Cockcroft Creat +Creatine Creatinine D'Agostino +Duniec +DAIDs DIABP DILI DT @@ -68,16 +78,21 @@ DTF DTM DURD Datetime +Daniil +Declan +Denney DuBois Durations EMA EOSSTT EPI +Ehmann FACM FCVD Fibrinogen Findability Framingham +Franciszek Fridericia Fridericia's Fujimoto @@ -87,12 +102,16 @@ GRPID GRPNAME GSK Gault +Gayatri Gehan GlaxoSmithKline Glomerular +Golab GxP HDL Haptoglobin +Hamza +Hodges Hoffmann Hy's Hypercalcemia @@ -109,19 +128,37 @@ Hyponatremia Hypophosphatemia IG INR +Jaxon +Jordanna +Kabi +Kamila +Khatri +Koeger +Konstantina +Koukourikou +Kumar +Kumari +LDL LLC LLOQ LOCF +Lee +Leena Leukocytosis Lipase +Liu MDRD MH MRRLT +McGavigan MedDRA Meds Metatools +Methemoglobin Modularity +Morrish Mosteller +Mubasheer NCA NCI NCICTCAEv @@ -131,21 +168,30 @@ NRRLT NUM Neutrophil Nom +Nonfasting +O'Reilly OCCDS +Ojesh +Omnes +Ondrej PARAM PARAMCD PARAMN PHUSE PLDOSE +PTT Param +Pavan Pharma Pharmacokinetic Pharmacokinetics +Pooja Pre QD QID -Quosures README +Rahal +Ratford SCE SCN SCOPEN @@ -161,8 +207,15 @@ SRCVAR SYSBP Sagie Sagie's +Samia +Shan +Shapcott +Shimeng +Slama +Stefonishin Subperiod Subperiods +Syed Sys TADJ TADJAE @@ -176,12 +229,21 @@ TMF TNDOSINT TPDOSE Takahira +Teckla +Thanikachalam Timepoint ULN USUBJID +USUBJIDs +Upadhyay VAD +Vignesh WBC +Walkowiak +Wenyi +Yohann XXXXXXXX +acknowledgements adam adamig adeg @@ -214,6 +276,7 @@ constructible creatinine ctcv dL +daids datacut datepart datetime @@ -240,6 +303,7 @@ groupwise hms https lockfile +lubridate mL magrittr metacore @@ -248,11 +312,11 @@ mmHg mmol modularized msec -nolint occds onwards parttime pharmaverse +pharmaversesdtm phosphatase poppk pre @@ -265,7 +329,6 @@ rlang roche roxygen scalable -str submittable subperiod subperiods @@ -273,7 +336,9 @@ subscale summarization th thromboplastin +tidyselect tidyverse +tidyselect timeframe timepart timepoint @@ -287,3 +352,7 @@ xportr xpt α κ +admiraldev +admiralophtha +admiralvaccine + diff --git a/inst/adlb_grading/adlb_grading_spec.xlsx b/inst/adlb_grading/adlb_grading_spec.xlsx old mode 100755 new mode 100644 index 116090de13..8ed3e1c4d9 Binary files a/inst/adlb_grading/adlb_grading_spec.xlsx and b/inst/adlb_grading/adlb_grading_spec.xlsx differ diff --git a/inst/adlb_grading/atoxgr_sources.R b/inst/adlb_grading/atoxgr_sources.R index 99e7c45207..30cfab2aad 100644 --- a/inst/adlb_grading/atoxgr_sources.R +++ b/inst/adlb_grading/atoxgr_sources.R @@ -14,3 +14,9 @@ atoxgr_criteria_ctcv5 <- atoxgr_criteria %>% dplyr::mutate(GRADE_CRITERIA_CODE = gsub("[\r\n]", " ", GRADE_CRITERIA_CODE)) save(atoxgr_criteria_ctcv5, file = "data/atoxgr_criteria_ctcv5.rda") + +atoxgr_criteria_daids <- atoxgr_criteria %>% + readxl::read_excel(sheet = "DAIDS") %>% + dplyr::mutate(GRADE_CRITERIA_CODE = gsub("[\r\n]", " ", GRADE_CRITERIA_CODE)) + +save(atoxgr_criteria_daids, file = "data/atoxgr_criteria_daids.rda") diff --git a/inst/example_scripts/derive_single_dose.R b/inst/example_scripts/derive_single_dose.R index e94bb13d2c..17900e05bc 100644 --- a/inst/example_scripts/derive_single_dose.R +++ b/inst/example_scripts/derive_single_dose.R @@ -1,9 +1,7 @@ - -library(admiral.test) +library(pharmaversesdtm) library(admiral) library(dplyr) -data(admiral_ex) -ex <- admiral_ex +data(ex) # check that there is only one start/end date of exposure per subject and visit check_cond <- ex %>% diff --git a/inst/templates/ad_adae.R b/inst/templates/ad_adae.R index 4e0929d08f..e9a5e64480 100644 --- a/inst/templates/ad_adae.R +++ b/inst/templates/ad_adae.R @@ -4,7 +4,7 @@ # # Input: ae, adsl, ex_single library(admiral) -library(admiral.test) # Contains example datasets from the CDISC pilot project +library(pharmaversesdtm) # Contains example datasets from the CDISC pilot project library(dplyr) library(lubridate) @@ -14,13 +14,12 @@ library(lubridate) # as needed and assign to the variables below. # For illustration purposes read in admiral test data -data("admiral_ae") +data("ae") data("admiral_adsl") data("ex_single") +data("suppae") adsl <- admiral_adsl -ae <- admiral_ae -suppae <- admiral_suppae # When SAS datasets are imported into R using haven::read_sas(), missing # character values from SAS appear as "" characters in R, instead of appearing diff --git a/inst/templates/ad_adcm.R b/inst/templates/ad_adcm.R index 1dedb7919c..2b72783349 100644 --- a/inst/templates/ad_adcm.R +++ b/inst/templates/ad_adcm.R @@ -4,7 +4,7 @@ # # Input: cm, adsl library(admiral) -library(admiral.test) # Contains example datasets from the CDISC pilot project +library(pharmaversesdtm) # Contains example datasets from the CDISC pilot project library(dplyr) library(lubridate) @@ -14,11 +14,10 @@ library(lubridate) # as needed and assign to the variables below. # For illustration purposes read in admiral test data -data("admiral_cm") +data("cm") data("admiral_adsl") adsl <- admiral_adsl -cm <- admiral_cm # When SAS datasets are imported into R using haven::read_sas(), missing # character values from SAS appear as "" characters in R, instead of appearing @@ -77,7 +76,7 @@ adcm <- cm %>% ## Derive flags ---- adcm <- adcm %>% # Derive On-Treatment flag - # Set `span_period = "Y"` if you want occurrences that started prior to drug + # Set `span_period = TRUE` if you want occurrences that started prior to drug # intake and ongoing or ended after this time to be considered as on-treatment. derive_var_ontrtfl( start_date = ASTDT, diff --git a/inst/templates/ad_adeg.R b/inst/templates/ad_adeg.R index 523491a82b..62a680a7da 100644 --- a/inst/templates/ad_adeg.R +++ b/inst/templates/ad_adeg.R @@ -6,7 +6,7 @@ # # Input: adsl, eg library(admiral) -library(admiral.test) # Contains example datasets from the CDISC pilot project +library(pharmaversesdtm) # Contains example datasets from the CDISC pilot project library(dplyr) library(lubridate) library(stringr) @@ -18,10 +18,10 @@ library(stringr) # For illustration purposes read in admiral test data data("admiral_adsl") -data("admiral_eg") +data("eg") adsl <- admiral_adsl -eg <- admiral_eg +eg <- eg # When SAS datasets are imported into R using haven::read_sas(), missing # character values from SAS appear as "" characters in R, instead of appearing diff --git a/inst/templates/ad_adex.R b/inst/templates/ad_adex.R index 048e8ccc93..aa6f5b40d3 100644 --- a/inst/templates/ad_adex.R +++ b/inst/templates/ad_adex.R @@ -6,7 +6,7 @@ # library(admiral) -library(admiral.test) # Contains example datasets from the CDISC pilot project +library(pharmaversesdtm) # Contains example datasets from the CDISC pilot project library(dplyr) library(lubridate) library(stringr) @@ -16,10 +16,9 @@ library(stringr) # as needed and assign to the variables below. # The CDISC pilot datasets are used for demonstration purpose. data("admiral_adsl") -data("admiral_ex") +data("ex") adsl <- admiral_adsl -ex <- admiral_ex # When SAS datasets are imported into R using haven::read_sas(), missing # character values from SAS appear as "" characters in R, instead of appearing @@ -214,13 +213,17 @@ adex <- adex %>% variable_params = list( params( parameters = c("TDOSE", "TDURD"), - analysis_value = (AVAL.TDOSE / AVAL.TDURD), - set_values_to = exprs(PARAMCD = "AVDDSE") + set_values_to = exprs( + AVAL = (AVAL.TDOSE / AVAL.TDURD), + PARAMCD = "AVDDSE" + ) ), params( parameters = c("PDOSE", "PDURD"), - analysis_value = (AVAL.PDOSE / AVAL.PDURD), - set_values_to = exprs(PARAMCD = "PAVDDSE") + set_values_to = exprs( + AVAL = (AVAL.PDOSE / AVAL.PDURD), + PARAMCD = "PAVDDSE" + ) ) ), by_vars = exprs( diff --git a/inst/templates/ad_adlb.R b/inst/templates/ad_adlb.R index 22275b11a5..99194bf71d 100644 --- a/inst/templates/ad_adlb.R +++ b/inst/templates/ad_adlb.R @@ -4,7 +4,7 @@ # # Input: adsl, lb library(admiral) -library(admiral.test) # Contains example datasets from the CDISC pilot project +library(pharmaversesdtm) # Contains example datasets from the CDISC pilot project library(dplyr) library(lubridate) library(stringr) @@ -15,10 +15,9 @@ library(stringr) # as needed and assign to the variables below. # For illustration purposes read in admiral test data -data("admiral_lb") +data("lb") data("admiral_adsl") -lb <- admiral_lb adsl <- admiral_adsl # When SAS datasets are imported into R using haven::read_sas(), missing diff --git a/inst/templates/ad_adlbhy.R b/inst/templates/ad_adlbhy.R index 03664ab1c5..7b5458a807 100644 --- a/inst/templates/ad_adlbhy.R +++ b/inst/templates/ad_adlbhy.R @@ -4,7 +4,6 @@ # # Input: adlb library(admiral) -library(admiral.test) # Contains example datasets from the CDISC pilot project library(dplyr) library(lubridate) diff --git a/inst/templates/ad_admh.R b/inst/templates/ad_admh.R index aa77e2193f..76a8120308 100644 --- a/inst/templates/ad_admh.R +++ b/inst/templates/ad_admh.R @@ -4,7 +4,7 @@ # # Input: mh, adsl library(admiral) -library(admiral.test) # Contains example datasets from the CDISC pilot project +library(pharmaversesdtm) # Contains example datasets from the CDISC pilot project library(dplyr) library(lubridate) @@ -13,12 +13,11 @@ library(lubridate) # Use e.g. haven::read_sas to read in .sas7bdat, or other suitable functions # as needed and assign to the variables below. # For illustration purposes read in admiral test data -data("admiral_mh") +data("mh") data("admiral_adsl") data("queries_mh") adsl <- admiral_adsl -mh <- admiral_mh mh <- convert_blanks_to_na(mh) diff --git a/inst/templates/ad_adpc.R b/inst/templates/ad_adpc.R index dda1a1991a..dc13c425f5 100644 --- a/inst/templates/ad_adpc.R +++ b/inst/templates/ad_adpc.R @@ -11,7 +11,7 @@ library(dplyr) library(lubridate) library(stringr) -library(admiral.test) # Contains example datasets from the CDISC pilot project or simulated +library(pharmaversesdtm) # Contains example datasets from the CDISC pilot project or simulated # ---- Load source datasets ---- @@ -21,9 +21,9 @@ library(admiral.test) # Contains example datasets from the CDISC pilot project o # Load PC, EX, VS and ADSL -data("admiral_pc") -data("admiral_ex") -data("admiral_vs") +data("pc") +data("ex") +data("vs") data("admiral_adsl") @@ -36,15 +36,15 @@ adsl <- admiral_adsl # Load EX -ex <- convert_blanks_to_na(admiral_ex) +ex <- convert_blanks_to_na(ex) # Load PC -pc <- convert_blanks_to_na(admiral_pc) +pc <- convert_blanks_to_na(pc) # Load VS for baseline height and weight -vs <- convert_blanks_to_na(admiral_vs) +vs <- convert_blanks_to_na(vs) # ---- Lookup tables ---- param_lookup <- tibble::tribble( diff --git a/inst/templates/ad_adpp.R b/inst/templates/ad_adpp.R index c215c5cdeb..d1acd39964 100644 --- a/inst/templates/ad_adpp.R +++ b/inst/templates/ad_adpp.R @@ -6,7 +6,7 @@ # # Input: pp, adsl library(admiral) -library(admiral.test) # Contains example datasets from the CDISC pilot project +library(pharmaversesdtm) # Contains example datasets from the CDISC pilot project library(dplyr) library(lubridate) library(stringr) @@ -19,7 +19,7 @@ library(stringr) # For illustration purposes read in admiral test data # Load PP and Adsl -data("admiral_pp") +data("pp") data("admiral_adsl") # When SAS datasets are imported into R using haven::read_sas(), missing @@ -27,7 +27,7 @@ data("admiral_adsl") # as NA values. Further details can be obtained via the following link: # https://pharmaverse.github.io/admiral/cran-release/articles/admiral.html#handling-of-missing-values # nolint -pp <- convert_blanks_to_na(admiral_pp) +pp <- convert_blanks_to_na(pp) # Lookup tables ---- param_lookup <- tibble::tribble( diff --git a/inst/templates/ad_adppk.R b/inst/templates/ad_adppk.R index ea4ceb122b..c16ec615b6 100644 --- a/inst/templates/ad_adppk.R +++ b/inst/templates/ad_adppk.R @@ -9,8 +9,7 @@ library(admiral) library(dplyr) library(lubridate) library(stringr) - -library(admiral.test) # Contains example datasets from the CDISC pilot project or simulated +library(pharmaversesdtm) # Contains example datasets from the CDISC pilot project or simulated # ---- Load source datasets ---- @@ -19,10 +18,10 @@ library(admiral.test) # Contains example datasets from the CDISC pilot project o # For illustration purposes read in admiral test data # Load PC, EX, VS, LB and ADSL -data("admiral_pc") -data("admiral_ex") -data("admiral_vs") -data("admiral_lb") +data("pc") +data("ex") +data("vs") +data("lb") data("admiral_adsl") @@ -33,21 +32,10 @@ adsl <- admiral_adsl # as NA values. Further details can be obtained via the following link: # https://pharmaverse.github.io/admiral/cran-release/articles/admiral.html#handling-of-missing-values # nolint -# Load EX - -ex <- convert_blanks_to_na(admiral_ex) - -# Load PC - -pc <- convert_blanks_to_na(admiral_pc) - -# Load VS for baseline height and weight - -vs <- convert_blanks_to_na(admiral_vs) - -# Load LB for baseline lab values - -lb <- convert_blanks_to_na(admiral_lb) +ex <- convert_blanks_to_na(ex) +pc <- convert_blanks_to_na(pc) +vs <- convert_blanks_to_na(vs) +lb <- convert_blanks_to_na(lb) # ---- Lookup tables ---- param_lookup <- tibble::tribble( @@ -448,11 +436,11 @@ covar_vslb <- covar %>% method = "Mosteller" ), CRCLBL = compute_egfr( - creat = CREATBL, creatu = "SI", age = AGE, wt = WTBL, sex = SEX, + creat = CREATBL, creatu = "SI", age = AGE, weight = WTBL, sex = SEX, method = "CRCL" ), EGFRBL = compute_egfr( - creat = CREATBL, creatu = "SI", age = AGE, wt = WTBL, sex = SEX, + creat = CREATBL, creatu = "SI", age = AGE, weight = WTBL, sex = SEX, method = "CKD-EPI" ) ) %>% diff --git a/inst/templates/ad_adsl.R b/inst/templates/ad_adsl.R index 59a7d45fbe..161fcd87e8 100644 --- a/inst/templates/ad_adsl.R +++ b/inst/templates/ad_adsl.R @@ -4,7 +4,7 @@ # # Input: dm, ex, ds library(admiral) -library(admiral.test) # Contains example datasets from the CDISC pilot project +library(pharmaversesdtm) # Contains example datasets from the CDISC pilot project library(dplyr) library(lubridate) library(stringr) @@ -15,17 +15,11 @@ library(stringr) # as needed and assign to the variables below. # For illustration purposes read in admiral test data -data("admiral_dm") -data("admiral_ds") -data("admiral_ex") -data("admiral_ae") -data("admiral_lb") - -dm <- admiral_dm -ds <- admiral_ds -ex <- admiral_ex -ae <- admiral_ae -lb <- admiral_lb +data("dm") +data("ds") +data("ex") +data("ae") +data("lb") # When SAS datasets are imported into R using haven::read_sas(), missing # character values from SAS appear as "" characters in R, instead of appearing diff --git a/inst/templates/ad_advs.R b/inst/templates/ad_advs.R index eb0977ce9d..1e43d8391d 100644 --- a/inst/templates/ad_advs.R +++ b/inst/templates/ad_advs.R @@ -4,7 +4,7 @@ # # Input: adsl, vs library(admiral) -library(admiral.test) # Contains example datasets from the CDISC pilot project +library(pharmaversesdtm) # Contains example datasets from the CDISC pilot project library(dplyr) library(lubridate) library(stringr) @@ -15,11 +15,10 @@ library(stringr) # as needed and assign to the variables below. # For illustration purposes read in admiral test data -data("admiral_vs") +data("vs") data("admiral_adsl") adsl <- admiral_adsl -vs <- admiral_vs # When SAS datasets are imported into R using haven::read_sas(), missing # character values from SAS appear as "" characters in R, instead of appearing @@ -121,14 +120,16 @@ advs <- advs %>% method = "Mosteller", set_values_to = exprs(PARAMCD = "BSA"), get_unit_expr = VSSTRESU, - filter = VSSTAT != "NOT DONE" | is.na(VSSTAT) + filter = VSSTAT != "NOT DONE" | is.na(VSSTAT), + constant_by_vars = exprs(USUBJID) ) %>% # Derive Body Mass Index derive_param_bmi( by_vars = exprs(STUDYID, USUBJID, !!!adsl_vars, VISIT, VISITNUM, ADT, ADY, VSTPT, VSTPTNUM), set_values_to = exprs(PARAMCD = "BMI"), get_unit_expr = VSSTRESU, - filter = VSSTAT != "NOT DONE" | is.na(VSSTAT) + filter = VSSTAT != "NOT DONE" | is.na(VSSTAT), + constant_by_vars = exprs(USUBJID) ) diff --git a/man/admiral-package.Rd b/man/admiral-package.Rd index ad3bdb6975..96835f9ebf 100644 --- a/man/admiral-package.Rd +++ b/man/admiral-package.Rd @@ -25,65 +25,25 @@ Useful links: Authors: \itemize{ \item Stefan Bundfuss - \item Thomas Neitmann - \item Samia Kabi - \item Gordon Miller - \item Teckla Akinyi - \item Andrew Smith - \item Konstantina Koukourikou - \item Ross Farrugia - \item Eric Simms - \item Annie Yang - \item Robin Koeger - \item Sophie Shapcott - \item Ojesh Upadhyay - \item Jack McGavigan - \item Kamila Duniec - \item Gayatri G - \item Alana Harris - \item Mahdi About - \item Pooja Kumari - \item Claudia Carlucci - \item Daniil Stefonishin - \item Sadchla Mascary - \item Zelos Zhu \item Jeffrey Dickinson - \item Ania Golab - \item Kangjie Zhang - \item Daphne Grasselly + \item Ross Farrugia \item Adam Forys + \item Daphne Grasselly + \item Dinakar Kulkarni \item Edoardo Mancini + \item Sadchla Mascary + \item Gordon Miller + \item Sophie Shapcott + \item Eric Simms \item Stefan Thoma + \item Kangjie Zhang + \item Zelos Zhu } Other contributors: \itemize{ - \item Michael Thorpe [contributor] - \item Declan Hodges [contributor] - \item Jaxon Abercrombie [contributor] - \item Nick Ramirez [contributor] - \item Pavan Kumar [contributor] - \item Hamza Rahal [contributor] - \item Yohann Omnes [contributor] - \item Alice Ehmann [contributor] - \item Tom Ratford [contributor] - \item Vignesh Thanikachalam [contributor] - \item Ondrej Slama [contributor] - \item Shimeng Huang [contributor] - \item James Kim [contributor] - \item Shan Lee [contributor] - \item Bill Denney [contributor] - \item Syed Mubasheer [contributor] - \item Wenyi Liu [contributor] - \item Dinakar Kulkarni [contributor] - \item Franciszek Walkowiak [contributor] - \item Tamara Senior [contributor] - \item Jordanna Morrish [contributor] - \item Anthony Howard [contributor] - \item Barbara O'Reilly [contributor] - \item John Kirkpatrick [contributor] - \item James Black [contributor] - \item Leena Khatri [contributor] + \item G Gayatri [contributor] + \item Thomas Neitmann [contributor] \item F. Hoffmann-La Roche AG [copyright holder, funder] \item GlaxoSmithKline LLC [copyright holder, funder] } diff --git a/man/assert_db_requirements.Rd b/man/assert_db_requirements.Rd index 80bf8bd57f..728d4bbd57 100644 --- a/man/assert_db_requirements.Rd +++ b/man/assert_db_requirements.Rd @@ -35,13 +35,11 @@ database must be provided. The function checks these requirements. } \seealso{ Other Advanced Functions: -\code{\link{assert_parameters_argument}()}, \code{\link{assert_terms}()}, \code{\link{assert_valid_queries}()}, \code{\link{extend_source_datasets}()}, \code{\link{filter_date_sources}()}, \code{\link{format.basket_select}()}, -\code{\link{get_hori_data}()}, \code{\link{list_tte_source_objects}()}, \code{\link{params}()}, \code{\link{validate_basket_select}()}, diff --git a/man/assert_parameters_argument.Rd b/man/assert_parameters_argument.Rd index 50974eb92d..867006f937 100644 --- a/man/assert_parameters_argument.Rd +++ b/man/assert_parameters_argument.Rd @@ -21,19 +21,4 @@ The function asserts that the argument is a character vector or a list of expressions. If it is a character vector, it converts it to a list of symbols. } -\seealso{ -Other Advanced Functions: -\code{\link{assert_db_requirements}()}, -\code{\link{assert_terms}()}, -\code{\link{assert_valid_queries}()}, -\code{\link{extend_source_datasets}()}, -\code{\link{filter_date_sources}()}, -\code{\link{format.basket_select}()}, -\code{\link{get_hori_data}()}, -\code{\link{list_tte_source_objects}()}, -\code{\link{params}()}, -\code{\link{validate_basket_select}()}, -\code{\link{validate_query}()} -} -\concept{other_advanced} -\keyword{other_advanced} +\keyword{internal} diff --git a/man/assert_terms.Rd b/man/assert_terms.Rd index d88f8bab5e..ca69eff34f 100644 --- a/man/assert_terms.Rd +++ b/man/assert_terms.Rd @@ -45,12 +45,10 @@ try( Other Advanced Functions: \code{\link{assert_db_requirements}()}, -\code{\link{assert_parameters_argument}()}, \code{\link{assert_valid_queries}()}, \code{\link{extend_source_datasets}()}, \code{\link{filter_date_sources}()}, \code{\link{format.basket_select}()}, -\code{\link{get_hori_data}()}, \code{\link{list_tte_source_objects}()}, \code{\link{params}()}, \code{\link{validate_basket_select}()}, diff --git a/man/assert_valid_queries.Rd b/man/assert_valid_queries.Rd index 421d207018..925bc6c63d 100644 --- a/man/assert_valid_queries.Rd +++ b/man/assert_valid_queries.Rd @@ -39,12 +39,10 @@ assert_valid_queries(queries, "queries") \seealso{ Other Advanced Functions: \code{\link{assert_db_requirements}()}, -\code{\link{assert_parameters_argument}()}, \code{\link{assert_terms}()}, \code{\link{extend_source_datasets}()}, \code{\link{filter_date_sources}()}, \code{\link{format.basket_select}()}, -\code{\link{get_hori_data}()}, \code{\link{list_tte_source_objects}()}, \code{\link{params}()}, \code{\link{validate_basket_select}()}, diff --git a/man/atoxgr_criteria_ctcv4.Rd b/man/atoxgr_criteria_ctcv4.Rd index 3a3c286b47..00e0a8ee32 100644 --- a/man/atoxgr_criteria_ctcv4.Rd +++ b/man/atoxgr_criteria_ctcv4.Rd @@ -47,6 +47,7 @@ traceability only. \seealso{ Other metadata: \code{\link{atoxgr_criteria_ctcv5}}, +\code{\link{atoxgr_criteria_daids}}, \code{\link{dose_freq_lookup}} } \concept{metadata} diff --git a/man/atoxgr_criteria_ctcv5.Rd b/man/atoxgr_criteria_ctcv5.Rd index 4d6c041650..70a3ef5aaa 100644 --- a/man/atoxgr_criteria_ctcv5.Rd +++ b/man/atoxgr_criteria_ctcv5.Rd @@ -47,6 +47,7 @@ traceability only. \seealso{ Other metadata: \code{\link{atoxgr_criteria_ctcv4}}, +\code{\link{atoxgr_criteria_daids}}, \code{\link{dose_freq_lookup}} } \concept{metadata} diff --git a/man/atoxgr_criteria_daids.Rd b/man/atoxgr_criteria_daids.Rd new file mode 100644 index 0000000000..c17e78adae --- /dev/null +++ b/man/atoxgr_criteria_daids.Rd @@ -0,0 +1,56 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/data.R +\docType{data} +\name{atoxgr_criteria_daids} +\alias{atoxgr_criteria_daids} +\title{Metadata Holding Grading Criteria for DAIDs} +\format{ +An object of class \code{tbl_df} (inherits from \code{tbl}, \code{data.frame}) with 63 rows and 15 columns. +} +\usage{ +atoxgr_criteria_daids +} +\description{ +Metadata Holding Grading Criteria for DAIDs +} +\details{ +This metadata has its origin in the ADLB Grading Spec Excel file which ships with \code{{admiral}} +and can be accessed using \code{system.file("adlb_grading/adlb_grading_spec.xlsx", package = "admiral")} +in sheet = "DAIDS". +The dataset contained in there has the following columns: +\itemize{ +\item \code{SOC}: variable to hold the SOC of the lab test criteria. +\item \code{TERM}: variable to hold the term describing the criteria applied to a particular lab test, +eg. 'Anemia' or 'INR Increased'. Note: the variable is case insensitive. +\item \code{SUBGROUP} : Description of sub-group of subjects were grading will be applied (i.e. >= 18 years) +\item \verb{Grade 1}: Criteria defining lab value as Grade 1. +\item \verb{Grade 2}: Criteria defining lab value as Grade 2. +\item \verb{Grade 3}: Criteria defining lab value as Grade 3. +\item \verb{Grade 4}: Criteria defining lab value as Grade 4. +\item \verb{Grade 5}: Criteria defining lab value as Grade 5. +\item \code{Definition}: Holds the definition of the lab test abnormality. +\item \code{FILTER} : \code{admiral} code to apply the filter based on SUBGROUP column. +\item \code{GRADE_CRITERIA_CODE}: variable to hold code that creates grade based on defined criteria. +\item \code{SI_UNIT_CHECK}: variable to hold unit of particular lab test. Used to check against input data +if criteria is based on absolute values. +\item \code{VAR_CHECK}: List of variables required to implement lab grade criteria. Use to check against +input data. +\item \code{DIRECTION}: variable to hold the direction of the abnormality of a particular lab test +value. 'L' is for LOW values, 'H' is for HIGH values. Note: the variable is case insensitive. +\item \code{COMMENT}: Holds any information regarding rationale behind implementation of grading criteria. +} + +Note: Variables \code{SOC}, \code{TERM}, \code{SUBGROUP}, \verb{Grade 1}, \verb{Grade 2},\verb{Grade 3},\verb{Grade 4},\verb{Grade 5}, \code{Definition} +are from the source document on DAIDS website defining the grading criteria. +[Division of AIDS (DAIDS) Table for Grading the Severity of Adult and Pediatric Adverse Events +From these variables only 'TERM' is used in the {admiral} code, the rest are for information and +traceability only. +} +\seealso{ +Other metadata: +\code{\link{atoxgr_criteria_ctcv4}}, +\code{\link{atoxgr_criteria_ctcv5}}, +\code{\link{dose_freq_lookup}} +} +\concept{metadata} +\keyword{metadata} diff --git a/man/basket_select.Rd b/man/basket_select.Rd index 2eb207dcd4..82ca48a8d1 100644 --- a/man/basket_select.Rd +++ b/man/basket_select.Rd @@ -39,6 +39,7 @@ Source Objects: \code{\link{date_source}()}, \code{\link{death_event}}, \code{\link{dthcaus_source}()}, +\code{\link{event_joined}()}, \code{\link{event_source}()}, \code{\link{event}()}, \code{\link{query}()}, diff --git a/man/censor_source.Rd b/man/censor_source.Rd index b2c3d5f31b..e3c83c606e 100644 --- a/man/censor_source.Rd +++ b/man/censor_source.Rd @@ -67,6 +67,7 @@ Source Objects: \code{\link{date_source}()}, \code{\link{death_event}}, \code{\link{dthcaus_source}()}, +\code{\link{event_joined}()}, \code{\link{event_source}()}, \code{\link{event}()}, \code{\link{query}()}, diff --git a/man/compute_age_years.Rd b/man/compute_age_years.Rd index b4f4cfff56..6c1d05c440 100644 --- a/man/compute_age_years.Rd +++ b/man/compute_age_years.Rd @@ -19,7 +19,7 @@ permitted values are cases insensitive (e.g. \code{"YEARS"} is treated the same as \code{"years"} and \code{"Years"}). Permitted Values: \code{"years"}, \code{"months"}, \code{"weeks"}, \code{"days"}, \code{"hours"}, \code{"minutes"}, -\code{"seconds"}.} +\code{"seconds"}, \code{NA_character_}.} } \value{ The ages contained in \code{age} converted to years. @@ -28,8 +28,10 @@ The ages contained in \code{age} converted to years. Converts a set of age values from the specified time unit to years. } \details{ -Returns a numeric vector of ages in years as doubles. Note, underlying -computations assume an equal number of days in each year (365.25). +Returns a numeric vector of ages in years as doubles. Note +that passing \code{NA_character_} as a unit will result in an \code{NA} value for the outputted +age. Also note, underlying computations assume an equal number of days in each +year (365.25). } \examples{ compute_age_years( @@ -38,8 +40,8 @@ compute_age_years( ) compute_age_years( - age = c(10, 520, 3650), - age_unit = c("YEARS", "WEEKS", "DAYS") + age = c(10, 520, 3650, 1000), + age_unit = c("YEARS", "WEEKS", "DAYS", NA_character_) ) } diff --git a/man/compute_bmi.Rd b/man/compute_bmi.Rd index aa6177f15b..3c9e966d11 100644 --- a/man/compute_bmi.Rd +++ b/man/compute_bmi.Rd @@ -11,13 +11,13 @@ compute_bmi(height, weight) It is expected that HEIGHT is in cm. -Permitted Values: numeric vector} +\emph{Permitted Values:} numeric vector} \item{weight}{WEIGHT value It is expected that WEIGHT is in kg. -Permitted Values: numeric vector} +\emph{Permitted Values:} numeric vector} } \value{ The BMI (Body Mass Index Area) in kg/m^2. @@ -32,6 +32,8 @@ Usually this computation function can not be used with \verb{\%>\%}. compute_bmi(height = 170, weight = 75) } \seealso{ +\code{\link[=derive_param_bmi]{derive_param_bmi()}} + BDS-Findings Functions that returns a vector: \code{\link{compute_bsa}()}, \code{\link{compute_egfr}()}, diff --git a/man/compute_bsa.Rd b/man/compute_bsa.Rd index a8b3c9fe9e..ba887a10f9 100644 --- a/man/compute_bsa.Rd +++ b/man/compute_bsa.Rd @@ -11,13 +11,13 @@ compute_bsa(height = height, weight = weight, method) It is expected that HEIGHT is in cm. -Permitted Values: numeric vector} +\emph{Permitted Values:} numeric vector} \item{weight}{WEIGHT value It is expected that WEIGHT is in kg. -Permitted Values: numeric vector} +\emph{Permitted Values:} numeric vector} \item{method}{Derivation method to use: @@ -35,7 +35,7 @@ Fujimoto: 0.008883 * height ^ 0.663 * weight ^ 0.444 Takahira: 0.007241 * height ^ 0.725 * weight ^ 0.425 -Permitted Values: character value} +\emph{Permitted Values:} character value} } \value{ The BSA (Body Surface Area) in m^2. @@ -62,6 +62,8 @@ compute_bsa( ) } \seealso{ +\code{\link[=derive_param_bsa]{derive_param_bsa()}} + BDS-Findings Functions that returns a vector: \code{\link{compute_bmi}()}, \code{\link{compute_egfr}()}, diff --git a/man/compute_dtf.Rd b/man/compute_dtf.Rd index 18f0c816b4..0875ce16e8 100644 --- a/man/compute_dtf.Rd +++ b/man/compute_dtf.Rd @@ -28,6 +28,10 @@ Usually this computation function can not be used with \verb{\%>\%}. \examples{ compute_dtf(dtc = "2019-07", dt = as.Date("2019-07-18")) compute_dtf(dtc = "2019", dt = as.Date("2019-07-18")) +compute_dtf(dtc = "--06-01T00:00", dt = as.Date("2022-06-01")) +compute_dtf(dtc = "2022-06--T00:00", dt = as.Date("2022-06-01")) +compute_dtf(dtc = "2022---01T00:00", dt = as.Date("2022-06-01")) +compute_dtf(dtc = "2022----T00:00", dt = as.Date("2022-06-01")) } \seealso{ Date/Time Computation Functions that returns a vector: diff --git a/man/compute_duration.Rd b/man/compute_duration.Rd index 4439f55239..08ece00103 100644 --- a/man/compute_duration.Rd +++ b/man/compute_duration.Rd @@ -11,7 +11,8 @@ compute_duration( out_unit = "days", floor_in = TRUE, add_one = TRUE, - trunc_out = FALSE + trunc_out = FALSE, + type = "duration" ) } \arguments{ @@ -77,6 +78,14 @@ integer part is returned. Default: \code{FALSE} Permitted Values: \code{TRUE}, \code{FALSE}} + +\item{type}{lubridate duration type. + +See below for details. + +Default: \code{"duration"} + +Permitted Values: \code{"duration"}, \code{"interval"}} } \value{ The duration between the two date in the specified unit @@ -90,6 +99,28 @@ The output is a numeric vector providing the duration as time from start to end date in the specified unit. If the end date is before the start date, the duration is negative. } +\section{Duration Type}{ + + +The \href{https://lubridate.tidyverse.org/}{lubridate} package calculates two +types of spans between two dates: duration and interval. +While these calculations are largely the same, when the unit of the time period +is month or year the result can be slightly different. + +The difference arises from the ambiguity in the length of \code{"1 month"} or +\code{"1 year"}. +Months may have 31, 30, 28, or 29 days, and years are 365 days and 366 during leap years. +Durations and intervals help solve the ambiguity in these measures. + +The \strong{interval} between \code{2000-02-01} and \code{2000-03-01} is \code{1} (i.e. one month). +The \strong{duration} between these two dates is \code{0.95}, which accounts for the fact +that the year 2000 is a leap year, February has 29 days, and the average month +length is \code{30.4375}, i.e. \code{29 / 30.4375 = 0.95}. + +For additional details, review the +\href{https://lubridate.tidyverse.org/reference/timespan.html}{lubridate time span reference page}. +} + \examples{ library(lubridate) @@ -126,6 +157,8 @@ compute_duration( ) } \seealso{ +\code{\link[=derive_vars_duration]{derive_vars_duration()}} + Date/Time Computation Functions that returns a vector: \code{\link{compute_age_years}()}, \code{\link{compute_dtf}()}, diff --git a/man/compute_egfr.Rd b/man/compute_egfr.Rd index db34c29df7..746f387d8f 100644 --- a/man/compute_egfr.Rd +++ b/man/compute_egfr.Rd @@ -4,7 +4,7 @@ \alias{compute_egfr} \title{Compute Estimated Glomerular Filtration Rate (eGFR) for Kidney Function} \usage{ -compute_egfr(creat, creatu = "SI", age, wt, sex, race = NULL, method) +compute_egfr(creat, creatu = "SI", age, weight, sex, race = NULL, method, wt) } \arguments{ \item{creat}{Creatinine @@ -23,7 +23,7 @@ Expected Values: \code{"SI"}, \code{"CV"}, \code{"umol/L"}, \code{"mg/dL"}} A numeric vector is expected.} -\item{wt}{Weight (kg) +\item{weight}{Weight (kg) A numeric vector is expected if \code{method = "CRCL"}} @@ -44,6 +44,8 @@ Expected Values: \code{"BLACK OR AFRICAN AMERICAN"} and others} A character vector is expected. Expected Values: \code{"CRCL"}, \code{"CKD-EPI"}, \code{"MDRD"}} + +\item{wt}{\emph{Deprecated}, please use \code{weight} instead.} } \value{ A numeric vector of egfr values @@ -97,7 +99,7 @@ units = mL/min/1.73 m2 } \examples{ compute_egfr( - creat = 90, creatu = "umol/L", age = 53, wt = 85, sex = "M", method = "CRCL" + creat = 90, creatu = "umol/L", age = 53, weight = 85, sex = "M", method = "CRCL" ) compute_egfr( @@ -125,15 +127,15 @@ base <- tibble::tribble( base \%>\% dplyr::mutate( CRCL_CG = compute_egfr( - creat = CREATBL, creatu = CREATBLU, age = AGE, wt = WTBL, sex = SEX, + creat = CREATBL, creatu = CREATBLU, age = AGE, weight = WTBL, sex = SEX, method = "CRCL" ), EGFR_EPI = compute_egfr( - creat = CREATBL, creatu = CREATBLU, age = AGE, wt = WTBL, sex = SEX, + creat = CREATBL, creatu = CREATBLU, age = AGE, weight = WTBL, sex = SEX, method = "CKD-EPI" ), EGFR_MDRD = compute_egfr( - creat = CREATBL, creatu = CREATBLU, age = AGE, wt = WTBL, sex = SEX, + creat = CREATBL, creatu = CREATBLU, age = AGE, weight = WTBL, sex = SEX, race = RACE, method = "MDRD" ), ) diff --git a/man/compute_map.Rd b/man/compute_map.Rd index 2677ee2ced..59902e7f0c 100644 --- a/man/compute_map.Rd +++ b/man/compute_map.Rd @@ -43,6 +43,8 @@ compute_map(diabp = 51, sysbp = 121) compute_map(diabp = 51, sysbp = 121, hr = 59) } \seealso{ +\code{\link[=derive_param_map]{derive_param_map()}} + BDS-Findings Functions that returns a vector: \code{\link{compute_bmi}()}, \code{\link{compute_bsa}()}, diff --git a/man/compute_qtc.Rd b/man/compute_qtc.Rd index 746a107973..a484776b47 100644 --- a/man/compute_qtc.Rd +++ b/man/compute_qtc.Rd @@ -45,6 +45,8 @@ compute_qtc(qt = 350, rr = 56.54, method = "Fridericia") compute_qtc(qt = 350, rr = 56.54, method = "Sagie") } \seealso{ +\code{\link[=derive_param_qtc]{derive_param_qtc()}} + BDS-Findings Functions that returns a vector: \code{\link{compute_bmi}()}, \code{\link{compute_bsa}()}, diff --git a/man/compute_rr.Rd b/man/compute_rr.Rd index 518c4d10d6..ba98aaba3e 100644 --- a/man/compute_rr.Rd +++ b/man/compute_rr.Rd @@ -26,6 +26,8 @@ Usually this computation function can not be used with \verb{\%>\%}. compute_rr(hr = 70.14) } \seealso{ +\code{\link[=derive_param_rr]{derive_param_rr()}} + BDS-Findings Functions that returns a vector: \code{\link{compute_bmi}()}, \code{\link{compute_bsa}()}, diff --git a/man/create_query_data.Rd b/man/create_query_data.Rd index 1f7ca894a2..4a6e14e02f 100644 --- a/man/create_query_data.Rd +++ b/man/create_query_data.Rd @@ -108,7 +108,7 @@ specified, the variable is not created. \examples{ library(tibble) library(dplyr, warn.conflicts = FALSE) -library(admiral.test) +library(pharmaversesdtm) library(admiral) # creating a query dataset for a customized query @@ -147,11 +147,11 @@ bilismq <- query( ) ) -# The get_terms function from admiral.test is used for this example. +# The get_terms function from pharmaversesdtm is used for this example. # In a real application a company-specific function must be used. create_query_data( queries = list(pregsmq, bilismq), - get_terms_fun = admiral.test:::get_terms, + get_terms_fun = pharmaversesdtm:::get_terms, version = "20.1" ) @@ -166,16 +166,16 @@ sdg <- query( ) ) -# The get_terms function from admiral.test is used for this example. +# The get_terms function from pharmaversesdtm is used for this example. # In a real application a company-specific function must be used. create_query_data( queries = list(sdg), - get_terms_fun = admiral.test:::get_terms, + get_terms_fun = pharmaversesdtm:::get_terms, version = "2019-09" ) # creating a query dataset for a customized query including SMQs -# The get_terms function from admiral.test is used for this example. +# The get_terms function from pharmaversesdtm is used for this example. # In a real application a company-specific function must be used. create_query_data( queries = list( @@ -192,7 +192,7 @@ create_query_data( ) ) ), - get_terms_fun = admiral.test:::get_terms, + get_terms_fun = pharmaversesdtm:::get_terms, version = "20.1" ) } diff --git a/man/date_source.Rd b/man/date_source.Rd index e9fd8e1a52..fd45481e12 100644 --- a/man/date_source.Rd +++ b/man/date_source.Rd @@ -4,7 +4,13 @@ \alias{date_source} \title{Create a \code{date_source} object} \usage{ -date_source(dataset_name, filter = NULL, date, traceability_vars = NULL) +date_source( + dataset_name, + filter = NULL, + date, + traceability_vars = NULL, + set_values_to = NULL +) } \arguments{ \item{dataset_name}{The name of the dataset, i.e. a string, used to search for @@ -17,7 +23,11 @@ datetime can be specified. An unquoted symbol or expression is expected.} \item{traceability_vars}{A named list returned by \code{exprs()} defining the traceability variables, e.g. \code{exprs(LALVDOM = "AE", LALVSEQ = AESEQ, LALVVAR = "AESTDTC")}. The values must be a symbol, a character string, a numeric, -an expression, or \code{NA}.} +an expression, or \code{NA}. + +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Please use \code{set_values_to} instead.} + +\item{set_values_to}{Variables to be set} } \value{ An object of class \code{date_source}. @@ -45,7 +55,7 @@ lb_date <- date_source( death_date <- date_source( dataset_name = "adsl", date = DTHDT, - traceability_vars = exprs( + set_values_to = exprs( LALVDOM = "ADSL", LALVVAR = "DTHDT" ) @@ -59,6 +69,7 @@ Source Objects: \code{\link{censor_source}()}, \code{\link{death_event}}, \code{\link{dthcaus_source}()}, +\code{\link{event_joined}()}, \code{\link{event_source}()}, \code{\link{event}()}, \code{\link{query}()}, diff --git a/man/default_qtc_paramcd.Rd b/man/default_qtc_paramcd.Rd index 3ca73a9c6f..ae579dc2e3 100644 --- a/man/default_qtc_paramcd.Rd +++ b/man/default_qtc_paramcd.Rd @@ -22,6 +22,8 @@ Get Default Parameter Code for Corrected QT default_qtc_paramcd("Sagie") } \seealso{ +\code{\link[=derive_param_qtc]{derive_param_qtc()}} + BDS-Findings Functions for adding Parameters/Records: \code{\link{derive_expected_records}()}, \code{\link{derive_extreme_event}()}, diff --git a/man/derive_expected_records.Rd b/man/derive_expected_records.Rd index 75022c4b80..146b48ff60 100644 --- a/man/derive_expected_records.Rd +++ b/man/derive_expected_records.Rd @@ -7,6 +7,7 @@ derive_expected_records( dataset, dataset_expected_obs, + dataset_ref, by_vars = NULL, set_values_to = NULL ) @@ -14,17 +15,19 @@ derive_expected_records( \arguments{ \item{dataset}{Input dataset -A data frame, the columns from \code{dataset_expected_obs} and specified by the +A data frame, the columns from \code{dataset_ref} and specified by the \code{by_vars} parameter are expected.} -\item{dataset_expected_obs}{Expected observations dataset +\item{dataset_expected_obs}{\emph{Deprecated}, please use \code{dataset_ref} instead.} + +\item{dataset_ref}{Expected observations dataset Data frame with the expected observations, e.g., all the expected combinations of \code{PARAMCD}, \code{PARAM}, \code{AVISIT}, \code{AVISITN}, ...} \item{by_vars}{Grouping variables -For each group defined by \code{by_vars} those observations from \code{dataset_expected_obs} +For each group defined by \code{by_vars} those observations from \code{dataset_ref} are added to the output dataset which do not have a corresponding observation in the input dataset.} @@ -51,7 +54,7 @@ contains missing observations. } \details{ For each group (the variables specified in the \code{by_vars} parameter), -those records from \code{dataset_expected_obs} that are missing in the input +those records from \code{dataset_ref} that are missing in the input dataset are added to the output dataset. } \examples{ @@ -74,7 +77,7 @@ parm_visit_ref <- tribble( derive_expected_records( dataset = adqs, - dataset_expected_obs = parm_visit_ref, + dataset_ref = parm_visit_ref, by_vars = exprs(USUBJID, PARAMCD), set_values_to = exprs(DTYPE = "DERIVED") ) @@ -89,7 +92,7 @@ parm_visit_ref <- tribble( derive_expected_records( dataset = adqs, - dataset_expected_obs = parm_visit_ref, + dataset_ref = parm_visit_ref, by_vars = exprs(USUBJID, PARAMCD), set_values_to = exprs(DTYPE = "DERIVED") ) diff --git a/man/derive_extreme_event.Rd b/man/derive_extreme_event.Rd index b2912f1783..21b4e90564 100644 --- a/man/derive_extreme_event.Rd +++ b/man/derive_extreme_event.Rd @@ -10,8 +10,11 @@ derive_extreme_event( events, order, mode, + source_datasets = NULL, + ignore_event_order = FALSE, check_type = "warning", - set_values_to + set_values_to, + keep_source_vars = exprs(everything()) ) } \arguments{ @@ -28,9 +31,14 @@ expected.} \item{events}{Conditions and new values defining events -A list of \code{event()} objects is expected. Only observations listed in the -\code{events} are considered for deriving extreme event. If multiple records -meet the filter \code{condition}, take the first record sorted by \code{order}.} +A list of \code{event()} or \code{event_joined()} objects is expected. Only +observations listed in the \code{events} are considered for deriving extreme +event. If multiple records meet the filter \code{condition}, take the first +record sorted by \code{order}. The data is grouped by \code{by_vars}, i.e., summary +functions like \code{all()} or \code{any()} can be used in \code{condition}. + +For \code{event_joined()} events the observations are selected by calling +\code{filter_joined}. The \code{condition} field is passed to the \code{filter} argument.} \item{order}{Sort order @@ -48,6 +56,20 @@ sorting by \code{order}. \emph{Permitted Values:} \code{"first"}, \code{"last"}} +\item{source_datasets}{Source datasets + +A named list of datasets is expected. The \code{dataset_name} field of \code{event()} +and \code{event_joined()} refers to the dataset provided in the list.} + +\item{ignore_event_order}{Ignore event order + +If the argument is set to \code{TRUE}, all events defined by \code{events} are +considered equivalent. If there is more than one observation per by group +the first or last (with respect to \code{mode} and \code{order}) is select without +taking the order of the events into account. + +\emph{Permitted Values:} \code{TRUE}, \code{FALSE}} + \item{check_type}{Check uniqueness? If \code{"warning"} or \code{"error"} is specified, the specified message is issued @@ -69,6 +91,15 @@ A list of variable name-value pairs is expected. \item RHS refers to the values to set to the variable. This can be a string, a symbol, a numeric value, an expression, or \code{NA}, e.g., \code{exprs(PARAMCD = "TDOSE", PARCAT1 = "OVERALL")}. }} + +\item{keep_source_vars}{Variables to keep from the source dataset + +For each event the specified variables are kept from the selected +observations. The variables specified for \code{by_vars} and created by +\code{set_values_to} are always kept. + +\emph{Permitted Values}: A list of expressions where each element is +a symbol or a tidyselect expression, e.g., \code{exprs(VISIT, VISITNUM, starts_with("RS"))}.} } \value{ The input dataset with the best or worst observation of each by group @@ -78,16 +109,29 @@ added as new observations. Add the first available record from \code{events} for each by group as new records, all variables of the selected observation are kept. It can be used for selecting the extreme observation from a series of user-defined events. -This distinguish \code{derive_extreme_event()} from \code{derive_extreme_records()}, +This distinguishes \code{derive_extreme_event()} from \code{derive_extreme_records()}, where extreme records are derived based on certain order of existing variables. } \details{ \enumerate{ -\item Construct a dataset based on \code{events}: apply the filter \code{condition} and -\code{set_values_to} to the input dataset. +\item For each event select the observations to consider: +\enumerate{ +\item If the event is of class \code{event}, the observations of the source dataset +are restricted by \code{condition} and then the first or last (\code{mode}) +observation per by group (\code{by_vars}) is selected. + +If the event is of class \code{event_joined}, \code{filter_joined()} is called to +select the observations. +\item The variables specified by the \code{set_values_to} field of the event +are added to the selected observations. +\item Only the variables specified for the \code{keep_source_vars} field of the +event, and the by variables (\code{by_vars}) and the variables created by +\code{set_values_to} are kept. +} \item For each group (with respect to the variables specified for the -\code{by_vars} parameter) the first or last observation (with respect to the +\code{by_vars} parameter) the first event is selected. If there is more than one +observation per event the first or last observation (with respect to the order specified for the \code{order} parameter and the mode specified for the \code{mode} parameter) is selected. \item The variables specified by the \code{set_values_to} parameter are added to @@ -97,6 +141,8 @@ the selected observations. } \examples{ library(tibble) +library(dplyr) +library(lubridate) adqs <- tribble( ~USUBJID, ~PARAMCD, ~AVALC, ~ADY, @@ -145,8 +191,180 @@ derive_extreme_event( PARAM = "Worst Sleeping Problems" ) ) + +# Use different mode by event +adhy <- tribble( + ~USUBJID, ~AVISITN, ~CRIT1FL, + "1", 1, "Y", + "1", 2, "Y", + "2", 1, "Y", + "2", 2, NA_character_, + "2", 3, "Y", + "2", 4, NA_character_ +) \%>\% + mutate( + PARAMCD = "ALKPH", + PARAM = "Alkaline Phosphatase (U/L)" + ) + +derive_extreme_event( + adhy, + by_vars = exprs(USUBJID), + events = list( + event( + condition = is.na(CRIT1FL), + set_values_to = exprs(AVALC = "N") + ), + event( + condition = CRIT1FL == "Y", + mode = "last", + set_values_to = exprs(AVALC = "Y") + ) + ), + order = exprs(AVISITN), + mode = "first", + keep_source_vars = exprs(AVISITN), + set_values_to = exprs( + PARAMCD = "ALK2", + PARAM = "ALKPH <= 2 times ULN" + ) +) + +# Derive confirmed best overall response (using event_joined()) +# CR - complete response, PR - partial response, SD - stable disease +# NE - not evaluable, PD - progressive disease +adsl <- tribble( + ~USUBJID, ~TRTSDTC, + "1", "2020-01-01", + "2", "2019-12-12", + "3", "2019-11-11", + "4", "2019-12-30", + "5", "2020-01-01", + "6", "2020-02-02", + "7", "2020-02-02", + "8", "2020-02-01" +) \%>\% + mutate(TRTSDT = ymd(TRTSDTC)) + +adrs <- tribble( + ~USUBJID, ~ADTC, ~AVALC, + "1", "2020-01-01", "PR", + "1", "2020-02-01", "CR", + "1", "2020-02-16", "NE", + "1", "2020-03-01", "CR", + "1", "2020-04-01", "SD", + "2", "2020-01-01", "SD", + "2", "2020-02-01", "PR", + "2", "2020-03-01", "SD", + "2", "2020-03-13", "CR", + "4", "2020-01-01", "PR", + "4", "2020-03-01", "NE", + "4", "2020-04-01", "NE", + "4", "2020-05-01", "PR", + "5", "2020-01-01", "PR", + "5", "2020-01-10", "PR", + "5", "2020-01-20", "PR", + "6", "2020-02-06", "PR", + "6", "2020-02-16", "CR", + "6", "2020-03-30", "PR", + "7", "2020-02-06", "PR", + "7", "2020-02-16", "CR", + "7", "2020-04-01", "NE", + "8", "2020-02-16", "PD" +) \%>\% + mutate( + ADT = ymd(ADTC), + PARAMCD = "OVR", + PARAM = "Overall Response by Investigator" + ) \%>\% + derive_vars_merged( + dataset_add = adsl, + by_vars = exprs(USUBJID), + new_vars = exprs(TRTSDT) + ) + +derive_extreme_event( + adrs, + by_vars = exprs(USUBJID), + order = exprs(ADT), + mode = "first", + source_datasets = list(adsl = adsl), + events = list( + event_joined( + description = paste( + "CR needs to be confirmed by a second CR at least 28 days later", + "at most one NE is acceptable between the two assessments" + ), + join_vars = exprs(AVALC, ADT), + join_type = "after", + first_cond = AVALC.join == "CR" & + ADT.join >= ADT + 28, + condition = AVALC == "CR" & + all(AVALC.join \%in\% c("CR", "NE")) & + count_vals(var = AVALC.join, val = "NE") <= 1, + set_values_to = exprs( + AVALC = "CR" + ) + ), + event_joined( + description = paste( + "PR needs to be confirmed by a second CR or PR at least 28 days later,", + "at most one NE is acceptable between the two assessments" + ), + join_vars = exprs(AVALC, ADT), + join_type = "after", + first_cond = AVALC.join \%in\% c("CR", "PR") & + ADT.join >= ADT + 28, + condition = AVALC == "PR" & + all(AVALC.join \%in\% c("CR", "PR", "NE")) & + count_vals(var = AVALC.join, val = "NE") <= 1, + set_values_to = exprs( + AVALC = "PR" + ) + ), + event( + description = paste( + "CR, PR, or SD are considered as SD if occurring at least 28", + "after treatment start" + ), + condition = AVALC \%in\% c("CR", "PR", "SD") & ADT >= TRTSDT + 28, + set_values_to = exprs( + AVALC = "SD" + ) + ), + event( + condition = AVALC == "PD", + set_values_to = exprs( + AVALC = "PD" + ) + ), + event( + condition = AVALC \%in\% c("CR", "PR", "SD", "NE"), + set_values_to = exprs( + AVALC = "NE" + ) + ), + event( + description = "set response to MISSING for patients without records in ADRS", + dataset_name = "adsl", + condition = TRUE, + set_values_to = exprs( + AVALC = "MISSING" + ), + keep_source_vars = exprs(TRTSDT) + ) + ), + set_values_to = exprs( + PARAMCD = "CBOR", + PARAM = "Best Confirmed Overall Response by Investigator" + ) +) \%>\% + filter(PARAMCD == "CBOR") + } \seealso{ +\code{\link[=event]{event()}}, \code{\link[=event_joined]{event_joined()}} + BDS-Findings Functions for adding Parameters/Records: \code{\link{default_qtc_paramcd}()}, \code{\link{derive_expected_records}()}, diff --git a/man/derive_extreme_records.Rd b/man/derive_extreme_records.Rd index a18c354a8f..872235d156 100644 --- a/man/derive_extreme_records.Rd +++ b/man/derive_extreme_records.Rd @@ -16,6 +16,7 @@ derive_extreme_records( exist_flag = NULL, true_value = "Y", false_value = "N", + keep_source_vars = exprs(everything()), set_values_to, filter ) @@ -105,6 +106,13 @@ For new observations selected from the additional dataset (\code{dataset_add}), For new observations not selected from the additional dataset (\code{dataset_add}), \code{exist_flag} is set to the specified value.} +\item{keep_source_vars}{Variables to be kept in the new records + +A named list or tidyselect expressions created by \code{exprs()} defining the +variables to be kept for the new records. The variables specified for +\code{by_vars} and \code{set_values_to} need not be specified here as they are kept +automatically.} + \item{set_values_to}{Variables to be set The specified variables are set to the specified values for the new @@ -151,6 +159,9 @@ order specified for the \code{order} argument and the mode specified for the but not in the selected records are added. \item The variables specified by the \code{set_values_to} argument are added to the selected observations. +\item The variables specified by the \code{keep_source_vars} argument are selected +along with the variables specified in \code{by_vars} and \code{set_values_to} +arguments. \item The observations are added to input dataset. } } @@ -172,12 +183,14 @@ adlb <- tribble( # Add a new record for each USUBJID storing the minimum value (first AVAL). # If multiple records meet the minimum criterion, take the first value by # AVISITN. Set AVISITN = 97 and DTYPE = MINIMUM for these new records. +# Specify the variables that need to be kept in the new records. derive_extreme_records( adlb, by_vars = exprs(USUBJID), order = exprs(AVAL, AVISITN), mode = "first", filter_add = !is.na(AVAL), + keep_source_vars = exprs(AVAL), set_values_to = exprs( AVISITN = 97, DTYPE = "MINIMUM" diff --git a/man/derive_locf_records.Rd b/man/derive_locf_records.Rd index 3ef93a3e51..5f500aaf0b 100644 --- a/man/derive_locf_records.Rd +++ b/man/derive_locf_records.Rd @@ -7,6 +7,7 @@ derive_locf_records( dataset, dataset_expected_obs, + dataset_ref, by_vars, analysis_var = AVAL, order, @@ -19,14 +20,16 @@ derive_locf_records( The columns specified by the \code{by_vars}, \code{analysis_var}, \code{order}, \code{keep_vars} parameters are expected.} -\item{dataset_expected_obs}{Expected observations dataset +\item{dataset_expected_obs}{\emph{Deprecated}, please use \code{dataset_ref} instead.} + +\item{dataset_ref}{Expected observations dataset Data frame with all the combinations of \code{PARAMCD}, \code{PARAM}, \code{AVISIT}, \code{AVISITN}, ... which are expected in the dataset is expected.} \item{by_vars}{Grouping variables -For each group defined by \code{by_vars} those observations from \code{dataset_expected_obs} +For each group defined by \code{by_vars} those observations from \code{dataset_ref} are added to the output dataset which do not have a corresponding observation in the input dataset or for which \code{analysis_var} is \code{NA} for the corresponding observation in the input dataset.} @@ -59,7 +62,7 @@ does not contain observations for missed visits/time points. } \details{ For each group (with respect to the variables specified for the -by_vars parameter) those observations from dataset_expected_obs are added to +by_vars parameter) those observations from \code{dataset_ref} are added to the output dataset \itemize{ \item which do not have a corresponding observation in the input dataset or @@ -113,8 +116,8 @@ advs_expected_obsv <- tribble( ) derive_locf_records( - data = advs, - dataset_expected_obs = advs_expected_obsv, + dataset = advs, + dataset_ref = advs_expected_obsv, by_vars = exprs(STUDYID, USUBJID, PARAMCD), order = exprs(AVISITN, AVISIT), keep_vars = exprs(PARAMN) diff --git a/man/derive_param_bmi.Rd b/man/derive_param_bmi.Rd index fb8a3ee12e..5674f1007c 100644 --- a/man/derive_param_bmi.Rd +++ b/man/derive_param_bmi.Rd @@ -11,7 +11,8 @@ derive_param_bmi( weight_code = "WEIGHT", height_code = "HEIGHT", get_unit_expr, - filter = NULL + filter = NULL, + constant_by_vars = NULL ) } \arguments{ @@ -35,24 +36,26 @@ in the newly created records. \item{set_values_to}{Variables to be set The specified variables are set to the specified values for the new -observations. For example \code{exprs(PARAMCD = "MAP")} defines the parameter -code for the new parameter. +observations. For example \code{exprs(PARAMCD = "MAP")} defines the parameter code +for the new parameter. -\emph{Permitted Values:} List of variable-value pairs} +\emph{Permitted Values}: List of variable-value pairs} \item{weight_code}{WEIGHT parameter code The observations where \code{PARAMCD} equals the specified value are considered as the WEIGHT. It is expected that WEIGHT is measured in kg -Permitted Values: character value} +\emph{Permitted Values:} character value} \item{height_code}{HEIGHT parameter code The observations where \code{PARAMCD} equals the specified value are considered as the HEIGHT. It is expected that HEIGHT is measured in cm -Permitted Values: character value} +\emph{Permitted Values:} character value + +\emph{Permitted Values:} logical scalar} \item{get_unit_expr}{An expression providing the unit of the parameter @@ -67,6 +70,18 @@ new parameter, i.e., only observations fulfilling the condition are taken into account. \emph{Permitted Values:} a condition} + +\item{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 \code{constant_by_vars} to select the subject-level variable to merge on (e.g. \code{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. + +\emph{Permitted Values:} list of variables} } \value{ The input dataset with the new parameter added. Note, a variable will only @@ -83,20 +98,35 @@ The analysis value of the new parameter is derived as \deqn{BMI = \frac{WEIGHT}{HEIGHT^2}} } \examples{ -library(tibble) - -advs <- 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" + +# 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), @@ -108,8 +138,35 @@ derive_param_bmi( ), 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) +) } \seealso{ +\code{\link[=compute_bmi]{compute_bmi()}} + BDS-Findings Functions for adding Parameters/Records: \code{\link{default_qtc_paramcd}()}, \code{\link{derive_expected_records}()}, diff --git a/man/derive_param_bsa.Rd b/man/derive_param_bsa.Rd index 9fd45fd2c1..6295555c54 100644 --- a/man/derive_param_bsa.Rd +++ b/man/derive_param_bsa.Rd @@ -12,7 +12,8 @@ derive_param_bsa( height_code = "HEIGHT", weight_code = "WEIGHT", get_unit_expr, - filter = NULL + filter = NULL, + constant_by_vars = NULL ) } \arguments{ @@ -50,29 +51,29 @@ Fujimoto: \code{0.008883 * height ^ 0.663 * weight ^ 0.444} Takahira: \code{0.007241 * height ^ 0.725 * weight ^ 0.425} -Permitted Values: character value} +\emph{Permitted Values:} character value} \item{set_values_to}{Variables to be set The specified variables are set to the specified values for the new -observations. For example \code{exprs(PARAMCD = "MAP")} defines the parameter -code for the new parameter. +observations. For example \code{exprs(PARAMCD = "MAP")} defines the parameter code +for the new parameter. -\emph{Permitted Values:} List of variable-value pairs} +\emph{Permitted Values}: List of variable-value pairs} \item{height_code}{HEIGHT parameter code The observations where \code{PARAMCD} equals the specified value are considered as the HEIGHT assessments. It is expected that HEIGHT is measured in cm. -Permitted Values: character value} +\emph{Permitted Values:} character value} \item{weight_code}{WEIGHT parameter code The observations where \code{PARAMCD} equals the specified value are considered as the WEIGHT assessments. It is expected that WEIGHT is measured in kg. -Permitted Values: character value} +\emph{Permitted Values:} character value} \item{get_unit_expr}{An expression providing the unit of the parameter @@ -87,6 +88,18 @@ new parameter, i.e., only observations fulfilling the condition are taken into account. \emph{Permitted Values:} a condition} + +\item{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 \code{constant_by_vars} to select the subject-level variable to merge on (e.g. \code{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. + +\emph{Permitted Values:} list of variables} } \value{ The input dataset with the new parameter added. Note, a variable will only @@ -102,7 +115,8 @@ available. \examples{ library(tibble) -advs <- tribble( +# 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", @@ -122,7 +136,8 @@ derive_param_bsa( PARAMCD = "BSA", PARAM = "Body Surface Area (m^2)" ), - get_unit_expr = extract_unit(PARAM) + get_unit_expr = extract_unit(PARAM), + constant_by_vars = exprs(USUBJID) ) derive_param_bsa( @@ -133,10 +148,50 @@ derive_param_bsa( 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) ) } \seealso{ +\code{\link[=compute_bsa]{compute_bsa()}} + BDS-Findings Functions for adding Parameters/Records: \code{\link{default_qtc_paramcd}()}, \code{\link{derive_expected_records}()}, diff --git a/man/derive_param_computed.Rd b/man/derive_param_computed.Rd index 14f1aea584..12cdf77ec6 100644 --- a/man/derive_param_computed.Rd +++ b/man/derive_param_computed.Rd @@ -14,7 +14,8 @@ derive_param_computed( set_values_to, filter = NULL, constant_by_vars = NULL, - constant_parameters = NULL + constant_parameters = NULL, + keep_nas = FALSE ) } \arguments{ @@ -69,6 +70,8 @@ parameter code \code{"HGHT"}. \item{analysis_var}{Analysis variable +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Please use \code{set_values_to} instead. + The specified variable is set to the value of \code{analysis_value} for the new observations. @@ -76,6 +79,8 @@ observations. \item{analysis_value}{Definition of the analysis value +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Please use \code{set_values_to} instead. + An expression defining the analysis value (\code{AVAL}) of the new parameter is expected. The values of variables of the parameters specified by \code{parameters} can be accessed using \verb{.}, @@ -88,8 +93,19 @@ Variable names in the expression must not contain more than one dot. \item{set_values_to}{Variables to be set The specified variables are set to the specified values for the new -observations. For example \code{exprs(PARAMCD = "MAP")} defines the parameter -code for the new parameter. +observations. The values of variables of the parameters specified by +\code{parameters} can be accessed using \verb{.}. For +example + +\if{html}{\out{
}}\preformatted{exprs( + AVAL = (AVAL.SYSBP + 2 * AVAL.DIABP) / 3, + PARAMCD = "MAP" +) +}\if{html}{\out{
}} + +defines the analysis value and parameter code for the new parameter. + +Variable names in the expression must not contain more than one dot. \emph{Permitted Values:} List of variable-value pairs} @@ -129,6 +145,11 @@ codes. For example, \code{constant_parameters = exprs(WEIGHT, HGHT = VSTESTCD == parameter code \code{"HGHT"}. \emph{Permitted Values:} A character vector of \code{PARAMCD} values or a list of expressions} + +\item{keep_nas}{Keep observations with \code{NA}s + +If the argument is set to \code{TRUE}, observations are added even if some of +the values contributing to the computed value are \code{NA}.} } \value{ The input dataset with the new parameter added. Note, a variable will only @@ -149,13 +170,14 @@ filtered input dataset (\code{dataset}) or the additional dataset (\code{dataset_add}) contains exactly one observation for each parameter code specified for \code{parameters}. -For the new observations \code{AVAL} is set to the value specified by -\code{analysis_value} and the variables specified for \code{set_values_to} are set to -the provided values. The values of the other variables of the input dataset -are set to \code{NA}. +For the new observations the variables specified for \code{set_values_to} are +set to the provided values. The values of the other variables of the input +dataset are set to \code{NA}. } \examples{ library(tibble) +library(dplyr) +library(lubridate) # Example 1: Derive MAP advs <- tribble( @@ -174,8 +196,8 @@ derive_param_computed( advs, by_vars = exprs(USUBJID, VISIT), parameters = c("SYSBP", "DIABP"), - analysis_value = (AVAL.SYSBP + 2 * AVAL.DIABP) / 3, set_values_to = exprs( + AVAL = (AVAL.SYSBP + 2 * AVAL.DIABP) / 3, PARAMCD = "MAP", PARAM = "Mean Arterial Pressure (mmHg)", AVALU = "mmHg" @@ -199,8 +221,8 @@ derive_param_computed( advs, by_vars = exprs(USUBJID, VISIT), parameters = "WEIGHT", - analysis_value = AVAL.WEIGHT / (AVAL.HEIGHT / 100)^2, set_values_to = exprs( + AVAL = AVAL.WEIGHT / (AVAL.HEIGHT / 100)^2, PARAMCD = "BMI", PARAM = "Body Mass Index (kg/m^2)", AVALU = "kg/m^2" @@ -210,7 +232,7 @@ derive_param_computed( ) # Example 3: Using data from an additional dataset and other variables than AVAL -qs <- tibble::tribble( +qs <- tribble( ~USUBJID, ~AVISIT, ~QSTESTCD, ~QSORRES, ~QSSTRESN, "1", "WEEK 2", "CHSF112", NA, 1, "1", "WEEK 2", "CHSF113", "Yes", NA, @@ -220,29 +242,58 @@ qs <- tibble::tribble( "1", "WEEK 4", "CHSF114", NA, 1 ) -adchsf <- tibble::tribble( - ~USUBJID, ~AVISIT, ~PARAMCD, ~QSORRES, ~QSSTRESN, ~AVAL, - "1", "WEEK 2", "CHSF12", NA, 1, 6, - "1", "WEEK 2", "CHSF14", NA, 1, 6, - "1", "WEEK 4", "CHSF12", NA, 2, 12, - "1", "WEEK 4", "CHSF14", NA, 1, 6 -) +adchsf <- tribble( + ~USUBJID, ~AVISIT, ~PARAMCD, ~QSSTRESN, ~AVAL, + "1", "WEEK 2", "CHSF12", 1, 6, + "1", "WEEK 2", "CHSF14", 1, 6, + "1", "WEEK 4", "CHSF12", 2, 12, + "1", "WEEK 4", "CHSF14", 1, 6 +) \%>\% + mutate(QSORRES = NA_character_) derive_param_computed( adchsf, dataset_add = qs, by_vars = exprs(USUBJID, AVISIT), parameters = exprs(CHSF12, CHSF13 = QSTESTCD \%in\% c("CHSF113", "CHSF213"), CHSF14), - analysis_value = case_when( - QSORRES.CHSF13 == "Not applicable" ~ 0, - QSORRES.CHSF13 == "Yes" ~ 38, - QSORRES.CHSF13 == "No" ~ if_else( - QSSTRESN.CHSF12 > QSSTRESN.CHSF14, - 25, - 0 - ) + set_values_to = exprs( + AVAL = case_when( + QSORRES.CHSF13 == "Not applicable" ~ 0, + QSORRES.CHSF13 == "Yes" ~ 38, + QSORRES.CHSF13 == "No" ~ if_else( + QSSTRESN.CHSF12 > QSSTRESN.CHSF14, + 25, + 0 + ) + ), + PARAMCD = "CHSF13" + ) +) + +# Example 4: Computing more than one variable +adlb_tbilialk <- tribble( + ~USUBJID, ~PARAMCD, ~AVALC, ~ADTM, ~ADTF, + "1", "ALK2", "Y", "2021-05-13", NA_character_, + "1", "TBILI2", "Y", "2021-06-30", "D", + "2", "ALK2", "Y", "2021-12-31", "M", + "2", "TBILI2", "N", "2021-11-11", NA_character_, + "3", "ALK2", "N", "2021-04-03", NA_character_, + "3", "TBILI2", "N", "2021-04-04", NA_character_ +) \%>\% + mutate(ADTM = ymd(ADTM)) + +derive_param_computed( + dataset_add = adlb_tbilialk, + by_vars = exprs(USUBJID), + parameters = c("ALK2", "TBILI2"), + set_values_to = exprs( + AVALC = if_else(AVALC.TBILI2 == "Y" & AVALC.ALK2 == "Y", "Y", "N"), + ADTM = pmax(ADTM.TBILI2, ADTM.ALK2), + ADTF = if_else(ADTM == ADTM.TBILI2, ADTF.TBILI2, ADTF.ALK2), + PARAMCD = "TB2AK2", + PARAM = "TBILI > 2 times ULN and ALKPH <= 2 times ULN" ), - set_values_to = exprs(PARAMCD = "CHSF13") + keep_nas = TRUE ) } \seealso{ diff --git a/man/derive_param_doseint.Rd b/man/derive_param_doseint.Rd index cf6bee3633..f67b68afff 100644 --- a/man/derive_param_doseint.Rd +++ b/man/derive_param_doseint.Rd @@ -34,10 +34,10 @@ Permitted Values: list of variables} \item{set_values_to}{Variables to be set The specified variables are set to the specified values for the new -observations. For example \code{exprs(PARAMCD = "MAP")} defines the parameter -code for the new parameter. +observations. For example \code{exprs(PARAMCD = "MAP")} defines the parameter code +for the new parameter. -\emph{Permitted Values:} List of variable-value pairs} +\emph{Permitted Values}: List of variable-value pairs} \item{tadm_code}{Total Doses Administered parameter code diff --git a/man/derive_param_extreme_event.Rd b/man/derive_param_extreme_event.Rd index 93e27a9b9b..c869f5e47f 100644 --- a/man/derive_param_extreme_event.Rd +++ b/man/derive_param_extreme_event.Rd @@ -134,17 +134,12 @@ the new observations. Other deprecated: \code{\link{derive_var_basetype}()}, \code{\link{derive_var_confirmation_flag}()}, -\code{\link{derive_var_disposition_status}()}, \code{\link{derive_var_last_dose_amt}()}, \code{\link{derive_var_last_dose_date}()}, \code{\link{derive_var_last_dose_grp}()}, \code{\link{derive_var_merged_cat}()}, \code{\link{derive_var_merged_character}()}, -\code{\link{derive_var_worst_flag}()}, -\code{\link{derive_vars_disposition_reason}()}, -\code{\link{derive_vars_last_dose}()}, -\code{\link{format_eoxxstt_default}()}, -\code{\link{format_reason_default}()} +\code{\link{derive_vars_last_dose}()} } \concept{deprecated} \keyword{deprecated} diff --git a/man/derive_param_framingham.Rd b/man/derive_param_framingham.Rd index 38058e9fa0..26a89ff1f7 100644 --- a/man/derive_param_framingham.Rd +++ b/man/derive_param_framingham.Rd @@ -42,10 +42,10 @@ Permitted Values: list of variables} \item{set_values_to}{Variables to be set The specified variables are set to the specified values for the new -observations. For example \code{exprs(PARAMCD = "MAP")} defines the parameter -code for the new parameter. +observations. For example \code{exprs(PARAMCD = "MAP")} defines the parameter code +for the new parameter. -\emph{Permitted Values:} List of variable-value pairs} +\emph{Permitted Values}: List of variable-value pairs} \item{sysbp_code}{Systolic blood pressure parameter code diff --git a/man/derive_param_map.Rd b/man/derive_param_map.Rd index f019558f0e..93b412d356 100644 --- a/man/derive_param_map.Rd +++ b/man/derive_param_map.Rd @@ -37,31 +37,31 @@ in the newly created records. \item{set_values_to}{Variables to be set The specified variables are set to the specified values for the new -observations. For example \code{exprs(PARAMCD = "MAP")} defines the parameter -code for the new parameter. +observations. For example \code{exprs(PARAMCD = "MAP")} defines the parameter code +for the new parameter. -\emph{Permitted Values:} List of variable-value pairs} +\emph{Permitted Values}: List of variable-value pairs} \item{sysbp_code}{Systolic blood pressure parameter code The observations where \code{PARAMCD} equals the specified value are considered as the systolic blood pressure assessments. -Permitted Values: character value} +\emph{Permitted Values:} character value} \item{diabp_code}{Diastolic blood pressure parameter code The observations where \code{PARAMCD} equals the specified value are considered as the diastolic blood pressure assessments. -Permitted Values: character value} +\emph{Permitted Values:} character value} \item{hr_code}{Heart rate parameter code The observations where \code{PARAMCD} equals the specified value are considered as the heart rate assessments. -Permitted Values: character value} +\emph{Permitted Values:} character value} \item{get_unit_expr}{An expression providing the unit of the parameter @@ -99,7 +99,7 @@ if it is based on diastolic, systolic blood pressure, and heart rate. library(tibble) library(dplyr, warn.conflicts = FALSE) -advs <- tribble( +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", @@ -140,6 +140,8 @@ derive_param_map( ) } \seealso{ +\code{\link[=compute_map]{compute_map()}} + BDS-Findings Functions for adding Parameters/Records: \code{\link{default_qtc_paramcd}()}, \code{\link{derive_expected_records}()}, diff --git a/man/derive_param_qtc.Rd b/man/derive_param_qtc.Rd index 73d8d22986..512945e8b0 100644 --- a/man/derive_param_qtc.Rd +++ b/man/derive_param_qtc.Rd @@ -39,10 +39,10 @@ Permitted Values: \code{"Bazett"}, \code{"Fridericia"}, \code{"Sagie"}} \item{set_values_to}{Variables to be set The specified variables are set to the specified values for the new -observations. For example \code{exprs(PARAMCD = "MAP")} defines the parameter -code for the new parameter. +observations. For example \code{exprs(PARAMCD = "MAP")} defines the parameter code +for the new parameter. -\emph{Permitted Values:} List of variable-value pairs} +\emph{Permitted Values}: List of variable-value pairs} \item{qt_code}{QT parameter code @@ -138,6 +138,8 @@ derive_param_qtc( \seealso{ \code{\link[=compute_qtc]{compute_qtc()}} +\code{\link[=compute_qtc]{compute_qtc()}} + BDS-Findings Functions for adding Parameters/Records: \code{\link{default_qtc_paramcd}()}, \code{\link{derive_expected_records}()}, diff --git a/man/derive_param_rr.Rd b/man/derive_param_rr.Rd index 1bb8e0642a..f6ba8b9add 100644 --- a/man/derive_param_rr.Rd +++ b/man/derive_param_rr.Rd @@ -34,10 +34,10 @@ in the newly created records. \item{set_values_to}{Variables to be set The specified variables are set to the specified values for the new -observations. For example \code{exprs(PARAMCD = "MAP")} defines the parameter -code for the new parameter. +observations. For example \code{exprs(PARAMCD = "MAP")} defines the parameter code +for the new parameter. -\emph{Permitted Values:} List of variable-value pairs} +\emph{Permitted Values}: List of variable-value pairs} \item{hr_code}{HR parameter code @@ -101,6 +101,8 @@ derive_param_rr( ) } \seealso{ +\code{\link[=compute_rr]{compute_rr()}} + BDS-Findings Functions for adding Parameters/Records: \code{\link{default_qtc_paramcd}()}, \code{\link{derive_expected_records}()}, diff --git a/man/derive_param_tte.Rd b/man/derive_param_tte.Rd index 8edb228af9..4177cbf61f 100644 --- a/man/derive_param_tte.Rd +++ b/man/derive_param_tte.Rd @@ -24,7 +24,7 @@ The \code{PARAMCD} variable is expected.} \item{dataset_adsl}{ADSL input dataset -The variables specified for \code{start_date}, \code{start_imputation_flag}, and +The variables specified for \code{start_date}, and \code{subject_keys} are expected.} \item{source_datasets}{Source datasets @@ -49,10 +49,7 @@ The variable \code{STARTDT} is set to the specified date. The value is taken from the ADSL dataset. If the event or censoring date is before the origin date, \code{ADT} is set to -the origin date. - -If the specified variable is imputed, the corresponding date imputation -flag must specified for \code{start_imputation_flag}.} +the origin date.} \item{event_conditions}{Sources and conditions defining events @@ -136,8 +133,8 @@ selected. Otherwise the censoring observation is selected. Finally: \enumerate{ -\item The variables specified for \code{start_date} and \code{start_imputation_flag} are -joined from the ADSL dataset. Only subjects in both datasets are kept, +\item The variable specified for \code{start_date} is joined from the +ADSL dataset. Only subjects in both datasets are kept, i.e., subjects with both an event or censoring and an observation in \code{dataset_adsl}. \item The variables as defined by the \code{set_values_to} parameter are added. diff --git a/man/derive_var_atoxgr.Rd b/man/derive_var_atoxgr.Rd index 9214320e7e..dab904a4e0 100644 --- a/man/derive_var_atoxgr.Rd +++ b/man/derive_var_atoxgr.Rd @@ -20,7 +20,7 @@ and \code{hitox_description_var} parameters are expected.} for low values, eg. "Anemia"} \item{hitox_description_var}{Variable containing the toxicity grade description -for low values, eg. "Hemoglobin Increased".} +for high values, eg. "Hemoglobin Increased".} } \value{ The input data set with the character variable added diff --git a/man/derive_var_atoxgr_dir.Rd b/man/derive_var_atoxgr_dir.Rd index 69daadaf2f..ed8e9b40d3 100644 --- a/man/derive_var_atoxgr_dir.Rd +++ b/man/derive_var_atoxgr_dir.Rd @@ -10,7 +10,8 @@ derive_var_atoxgr_dir( tox_description_var, meta_criteria, criteria_direction, - get_unit_expr + get_unit_expr, + signif_dig = 15 ) } \arguments{ @@ -26,15 +27,14 @@ criteria. For example: "Anemia" or "INR Increased".} \item{meta_criteria}{Metadata data set holding the criteria (normally a case statement) -Permitted Values: atoxgr_criteria_ctcv4, atoxgr_criteria_ctcv5 - -{admiral} metadata data set \code{atoxgr_criteria_ctcv4} implements -\href{https://ctep.cancer.gov/protocoldevelopment/electronic_applications/ctc.htm}{Common Terminology Criteria for Adverse Events (CTCAE) v4.0} -{admiral} metadata data set \code{atoxgr_criteria_ctcv5} implements -\href{https://ctep.cancer.gov/protocoldevelopment/electronic_applications/ctc.htm}{Common Terminology Criteria for Adverse Events (CTCAE) v5.0} +Permitted Values: \code{atoxgr_criteria_ctcv4}, \code{atoxgr_criteria_ctcv5}, \code{atoxgr_criteria_daids} +\itemize{ +\item \code{atoxgr_criteria_ctcv4} implements \href{https://ctep.cancer.gov/protocoldevelopment/electronic_applications/ctc.htm}{Common Terminology Criteria for Adverse Events (CTCAE) v4.0} +\item \code{atoxgr_criteria_ctcv5} implements \href{https://ctep.cancer.gov/protocoldevelopment/electronic_applications/ctc.htm}{Common Terminology Criteria for Adverse Events (CTCAE) v5.0} +\item \code{atoxgr_criteria_daids} implements +\href{https://rsc.niaid.nih.gov/sites/default/files/daidsgradingcorrectedv21.pdf}{Division of AIDS (DAIDS) Table for Grading the Severity of Adult and Pediatric Adverse Events} The metadata should have the following variables: -\itemize{ \item \code{TERM}: variable to hold the term describing the criteria applied to a particular lab test, eg. "Anemia" or "INR Increased". Note: the variable is case insensitive. \item \code{DIRECTION}: variable to hold the direction of the abnormality of a particular lab test @@ -44,6 +44,8 @@ if criteria is based on absolute values. \item \code{VAR_CHECK}: variable to hold comma separated list of variables used in criteria. Used to check against input data that variables exist. \item \code{GRADE_CRITERIA_CODE}: variable to hold code that creates grade based on defined criteria. +\item \code{FILTER}: Required only for DAIDS grading, specifies \code{admiral} code to filter the lab data +based on a subset of subjects (e.g. AGE > 18 YEARS) }} \item{criteria_direction}{Direction (L= Low, H = High) of toxicity grade. @@ -57,6 +59,11 @@ The result is used to check the units of the input parameters. Compared with Permitted Values: A variable containing unit from the input dataset, or a function call, for example, \code{get_unit_expr = extract_unit(PARAM)}.} + +\item{signif_dig}{Number of significant digits to use when comparing a lab value against another +value. + +Significant digits used to avoid floating point discrepancies when comparing numeric values.} } \value{ The input dataset with the character variable added @@ -80,37 +87,35 @@ severe grade library(tibble) data <- tribble( - ~ATOXDSCL, ~AVAL, ~ANRLO, ~ANRHI, ~PARAM, - "Hypoglycemia", 119, 4, 7, "Glucose (mmol/L)", - "Hypoglycemia", 120, 4, 7, "Glucose (mmol/L)", - "Anemia", 129, 120, 180, "Hemoglobin (g/L)", - "White blood cell decreased", 10, 5, 20, "White blood cell (10^9/L)", - "White blood cell decreased", 15, 5, 20, "White blood cell (10^9/L)", - "Anemia", 140, 120, 180, "Hemoglobin (g/L)" + ~ATOXDSCL, ~AVAL, ~ANRLO, ~ANRHI, ~PARAM, + "Hypoglycemia", 119, 4, 7, "Glucose (mmol/L)", + "Lymphocyte count decreased", 0.7, 1, 4, "Lymphocytes Abs (10^9/L)", + "Anemia", 129, 120, 180, "Hemoglobin (g/L)", + "White blood cell decreased", 10, 5, 20, "White blood cell (10^9/L)", + "White blood cell decreased", 15, 5, 20, "White blood cell (10^9/L)", + "Anemia", 140, 120, 180, "Hemoglobin (g/L)" ) derive_var_atoxgr_dir(data, new_var = ATOXGRL, tox_description_var = ATOXDSCL, - meta_criteria = atoxgr_criteria_ctcv4, + meta_criteria = atoxgr_criteria_ctcv5, criteria_direction = "L", get_unit_expr = extract_unit(PARAM) ) data <- tribble( ~ATOXDSCH, ~AVAL, ~ANRLO, ~ANRHI, ~PARAM, - "Hyperglycemia", 119, 4, 7, "Glucose (mmol/L)", - "Hyperglycemia", 120, 4, 7, "Glucose (mmol/L)", - "GGT increased", 129, 0, 30, "Gamma Glutamyl Transferase (U/L)", + "CPK increased", 129, 0, 30, "Creatine Kinase (U/L)", "Lymphocyte count increased", 4, 1, 4, "Lymphocytes Abs (10^9/L)", "Lymphocyte count increased", 2, 1, 4, "Lymphocytes Abs (10^9/L)", - "GGT increased", 140, 120, 180, "Gamma Glutamyl Transferase (U/L)" + "CPK increased", 140, 120, 180, "Creatine Kinase (U/L)" ) derive_var_atoxgr_dir(data, new_var = ATOXGRH, tox_description_var = ATOXDSCH, - meta_criteria = atoxgr_criteria_ctcv4, + meta_criteria = atoxgr_criteria_ctcv5, criteria_direction = "H", get_unit_expr = extract_unit(PARAM) ) diff --git a/man/derive_var_basetype.Rd b/man/derive_var_basetype.Rd index ed996203bc..c6a14589ef 100644 --- a/man/derive_var_basetype.Rd +++ b/man/derive_var_basetype.Rd @@ -47,17 +47,12 @@ condition are kept and \code{BASETYPE} is set to \code{NA}. Other deprecated: \code{\link{derive_param_extreme_event}()}, \code{\link{derive_var_confirmation_flag}()}, -\code{\link{derive_var_disposition_status}()}, \code{\link{derive_var_last_dose_amt}()}, \code{\link{derive_var_last_dose_date}()}, \code{\link{derive_var_last_dose_grp}()}, \code{\link{derive_var_merged_cat}()}, \code{\link{derive_var_merged_character}()}, -\code{\link{derive_var_worst_flag}()}, -\code{\link{derive_vars_disposition_reason}()}, -\code{\link{derive_vars_last_dose}()}, -\code{\link{format_eoxxstt_default}()}, -\code{\link{format_reason_default}()} +\code{\link{derive_vars_last_dose}()} } \concept{deprecated} \keyword{deprecated} diff --git a/man/derive_var_confirmation_flag.Rd b/man/derive_var_confirmation_flag.Rd index f45011cee3..4496c7ee81 100644 --- a/man/derive_var_confirmation_flag.Rd +++ b/man/derive_var_confirmation_flag.Rd @@ -196,17 +196,12 @@ previous step. For the other observations it is set to \code{false_value}. Other deprecated: \code{\link{derive_param_extreme_event}()}, \code{\link{derive_var_basetype}()}, -\code{\link{derive_var_disposition_status}()}, \code{\link{derive_var_last_dose_amt}()}, \code{\link{derive_var_last_dose_date}()}, \code{\link{derive_var_last_dose_grp}()}, \code{\link{derive_var_merged_cat}()}, \code{\link{derive_var_merged_character}()}, -\code{\link{derive_var_worst_flag}()}, -\code{\link{derive_vars_disposition_reason}()}, -\code{\link{derive_vars_last_dose}()}, -\code{\link{format_eoxxstt_default}()}, -\code{\link{format_reason_default}()} +\code{\link{derive_vars_last_dose}()} } \concept{deprecated} \keyword{deprecated} diff --git a/man/derive_var_disposition_status.Rd b/man/derive_var_disposition_status.Rd deleted file mode 100644 index 45644dedec..0000000000 --- a/man/derive_var_disposition_status.Rd +++ /dev/null @@ -1,101 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/derive_var_disposition_status.R -\name{derive_var_disposition_status} -\alias{derive_var_disposition_status} -\title{Derive a Disposition Status at a Specific Timepoint} -\usage{ -derive_var_disposition_status( - dataset, - dataset_ds, - new_var, - status_var, - format_new_var = format_eoxxstt_default, - filter_ds, - subject_keys = get_admiral_option("subject_keys") -) -} -\arguments{ -\item{dataset}{Input dataset.} - -\item{dataset_ds}{Dataset containing the disposition information (e.g.: ds). - -It must contain: -\itemize{ -\item \code{STUDYID}, \code{USUBJID}, -\item The variable(s) specified in the \code{status_var} -\item The variables used in \code{filter_ds}. -}} - -\item{new_var}{Name of the disposition status variable. - -A variable name is expected (e.g. \code{EOSSTT}).} - -\item{status_var}{The variable used to derive the disposition status. - -A variable name is expected (e.g. \code{DSDECOD}).} - -\item{format_new_var}{The format used to derive the status. - -Default: \code{format_eoxxstt_default()} defined as: - -\if{html}{\out{
}}\preformatted{format_eoxxstt_default <- function(status) \{ - case_when( - status \%in\% c("SCREEN FAILURE", "SCREENING NOT COMPLETED") ~ "NOT STARTED", - status == "COMPLETED" ~ "COMPLETED", - !status \%in\% c("COMPLETED", "SCREEN FAILURE", "SCREENING NOT COMPLETED") - & !is.na(status) ~ "DISCONTINUED", - TRUE ~ "ONGOING" - ) -\} -}\if{html}{\out{
}} - -where \code{status} is the \code{status_var.}} - -\item{filter_ds}{Filter condition for the disposition data. - -one observation per patient. An error is issued otherwise. - -Permitted Values: logical expression.} - -\item{subject_keys}{Variables to uniquely identify a subject - -A list of expressions where the expressions are symbols as returned by -\code{exprs()} is expected.} -} -\value{ -The input dataset with the disposition status (\code{new_var}) added. -\code{new_var} is derived based on the values given in \code{status_var} and according to the format -defined by \code{format_new_var} (e.g. when the default format is used, the function will derive -\code{new_var} as: -"NOT STARTED" if \code{status} is "SCREEN FAILURE" or "SCREENING NOT COMPLETED", -"COMPLETED" if \code{status_var} == "COMPLETED", -"DISCONTINUED" if \code{status} is not in ("COMPLETED","SCREEN FAILURE", -"SCREENING NOT COMPLETED") nor NA, -"ONGOING" otherwise). -} -\description{ -\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} - -This function is \emph{deprecated}, Please define your own function and use that as input for the -\code{cat_fun} argument in \code{derive_var_merged_cat()} instead. - -Derive a disposition status from the the relevant records in the disposition domain. -} -\seealso{ -Other deprecated: -\code{\link{derive_param_extreme_event}()}, -\code{\link{derive_var_basetype}()}, -\code{\link{derive_var_confirmation_flag}()}, -\code{\link{derive_var_last_dose_amt}()}, -\code{\link{derive_var_last_dose_date}()}, -\code{\link{derive_var_last_dose_grp}()}, -\code{\link{derive_var_merged_cat}()}, -\code{\link{derive_var_merged_character}()}, -\code{\link{derive_var_worst_flag}()}, -\code{\link{derive_vars_disposition_reason}()}, -\code{\link{derive_vars_last_dose}()}, -\code{\link{format_eoxxstt_default}()}, -\code{\link{format_reason_default}()} -} -\concept{deprecated} -\keyword{deprecated} diff --git a/man/derive_var_dthcaus.Rd b/man/derive_var_dthcaus.Rd index 09ff551c68..b94ba192d9 100644 --- a/man/derive_var_dthcaus.Rd +++ b/man/derive_var_dthcaus.Rd @@ -88,7 +88,7 @@ src_ae <- dthcaus_source( date = convert_dtc_to_dt(AEDTHDTC), mode = "first", dthcaus = AEDECOD, - traceability_vars = exprs(DTHDOM = "AE", DTHSEQ = AESEQ) + set_values_to = exprs(DTHDOM = "AE", DTHSEQ = AESEQ) ) src_ds <- dthcaus_source( @@ -97,7 +97,7 @@ src_ds <- dthcaus_source( date = convert_dtc_to_dt(DSSTDTC), mode = "first", dthcaus = DSTERM, - traceability_vars = exprs(DTHDOM = "DS", DTHSEQ = DSSEQ) + set_values_to = exprs(DTHDOM = "DS", DTHSEQ = DSSEQ) ) derive_var_dthcaus(adsl, src_ae, src_ds, source_datasets = list(ae = ae, ds = ds)) @@ -109,7 +109,7 @@ src_ae <- dthcaus_source( date = convert_dtc_to_dt(AEDTHDTC), mode = "first", dthcaus = AEDECOD, - traceability_vars = exprs(DTHDOM = "AE", DTHSEQ = AESEQ) + set_values_to = exprs(DTHDOM = "AE", DTHSEQ = AESEQ) ) ds <- mutate( @@ -123,7 +123,7 @@ src_ds <- dthcaus_source( date = DSSTDT, mode = "first", dthcaus = DSTERM, - traceability_vars = exprs(DTHDOM = "DS", DTHSEQ = DSSEQ) + set_values_to = exprs(DTHDOM = "DS", DTHSEQ = DSSEQ) ) src_ds_post <- dthcaus_source( @@ -132,7 +132,7 @@ src_ds_post <- dthcaus_source( date = DSSTDT, mode = "first", dthcaus = "POST STUDY: UNKNOWN CAUSE", - traceability_vars = exprs(DTHDOM = "DS", DTHSEQ = DSSEQ) + set_values_to = exprs(DTHDOM = "DS", DTHSEQ = DSSEQ) ) derive_var_dthcaus( diff --git a/man/derive_var_extreme_dt.Rd b/man/derive_var_extreme_dt.Rd index c64c03bc92..33eca0f7de 100644 --- a/man/derive_var_extreme_dt.Rd +++ b/man/derive_var_extreme_dt.Rd @@ -56,7 +56,7 @@ Then for each patient the first or last observation (with respect to \code{date} and \code{mode}) is selected. \item The new variable is set to the variable or expression specified by the \code{date} element. -\item The variables specified by the \code{traceability_vars} element are added. +\item The variables specified by the \code{set_values_to} element are added. \item The selected observations of all source datasets are combined into a single dataset. \item For each patient the first or last observation (with respect to the new @@ -183,7 +183,7 @@ dm \%>\% ae_start <- date_source( dataset_name = "ae", date = convert_dtc_to_dt(AESTDTC, highest_imputation = "M"), - traceability_vars = exprs( + set_values_to = exprs( LALVDOM = "AE", LALVSEQ = AESEQ, LALVVAR = "AESTDTC" @@ -193,7 +193,7 @@ ae_start <- date_source( ae_end <- date_source( dataset_name = "ae", date = convert_dtc_to_dt(AEENDTC, highest_imputation = "M"), - traceability_vars = exprs( + set_values_to = exprs( LALVDOM = "AE", LALVSEQ = AESEQ, LALVVAR = "AEENDTC" @@ -203,7 +203,7 @@ ae_end <- date_source( lb_date <- date_source( dataset_name = "lb", date = convert_dtc_to_dt(LBDTC), - traceability_vars = exprs( + set_values_to = exprs( LALVDOM = "LB", LALVSEQ = LBSEQ, LALVVAR = "LBDTC" @@ -213,7 +213,7 @@ lb_date <- date_source( adsl_date <- date_source( dataset_name = "adsl", date = TRTEDT, - traceability_vars = exprs( + set_values_to = exprs( LALVDOM = "ADSL", LALVSEQ = NA_integer_, LALVVAR = "TRTEDT" diff --git a/man/derive_var_extreme_dtm.Rd b/man/derive_var_extreme_dtm.Rd index 8f5f419eca..2a891d5d13 100644 --- a/man/derive_var_extreme_dtm.Rd +++ b/man/derive_var_extreme_dtm.Rd @@ -55,7 +55,7 @@ and \code{mode}) is selected. \item The new variable is set to the variable or expression specified by the \code{date} element. If this is a date variable (rather than datetime), then the time is imputed as \code{"00:00:00"}. -\item The variables specified by the \code{traceability_vars} element are added. +\item The variables specified by the \code{set_values_to} element are added. \item The selected observations of all source datasets are combined into a single dataset. \item For each patient the first or last observation (with respect to the new @@ -182,7 +182,7 @@ dm \%>\% ae_start <- date_source( dataset_name = "ae", date = convert_dtc_to_dtm(AESTDTC, highest_imputation = "M"), - traceability_vars = exprs( + set_values_to = exprs( LALVDOM = "AE", LALVSEQ = AESEQ, LALVVAR = "AESTDTC" @@ -192,7 +192,7 @@ ae_start <- date_source( ae_end <- date_source( dataset_name = "ae", date = convert_dtc_to_dtm(AEENDTC, highest_imputation = "M"), - traceability_vars = exprs( + set_values_to = exprs( LALVDOM = "AE", LALVSEQ = AESEQ, LALVVAR = "AEENDTC" @@ -201,7 +201,7 @@ ae_end <- date_source( lb_date <- date_source( dataset_name = "lb", date = convert_dtc_to_dtm(LBDTC), - traceability_vars = exprs( + set_values_to = exprs( LALVDOM = "LB", LALVSEQ = LBSEQ, LALVVAR = "LBDTC" @@ -211,7 +211,7 @@ lb_date <- date_source( adsl_date <- date_source( dataset_name = "adsl", date = TRTEDTM, - traceability_vars = exprs( + set_values_to = exprs( LALVDOM = "ADSL", LALVSEQ = NA_integer_, LALVVAR = "TRTEDTM" diff --git a/man/derive_var_extreme_flag.Rd b/man/derive_var_extreme_flag.Rd index b2a3b06399..acc55fa615 100644 --- a/man/derive_var_extreme_flag.Rd +++ b/man/derive_var_extreme_flag.Rd @@ -10,6 +10,7 @@ derive_var_extreme_flag( order, new_var, mode, + flag_all = FALSE, check_type = "warning" ) } @@ -42,6 +43,11 @@ Determines of the first or last observation is flagged. Permitted Values: \code{"first"}, \code{"last"}} +\item{flag_all}{Flag setting + +A logical value where if set to \code{TRUE}, all records are flagged +and no error or warning is issued if the first or last record is not unique.} + \item{check_type}{Check uniqueness? If \code{"warning"} or \code{"error"} is specified, the specified message is issued @@ -60,10 +66,11 @@ Add a variable flagging the first or last observation within each by group } \details{ For each group (with respect to the variables specified for the -\code{by_vars} parameter), \code{new_var} is set to "Y" for the first or last observation +\code{by_vars} parameter), \code{new_var} is set to \code{"Y"} for the first or last observation (with respect to the order specified for the \code{order} parameter and the flag mode -specified for the \code{mode} parameter). Only observations included by the \code{filter} parameter -are considered for flagging. +specified for the \code{mode} parameter). In the case where the user wants to flag multiple records +of a grouping, for example records that all happen on the same visit and time, the argument +\code{flag_all} can be set to \code{TRUE}. Otherwise, \code{new_var} is set to \code{NA}. Thus, the direction of "worst" is considered fixed for all parameters in the dataset depending on the \code{order} and the \code{mode}, i.e. for every parameter the first or last record will be flagged across the whole dataset. @@ -203,6 +210,22 @@ example_ae \%>\% arrange(USUBJID, AESTDY, AESEQ) \%>\% select(USUBJID, AEDECOD, AESEV, AESTDY, AESEQ, AOCCIFL) +# Most severe AE first occurrence per patient (flag all cases) +example_ae \%>\% + mutate( + TEMP_AESEVN = + as.integer(factor(AESEV, levels = c("SEVERE", "MODERATE", "MILD"))) + ) \%>\% + derive_var_extreme_flag( + new_var = AOCCIFL, + by_vars = exprs(USUBJID), + order = exprs(TEMP_AESEVN, AESTDY), + mode = "first", + flag_all = TRUE + ) \%>\% + arrange(USUBJID, AESTDY) \%>\% + select(USUBJID, AEDECOD, AESEV, AESTDY, AOCCIFL) + # Most severe AE first occurrence per patient per body system example_ae \%>\% mutate( @@ -219,8 +242,6 @@ example_ae \%>\% select(USUBJID, AEBODSYS, AESEV, AESTDY, AOCCSIFL) } \seealso{ -\code{\link[=derive_var_worst_flag]{derive_var_worst_flag()}} - General Derivation Functions for all ADaMs that returns variable appended to dataset: \code{\link{derive_var_joined_exist_flag}()}, \code{\link{derive_var_merged_exist_flag}()}, diff --git a/man/derive_var_last_dose_amt.Rd b/man/derive_var_last_dose_amt.Rd index f8962f2d04..2957c5ef0b 100644 --- a/man/derive_var_last_dose_amt.Rd +++ b/man/derive_var_last_dose_amt.Rd @@ -76,22 +76,15 @@ over a period defined by a start and end date) the function aggregate dose information and satisfy \code{single_dose_condition}. } \seealso{ -\code{\link[=derive_vars_last_dose]{derive_vars_last_dose()}}, \code{\link[=create_single_dose_dataset]{create_single_dose_dataset()}} - Other deprecated: \code{\link{derive_param_extreme_event}()}, \code{\link{derive_var_basetype}()}, \code{\link{derive_var_confirmation_flag}()}, -\code{\link{derive_var_disposition_status}()}, \code{\link{derive_var_last_dose_date}()}, \code{\link{derive_var_last_dose_grp}()}, \code{\link{derive_var_merged_cat}()}, \code{\link{derive_var_merged_character}()}, -\code{\link{derive_var_worst_flag}()}, -\code{\link{derive_vars_disposition_reason}()}, -\code{\link{derive_vars_last_dose}()}, -\code{\link{format_eoxxstt_default}()}, -\code{\link{format_reason_default}()} +\code{\link{derive_vars_last_dose}()} } \concept{deprecated} \keyword{deprecated} diff --git a/man/derive_var_last_dose_date.Rd b/man/derive_var_last_dose_date.Rd index 1fdab362f1..40323b807f 100644 --- a/man/derive_var_last_dose_date.Rd +++ b/man/derive_var_last_dose_date.Rd @@ -80,22 +80,15 @@ over a period defined by a start and end date) the function aggregate dose information and satisfy \code{single_dose_condition}. } \seealso{ -\code{\link[=derive_vars_last_dose]{derive_vars_last_dose()}}, \code{\link[=create_single_dose_dataset]{create_single_dose_dataset()}} - Other deprecated: \code{\link{derive_param_extreme_event}()}, \code{\link{derive_var_basetype}()}, \code{\link{derive_var_confirmation_flag}()}, -\code{\link{derive_var_disposition_status}()}, \code{\link{derive_var_last_dose_amt}()}, \code{\link{derive_var_last_dose_grp}()}, \code{\link{derive_var_merged_cat}()}, \code{\link{derive_var_merged_character}()}, -\code{\link{derive_var_worst_flag}()}, -\code{\link{derive_vars_disposition_reason}()}, -\code{\link{derive_vars_last_dose}()}, -\code{\link{format_eoxxstt_default}()}, -\code{\link{format_reason_default}()} +\code{\link{derive_vars_last_dose}()} } \concept{deprecated} \keyword{deprecated} diff --git a/man/derive_var_last_dose_grp.Rd b/man/derive_var_last_dose_grp.Rd index 496a0b582d..626c9eb31f 100644 --- a/man/derive_var_last_dose_grp.Rd +++ b/man/derive_var_last_dose_grp.Rd @@ -97,22 +97,15 @@ over a period defined by a start and end date) the function aggregate dose information and satisfy \code{single_dose_condition}. } \seealso{ -\code{\link[=derive_vars_last_dose]{derive_vars_last_dose()}}, \code{\link[=cut]{cut()}}, \code{\link[=create_single_dose_dataset]{create_single_dose_dataset()}} - Other deprecated: \code{\link{derive_param_extreme_event}()}, \code{\link{derive_var_basetype}()}, \code{\link{derive_var_confirmation_flag}()}, -\code{\link{derive_var_disposition_status}()}, \code{\link{derive_var_last_dose_amt}()}, \code{\link{derive_var_last_dose_date}()}, \code{\link{derive_var_merged_cat}()}, \code{\link{derive_var_merged_character}()}, -\code{\link{derive_var_worst_flag}()}, -\code{\link{derive_vars_disposition_reason}()}, -\code{\link{derive_vars_last_dose}()}, -\code{\link{format_eoxxstt_default}()}, -\code{\link{format_reason_default}()} +\code{\link{derive_vars_last_dose}()} } \concept{deprecated} \keyword{deprecated} diff --git a/man/derive_var_merged_cat.Rd b/man/derive_var_merged_cat.Rd index 1de2eb59a6..3a6249e272 100644 --- a/man/derive_var_merged_cat.Rd +++ b/man/derive_var_merged_cat.Rd @@ -111,83 +111,16 @@ first or last observation for each by group. \item The categorization variable is merged to the input dataset. } } -\examples{ -library(dplyr, warn.conflicts = FALSE) - -vs <- tribble( - ~STUDYID, ~DOMAIN, ~USUBJID, ~VISIT, ~VSTESTCD, ~VSSTRESN, ~VSSEQ, ~VSDTC, - "PILOT01", "VS", "04-1127", "SCREENING", "HEIGHT", 165.1, 43, "2013-09-16", - "PILOT01", "VS", "04-1127", "SCREENING", "WEIGHT", 42.87, 142, "2013-09-16", - "PILOT01", "VS", "04-1127", "BASELINE", "WEIGHT", 41.05, 143, "2013-10-02", - "PILOT01", "VS", "04-1127", "WEEK 2", "WEIGHT", 42.64, 144, "2013-10-16", - "PILOT01", "VS", "04-1127", "WEEK 4", "WEIGHT", 41.73, 145, "2013-10-30", - "PILOT01", "VS", "04-1127", "WEEK 26", "WEIGHT", 43.09, 152, "2014-03-31", - "PILOT01", "VS", "06-1049", "SCREENING", "HEIGHT", 167.64, 28, "2013-04-30", - "PILOT01", "VS", "06-1049", "SCREENING", "WEIGHT", 57.61, 92, "2013-04-30", - "PILOT01", "VS", "06-1049", "BASELINE", "WEIGHT", 57.83, 93, "2013-05-14", - "PILOT01", "VS", "06-1049", "WEEK 2", "WEIGHT", 58.29, 94, "2013-05-28", - "PILOT01", "VS", "06-1049", "WEEK 4", "WEIGHT", 58.97, 95, "2013-06-11" -) - -dm <- tribble( - ~STUDYID, ~DOMAIN, ~USUBJID, ~AGE, ~AGEU, - "PILOT01", "DM", "01-1057", 59, "YEARS", - "PILOT01", "DM", "04-1127", 84, "YEARS", - "PILOT01", "DM", "06-1049", 60, "YEARS" -) -wgt_cat <- function(wgt) { - case_when( - wgt < 50 ~ "low", - wgt > 90 ~ "high", - TRUE ~ "normal" - ) -} - -derive_var_merged_cat( - dm, - dataset_add = vs, - by_vars = exprs(STUDYID, USUBJID), - order = exprs(VSDTC, VSSEQ), - filter_add = VSTESTCD == "WEIGHT" & substr(VISIT, 1, 9) == "SCREENING", - new_var = WGTBLCAT, - source_var = VSSTRESN, - cat_fun = wgt_cat, - mode = "last" -) \%>\% - select(STUDYID, USUBJID, AGE, AGEU, WGTBLCAT) - - - -# defining a value for missing VS data -derive_var_merged_cat( - dm, - dataset_add = vs, - by_vars = exprs(STUDYID, USUBJID), - order = exprs(VSDTC, VSSEQ), - filter_add = VSTESTCD == "WEIGHT" & substr(VISIT, 1, 9) == "SCREENING", - new_var = WGTBLCAT, - source_var = VSSTRESN, - cat_fun = wgt_cat, - mode = "last", - missing_value = "MISSING" -) \%>\% - select(STUDYID, USUBJID, AGE, AGEU, WGTBLCAT) -} \seealso{ Other deprecated: \code{\link{derive_param_extreme_event}()}, \code{\link{derive_var_basetype}()}, \code{\link{derive_var_confirmation_flag}()}, -\code{\link{derive_var_disposition_status}()}, \code{\link{derive_var_last_dose_amt}()}, \code{\link{derive_var_last_dose_date}()}, \code{\link{derive_var_last_dose_grp}()}, \code{\link{derive_var_merged_character}()}, -\code{\link{derive_var_worst_flag}()}, -\code{\link{derive_vars_disposition_reason}()}, -\code{\link{derive_vars_last_dose}()}, -\code{\link{format_eoxxstt_default}()}, -\code{\link{format_reason_default}()} +\code{\link{derive_vars_last_dose}()} } \concept{deprecated} \keyword{deprecated} diff --git a/man/derive_var_merged_character.Rd b/man/derive_var_merged_character.Rd index f613ab037f..a9186d60c4 100644 --- a/man/derive_var_merged_character.Rd +++ b/man/derive_var_merged_character.Rd @@ -121,16 +121,11 @@ Other deprecated: \code{\link{derive_param_extreme_event}()}, \code{\link{derive_var_basetype}()}, \code{\link{derive_var_confirmation_flag}()}, -\code{\link{derive_var_disposition_status}()}, \code{\link{derive_var_last_dose_amt}()}, \code{\link{derive_var_last_dose_date}()}, \code{\link{derive_var_last_dose_grp}()}, \code{\link{derive_var_merged_cat}()}, -\code{\link{derive_var_worst_flag}()}, -\code{\link{derive_vars_disposition_reason}()}, -\code{\link{derive_vars_last_dose}()}, -\code{\link{format_eoxxstt_default}()}, -\code{\link{format_reason_default}()} +\code{\link{derive_vars_last_dose}()} } \concept{deprecated} \keyword{deprecated} diff --git a/man/derive_var_ontrtfl.Rd b/man/derive_var_ontrtfl.Rd index 55fa797e10..be267b1b11 100644 --- a/man/derive_var_ontrtfl.Rd +++ b/man/derive_var_ontrtfl.Rd @@ -14,7 +14,7 @@ derive_var_ontrtfl( ref_end_window = 0, ignore_time_for_ref_end_date = TRUE, filter_pre_timepoint = NULL, - span_period = NULL + span_period = FALSE ) } \arguments{ @@ -73,9 +73,9 @@ on-treatment when \code{date} = \code{ref_start_date}. For example, if observati where \code{VSTPT = PRE} should not be considered on-treatment when \code{date = ref_start_date}, \code{filter_pre_timepoint} should be used to denote when the on-treatment flag should be set to null. Optional; default is \code{NULL}.} -\item{span_period}{A \code{"Y"} scalar character. If \code{"Y"}, events that started +\item{span_period}{A logical scalar. If \code{TRUE}, events that started prior to the \code{ref_start_date}and are ongoing or end after the -\code{ref_start_date} are flagged as \code{"Y"}. Optional; default is \code{NULL}.} +\code{ref_start_date} are flagged as \code{"Y"}. Optional; default is \code{FALSE}.} } \value{ The input dataset with an additional column named \code{ONTRTFL} with a @@ -107,7 +107,7 @@ If the \code{end_date} is provided and the \code{end_date} < ref_start_date then \code{ONTRTFL} is set to \code{NULL}.This would be applicable to cases where the \code{start_date} is missing and \code{ONTRTFL} has been assigned as \code{"Y"} above. -If the \code{span_period} is specified as \code{"Y"}, this allows the user to assign +If the \code{span_period} is \code{TRUE}, this allows the user to assign \code{ONTRTFL} as \code{"Y"} to cases where the record started prior to the \code{ref_start_date} and was ongoing or ended after the \code{ref_start_date}. @@ -173,7 +173,7 @@ derive_var_ontrtfl( ref_start_date = TRTSDT, ref_end_date = TRTEDT, ref_end_window = 60, - span_period = "Y" + span_period = TRUE ) advs <- tribble( @@ -189,7 +189,7 @@ derive_var_ontrtfl( end_date = AENDT, ref_start_date = AP01SDT, ref_end_date = AP01EDT, - span_period = "Y" + span_period = TRUE ) } \seealso{ diff --git a/man/derive_var_shift.Rd b/man/derive_var_shift.Rd index 76c6a38679..ac4ff9fdfd 100644 --- a/man/derive_var_shift.Rd +++ b/man/derive_var_shift.Rd @@ -9,7 +9,8 @@ derive_var_shift( new_var, from_var, to_var, - na_val = "NULL", + na_val, + missing_value = "NULL", sep_val = " to " ) } @@ -24,7 +25,9 @@ The columns specified by \code{from_var} and the \code{to_var} parameters are ex \item{to_var}{Variable containing value to shift to.} -\item{na_val}{Character string to replace missing values in \code{from_var} or \code{to_var}. +\item{na_val}{\emph{Deprecated}, please use \code{missing_value} instead.} + +\item{missing_value}{Character string to replace missing values in \code{from_var} or \code{to_var}. Default: "NULL"} @@ -43,7 +46,7 @@ analysis value, shift from baseline grade to analysis grade, ... \details{ \code{new_var} is derived by concatenating the values of \code{from_var} to values of \code{to_var} (e.g. "NORMAL to HIGH"). When \code{from_var} or \code{to_var} has missing value, the -missing value is replaced by \code{na_val} (e.g. "NORMAL to NULL"). +missing value is replaced by \code{missing_value} (e.g. "NORMAL to NULL"). } \examples{ library(tibble) diff --git a/man/derive_var_worst_flag.Rd b/man/derive_var_worst_flag.Rd deleted file mode 100644 index d08084640d..0000000000 --- a/man/derive_var_worst_flag.Rd +++ /dev/null @@ -1,99 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/derive_var_extreme_flag.R -\name{derive_var_worst_flag} -\alias{derive_var_worst_flag} -\title{Adds a Variable Flagging the Maximal / Minimal Value Within a Group of Observations} -\usage{ -derive_var_worst_flag( - dataset, - by_vars, - order, - new_var, - param_var, - analysis_var, - worst_high, - worst_low, - check_type = "warning" -) -} -\arguments{ -\item{dataset}{Input dataset. -Variables specified by \code{by_vars}, \code{order}, \code{param_var}, and \code{analysis_var} are expected.} - -\item{by_vars}{Grouping variables - -Permitted Values: list of variables} - -\item{order}{Sort order. -Used to determine maximal / minimal observation if they are not unique, -see Details section for more information.} - -\item{new_var}{Variable to add to the \code{dataset}. -It is set \code{"Y"} for the maximal / minimal observation of each group, -see Details section for more information.} - -\item{param_var}{Variable with the parameter values for which the maximal / minimal -value is calculated.} - -\item{analysis_var}{Variable with the measurement values for which the maximal / minimal -value is calculated.} - -\item{worst_high}{Character with \code{param_var} values specifying the parameters -referring to "high". -Use \code{character(0)} if not required.} - -\item{worst_low}{Character with \code{param_var} values specifying the parameters -referring to "low". -Use \code{character(0)} if not required.} - -\item{check_type}{Check uniqueness? - -If \code{"warning"} or \code{"error"} is specified, the specified message is issued -if the observations of the input dataset are not unique with respect to the -by variables and the order. - -Default: \code{"warning"} - -Permitted Values: \code{"none"}, \code{"warning"}, \code{"error"}} -} -\value{ -The input dataset with the new flag variable added. -} -\description{ -\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} - -This function is \emph{deprecated}. Please use \code{slice_derivation()} / \code{derive_var_extreme_flag()} -to derive extreme flags and adjust the \code{order} argument. -} -\details{ -For each group with respect to the variables specified by the \code{by_vars} parameter, -the maximal / minimal observation of \code{analysis_var} -is labeled in the \code{new_var} column as \code{"Y"}, -if its \code{param_var} is in \code{worst_high} / \code{worst_low}. -Otherwise, it is assigned \code{NA}. -If there is more than one such maximal / minimal observation, -the first one with respect to the order specified by the \code{order} parameter is flagged. The -direction of "worst" depends on the definition of worst for a specified parameters in the -arguments \code{worst_high} / \code{worst_low}, i.e. for some parameters the highest value is the worst -and for others the worst is the lowest value. -} -\seealso{ -\code{\link[=derive_var_extreme_flag]{derive_var_extreme_flag()}} - -Other deprecated: -\code{\link{derive_param_extreme_event}()}, -\code{\link{derive_var_basetype}()}, -\code{\link{derive_var_confirmation_flag}()}, -\code{\link{derive_var_disposition_status}()}, -\code{\link{derive_var_last_dose_amt}()}, -\code{\link{derive_var_last_dose_date}()}, -\code{\link{derive_var_last_dose_grp}()}, -\code{\link{derive_var_merged_cat}()}, -\code{\link{derive_var_merged_character}()}, -\code{\link{derive_vars_disposition_reason}()}, -\code{\link{derive_vars_last_dose}()}, -\code{\link{format_eoxxstt_default}()}, -\code{\link{format_reason_default}()} -} -\concept{deprecated} -\keyword{deprecated} diff --git a/man/derive_vars_aage.Rd b/man/derive_vars_aage.Rd index 6c43f19929..2b3fa6c496 100644 --- a/man/derive_vars_aage.Rd +++ b/man/derive_vars_aage.Rd @@ -8,7 +8,8 @@ derive_vars_aage( dataset, start_date = BRTHDT, end_date = RANDDT, - unit = "years" + unit = "years", + age_unit = "years" ) } \arguments{ @@ -35,7 +36,9 @@ vector to a date object. Default: \code{RANDDT}} -\item{unit}{Unit +\item{unit}{\emph{Deprecated}, please use \code{age_unit} instead.} + +\item{age_unit}{Age unit The age is derived in the specified unit diff --git a/man/derive_vars_disposition_reason.Rd b/man/derive_vars_disposition_reason.Rd deleted file mode 100644 index ad80e2decb..0000000000 --- a/man/derive_vars_disposition_reason.Rd +++ /dev/null @@ -1,133 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/derive_vars_disposition_reason.R -\name{derive_vars_disposition_reason} -\alias{derive_vars_disposition_reason} -\title{Derive a Disposition Reason at a Specific Timepoint} -\usage{ -derive_vars_disposition_reason( - dataset, - dataset_ds, - new_var, - reason_var, - new_var_spe = NULL, - reason_var_spe = NULL, - format_new_vars = format_reason_default, - filter_ds, - subject_keys = get_admiral_option("subject_keys") -) -} -\arguments{ -\item{dataset}{Input dataset} - -\item{dataset_ds}{Dataset containing the disposition information (e.g. \code{ds}) - -The dataset must contain: -\itemize{ -\item \code{STUDYID}, \code{USUBJID}, -\item The variable(s) specified in the \code{reason_var} (and \code{reason_var_spe}, if required) -\item The variables used in \code{filter_ds}. -}} - -\item{new_var}{Name of the disposition reason variable - -A variable name is expected (e.g. \code{DCSREAS}).} - -\item{reason_var}{The variable used to derive the disposition reason - -A variable name is expected (e.g. \code{DSDECOD}).} - -\item{new_var_spe}{Name of the disposition reason detail variable - -A variable name is expected (e.g. \code{DCSREASP}). -If \code{new_var_spe} is specified, it is expected that \code{reason_var_spe} is also specified, -otherwise an error is issued. - -Default: NULL} - -\item{reason_var_spe}{The variable used to derive the disposition reason detail - -A variable name is expected (e.g. \code{DSTERM}). -If \code{new_var_spe} is specified, it is expected that \code{reason_var_spe} is also specified, -otherwise an error is issued. - -Default: NULL} - -\item{format_new_vars}{The function used to derive the reason(s) - -This function is used to derive the disposition reason(s) and must follow the below conventions -\itemize{ -\item If only the main reason for discontinuation needs to be derived (i.e. \code{new_var_spe} is NULL), -the function must have at least one character vector argument, e.g. -\verb{format_reason <- function(reason)} -and \code{new_var} will be derived as \code{new_var = format_reason(reason_var)}. -Typically, the content of the function would return \code{reason_var} or \code{NA} depending on the -value (e.g. \code{if_else ( reason != "COMPLETED" & !is.na(reason), reason, NA_character_)}). -\code{DCSREAS = format_reason(DSDECOD)} returns \code{DCSREAS = DSDECOD} -when \code{DSDECOD} is not \code{'COMPLETED'} nor \code{NA}, \code{NA} otherwise. -\item If both the main reason and the details needs to be derived (\code{new_var_spe} is specified) -the function must have two character vectors argument, e.g. -\verb{format_reason2 <- function(reason, reason_spe)} and -\code{new_var} will be derived as \code{new_var = format_reason(reason_var)}, -\code{new_var_spe} will be derived as \code{new_var_spe = format_reason(reason_var, reason_var_spe)}. -Typically, the content of the function would return \code{reason_var_spe} or \code{NA} depending on the -\code{reason_var} value (e.g. \code{if_else ( reason == "OTHER", reason_spe, NA_character_)}). -\code{DCSREASP = format_reason(DSDECOD, DSTERM)} returns \code{DCSREASP = DSTERM} when -\code{DSDECOD} is equal to \code{'OTHER'}. -} - -Default: \code{format_reason_default}, see \code{\link[=format_reason_default]{format_reason_default()}} for details.} - -\item{filter_ds}{Filter condition for the disposition data. - -Filter used to select the relevant disposition data. -It is expected that the filter restricts \code{dataset_ds} such that there is at most -one observation per patient. An error is issued otherwise. - -Permitted Values: logical expression.} - -\item{subject_keys}{Variables to uniquely identify a subject - -A list of expressions where the expressions are symbols as returned by -\code{exprs()} is expected.} -} -\value{ -the input dataset with the disposition reason(s) (\code{new_var} and -if required \code{new_var_spe}) added. -} -\description{ -\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} - -This function is \emph{deprecated}. Please use \code{derive_vars_merged()} and -specify the \code{filter_add} argument to derive the respective variables. - -Derive a disposition reason from the the relevant records in the disposition domain. -} -\details{ -This functions returns the main reason for discontinuation (e.g. \code{DCSREAS} or \code{DCTREAS}). -The reason for discontinuation is derived based on \code{reason_var} (e.g. \code{DSDECOD}) and -\code{format_new_vars}. -If \code{new_var_spe} is not NULL, then the function will also return the details associated -with the reason for discontinuation (e.g. \code{DCSREASP}). -The details associated with the reason for discontinuation are derived based on -\code{reason_var_spe} (e.g. \code{DSTERM}), \code{reason_var} and \code{format_new_vars}. -} -\seealso{ -\code{\link[=format_reason_default]{format_reason_default()}} - -Other deprecated: -\code{\link{derive_param_extreme_event}()}, -\code{\link{derive_var_basetype}()}, -\code{\link{derive_var_confirmation_flag}()}, -\code{\link{derive_var_disposition_status}()}, -\code{\link{derive_var_last_dose_amt}()}, -\code{\link{derive_var_last_dose_date}()}, -\code{\link{derive_var_last_dose_grp}()}, -\code{\link{derive_var_merged_cat}()}, -\code{\link{derive_var_merged_character}()}, -\code{\link{derive_var_worst_flag}()}, -\code{\link{derive_vars_last_dose}()}, -\code{\link{format_eoxxstt_default}()}, -\code{\link{format_reason_default}()} -} -\concept{deprecated} -\keyword{deprecated} diff --git a/man/derive_vars_dy.Rd b/man/derive_vars_dy.Rd index ea6d6241ed..cc2de470cf 100644 --- a/man/derive_vars_dy.Rd +++ b/man/derive_vars_dy.Rd @@ -12,9 +12,8 @@ derive_vars_dy(dataset, reference_date, source_vars) The columns specified by the \code{reference_date} and the \code{source_vars} parameter are expected.} -\item{reference_date}{The start date column, e.g., date of first treatment - -A date or date-time object column is expected. +\item{reference_date}{A date or date-time column, e.g., date of first treatment +or date-time of last exposure to treatment. Refer to \code{derive_vars_dt()} to impute and derive a date from a date character vector to a date object.} diff --git a/man/derive_vars_last_dose.Rd b/man/derive_vars_last_dose.Rd index a69acbbe4c..3821003947 100644 --- a/man/derive_vars_last_dose.Rd +++ b/man/derive_vars_last_dose.Rd @@ -100,23 +100,15 @@ then join cannot be performed properly and an error is issued. To resolve the er variables from \code{dataset_ex} (e.g. \code{new_vars = exprs(LSTEXVIS = VISIT)}). } \seealso{ -\code{\link[=derive_var_last_dose_amt]{derive_var_last_dose_amt()}}, \code{\link[=derive_var_last_dose_date]{derive_var_last_dose_date()}}, -\code{\link[=derive_var_last_dose_grp]{derive_var_last_dose_grp()}}, \code{\link[=create_single_dose_dataset]{create_single_dose_dataset()}} - Other deprecated: \code{\link{derive_param_extreme_event}()}, \code{\link{derive_var_basetype}()}, \code{\link{derive_var_confirmation_flag}()}, -\code{\link{derive_var_disposition_status}()}, \code{\link{derive_var_last_dose_amt}()}, \code{\link{derive_var_last_dose_date}()}, \code{\link{derive_var_last_dose_grp}()}, \code{\link{derive_var_merged_cat}()}, -\code{\link{derive_var_merged_character}()}, -\code{\link{derive_var_worst_flag}()}, -\code{\link{derive_vars_disposition_reason}()}, -\code{\link{format_eoxxstt_default}()}, -\code{\link{format_reason_default}()} +\code{\link{derive_var_merged_character}()} } \concept{deprecated} \keyword{deprecated} diff --git a/man/dose_freq_lookup.Rd b/man/dose_freq_lookup.Rd index 3d6593c7ac..45b654317d 100644 --- a/man/dose_freq_lookup.Rd +++ b/man/dose_freq_lookup.Rd @@ -45,7 +45,8 @@ To see the entire table in the console, run \code{print(dose_freq_lookup)}. Other metadata: \code{\link{atoxgr_criteria_ctcv4}}, -\code{\link{atoxgr_criteria_ctcv5}} +\code{\link{atoxgr_criteria_ctcv5}}, +\code{\link{atoxgr_criteria_daids}} } \concept{metadata} \keyword{metadata} diff --git a/man/dt_level.Rd b/man/dt_level.Rd index 980c459196..49dd845989 100644 --- a/man/dt_level.Rd +++ b/man/dt_level.Rd @@ -32,4 +32,4 @@ Utilities used for date imputation: \code{\link{restrict_imputed_dtc_dt}()} } \concept{utils_impute} -\keyword{utils_impute} +\keyword{internal} diff --git a/man/dthcaus_source.Rd b/man/dthcaus_source.Rd index 55c9e4c83e..0f336ecd0b 100644 --- a/man/dthcaus_source.Rd +++ b/man/dthcaus_source.Rd @@ -11,6 +11,7 @@ dthcaus_source( order = NULL, mode = "first", dthcaus, + set_values_to = NULL, traceability_vars = NULL ) } @@ -43,13 +44,17 @@ source dataset to be used to assign values to \code{DTHCAUS}; if an expression, e.g., \code{str_to_upper(AEDECOD)}, it is evaluated in the source dataset and the results is assigned to \code{DTHCAUS}; if a string literal, e.g. \code{"Adverse Event"}, it is the fixed value to be assigned to \code{DTHCAUS}.} +\item{set_values_to}{Variables to be set to trace the source dataset} + \item{traceability_vars}{A named list returned by \code{\link[=exprs]{exprs()}} listing the traceability variables, e.g. \code{exprs(DTHDOM = "DS", DTHSEQ = DSSEQ)}. The left-hand side (names of the list elements) gives the names of the traceability variables in the returned dataset. The right-hand side (values of the list elements) gives the values of the traceability variables in the returned dataset. These can be either strings, numbers, symbols, or -expressions referring to existing variables.} +expressions referring to existing variables. + +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Please use \code{set_values_to} instead.} } \value{ An object of class "dthcaus_source". @@ -84,6 +89,7 @@ Source Objects: \code{\link{censor_source}()}, \code{\link{date_source}()}, \code{\link{death_event}}, +\code{\link{event_joined}()}, \code{\link{event_source}()}, \code{\link{event}()}, \code{\link{query}()}, diff --git a/man/dtm_level.Rd b/man/dtm_level.Rd index 52ed47b88c..0c528b8a2c 100644 --- a/man/dtm_level.Rd +++ b/man/dtm_level.Rd @@ -33,4 +33,4 @@ Utilities used for date imputation: \code{\link{restrict_imputed_dtc_dt}()} } \concept{utils_impute} -\keyword{utils_impute} +\keyword{internal} diff --git a/man/event.Rd b/man/event.Rd index 39573f0a2e..aeabb110d1 100644 --- a/man/event.Rd +++ b/man/event.Rd @@ -4,15 +4,56 @@ \alias{event} \title{Create a \code{event} Object} \usage{ -event(condition, set_values_to = NULL) +event( + dataset_name = NULL, + condition = NULL, + mode = NULL, + order = NULL, + set_values_to = NULL, + keep_source_vars = NULL, + description = NULL +) } \arguments{ +\item{dataset_name}{Dataset name of the dataset to be used as input for the +event. The name refers to the dataset specified for \code{source_datasets} in +\code{derive_extreme_event()}. If the argument is not specified, the input +dataset (\code{dataset}) of \code{derive_extreme_event()} is used.} + \item{condition}{An unquoted condition for selecting the observations, which -will contribute to the extreme event.} +will contribute to the extreme event. If the condition contains summary +functions like \code{all()}, they are evaluated for each by group separately. + +\emph{Permitted Values}: an unquoted condition} + +\item{mode}{If specified, the first or last observation with respect to \code{order} is +selected for each by group. + +\emph{Permitted Values}: \code{"first"}, \code{"last"}, \code{NULL}} + +\item{order}{The specified variables or expressions are used to select the +first or last observation if \code{mode} is specified. + +\emph{Permitted Values}: list of expressions created by \code{exprs()}, e.g., +\code{exprs(ADT, desc(AVAL))} or \code{NULL}} \item{set_values_to}{A named list returned by \code{exprs()} defining the variables -to be set for the extreme answer, e.g. \verb{exprs(PARAMCD = "WSP", PARAM = "Worst Sleeping Problems"}. The values must be a symbol, a -character string, a numeric value, or \code{NA}.} +to be set for the event, e.g. \code{exprs(PARAMCD = "WSP", PARAM = "Worst Sleeping Problems")}. The values can be a symbol, a +character string, a numeric value, \code{NA} or an expression.} + +\item{keep_source_vars}{Variables to keep from the source dataset + +The specified variables are kept for the selected observations. The +variables specified for \code{by_vars} (of \code{derive_extreme_event()}) and created +by \code{set_values_to} are always kept. + +\emph{Permitted Values}: A list of expressions where each element is +a symbol or a tidyselect expression, e.g., \code{exprs(VISIT, VISITNUM, starts_with("RS"))}.} + +\item{description}{Description of the event + +The description does not affect the derivations where the event is used. It +is intended for documentation only.} } \value{ An object of class \code{event} @@ -22,7 +63,7 @@ The \code{event} object is used to define events as input for the \code{derive_extreme_event()} function. } \seealso{ -\code{\link[=derive_extreme_event]{derive_extreme_event()}} +\code{\link[=derive_extreme_event]{derive_extreme_event()}}, \code{\link[=event_joined]{event_joined()}} Source Objects: \code{\link{basket_select}()}, @@ -30,6 +71,7 @@ Source Objects: \code{\link{date_source}()}, \code{\link{death_event}}, \code{\link{dthcaus_source}()}, +\code{\link{event_joined}()}, \code{\link{event_source}()}, \code{\link{query}()}, \code{\link{records_source}()}, diff --git a/man/event_joined.Rd b/man/event_joined.Rd new file mode 100644 index 0000000000..0778b14ae8 --- /dev/null +++ b/man/event_joined.Rd @@ -0,0 +1,106 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/derive_extreme_event.R +\name{event_joined} +\alias{event_joined} +\title{Create a \code{event_joined} Object} +\usage{ +event_joined( + dataset_name = NULL, + condition, + order = NULL, + join_vars, + join_type, + first_cond = NULL, + set_values_to = NULL, + keep_source_vars = NULL, + description = NULL +) +} +\arguments{ +\item{dataset_name}{Dataset name of the dataset to be used as input for the +event. The name refers to the dataset specified for \code{source_datasets} in +\code{derive_extreme_event()}. If the argument is not specified, the input +dataset (\code{dataset}) of \code{derive_extreme_event()} is used.} + +\item{condition}{An unquoted condition for selecting the observations, which +will contribute to the extreme event. + +\emph{Permitted Values}: an unquoted condition} + +\item{order}{If specified, the specified variables or expressions are used to +select the first observation. + +\emph{Permitted Values}: list of expressions created by \code{exprs()}, e.g., +\code{exprs(ADT, desc(AVAL))} or \code{NULL}} + +\item{join_vars}{Variables to keep from joined dataset + +The variables needed from the other observations should be specified for +this parameter. The specified variables are added to the joined dataset +with suffix ".join". For example to select all observations with \code{AVALC == "Y"} and \code{AVALC == "Y"} for at least one subsequent visit \code{join_vars = exprs(AVALC, AVISITN)} and \code{filter = AVALC == "Y" & AVALC.join == "Y" & AVISITN < AVISITN.join} could be specified. + +The \verb{*.join} variables are not included in the output dataset.} + +\item{join_type}{Observations to keep after joining + +The argument determines which of the joined observations are kept with +respect to the original observation. For example, if \code{join_type = "after"} is specified all observations after the original observations are +kept. + +\emph{Permitted Values:} \code{"before"}, \code{"after"}, \code{"all"}} + +\item{first_cond}{Condition for selecting range of data + +If this argument is specified, the other observations are restricted up to +the first observation where the specified condition is fulfilled. If the +condition is not fulfilled for any of the subsequent observations, all +observations are removed.} + +\item{set_values_to}{A named list returned by \code{exprs()} defining the variables +to be set for the event, e.g. \code{exprs(PARAMCD = "WSP", PARAM = "Worst Sleeping Problems")}. The values can be a symbol, a +character string, a numeric value, \code{NA} or an expression.} + +\item{keep_source_vars}{Variables to keep from the source dataset + +The specified variables are kept for the selected observations. The +variables specified for \code{by_vars} (of \code{derive_extreme_event()}) and created +by \code{set_values_to} are always kept. + +\emph{Permitted Values}: A list of expressions where each element is +a symbol or a tidyselect expression, e.g., \code{exprs(VISIT, VISITNUM, starts_with("RS"))}.} + +\item{description}{Description of the event + +The description does not affect the derivations where the event is used. It +is intended for documentation only.} +} +\value{ +An object of class \code{event_joined} +} +\description{ +The \code{event_joined} object is used to define events as input for the +\code{derive_extreme_event()} function. This object should be used if the event +does not depend on a single observation of the source dataset but on multiple +observations. For example, if the event needs to be confirmed by a second +observation of the source dataset. + +The events are selected by calling \code{filter_joined()}. See its documentation +for more details. +} +\seealso{ +\code{\link[=derive_extreme_event]{derive_extreme_event()}}, \code{\link[=event]{event()}} + +Source Objects: +\code{\link{basket_select}()}, +\code{\link{censor_source}()}, +\code{\link{date_source}()}, +\code{\link{death_event}}, +\code{\link{dthcaus_source}()}, +\code{\link{event_source}()}, +\code{\link{event}()}, +\code{\link{query}()}, +\code{\link{records_source}()}, +\code{\link{tte_source}()} +} +\concept{source_specifications} +\keyword{source_specifications} diff --git a/man/event_source.Rd b/man/event_source.Rd index ba9d6cb3fb..dc27054758 100644 --- a/man/event_source.Rd +++ b/man/event_source.Rd @@ -58,6 +58,7 @@ Source Objects: \code{\link{date_source}()}, \code{\link{death_event}}, \code{\link{dthcaus_source}()}, +\code{\link{event_joined}()}, \code{\link{event}()}, \code{\link{query}()}, \code{\link{records_source}()}, diff --git a/man/extend_source_datasets.Rd b/man/extend_source_datasets.Rd index ac494f0144..1f7ad659bb 100644 --- a/man/extend_source_datasets.Rd +++ b/man/extend_source_datasets.Rd @@ -58,12 +58,10 @@ extend_source_datasets( \seealso{ Other Advanced Functions: \code{\link{assert_db_requirements}()}, -\code{\link{assert_parameters_argument}()}, \code{\link{assert_terms}()}, \code{\link{assert_valid_queries}()}, \code{\link{filter_date_sources}()}, \code{\link{format.basket_select}()}, -\code{\link{get_hori_data}()}, \code{\link{list_tte_source_objects}()}, \code{\link{params}()}, \code{\link{validate_basket_select}()}, diff --git a/man/filter_date_sources.Rd b/man/filter_date_sources.Rd index 691520e296..3851c7eada 100644 --- a/man/filter_date_sources.Rd +++ b/man/filter_date_sources.Rd @@ -121,12 +121,10 @@ filter_date_sources( \seealso{ Other Advanced Functions: \code{\link{assert_db_requirements}()}, -\code{\link{assert_parameters_argument}()}, \code{\link{assert_terms}()}, \code{\link{assert_valid_queries}()}, \code{\link{extend_source_datasets}()}, \code{\link{format.basket_select}()}, -\code{\link{get_hori_data}()}, \code{\link{list_tte_source_objects}()}, \code{\link{params}()}, \code{\link{validate_basket_select}()}, diff --git a/man/format.basket_select.Rd b/man/format.basket_select.Rd index 03587542fe..7b07168b6c 100644 --- a/man/format.basket_select.Rd +++ b/man/format.basket_select.Rd @@ -27,12 +27,10 @@ format(basket_select(id = 42, scope = "NARROW", type = "smq")) Other Advanced Functions: \code{\link{assert_db_requirements}()}, -\code{\link{assert_parameters_argument}()}, \code{\link{assert_terms}()}, \code{\link{assert_valid_queries}()}, \code{\link{extend_source_datasets}()}, \code{\link{filter_date_sources}()}, -\code{\link{get_hori_data}()}, \code{\link{list_tte_source_objects}()}, \code{\link{params}()}, \code{\link{validate_basket_select}()}, diff --git a/man/format_eoxxstt_default.Rd b/man/format_eoxxstt_default.Rd deleted file mode 100644 index 27cdbf84cc..0000000000 --- a/man/format_eoxxstt_default.Rd +++ /dev/null @@ -1,50 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/derive_var_disposition_status.R -\name{format_eoxxstt_default} -\alias{format_eoxxstt_default} -\title{Default Format for Disposition Status} -\usage{ -format_eoxxstt_default(status) -} -\arguments{ -\item{status}{the disposition variable used for the mapping (e.g. \code{DSDECOD}).} -} -\value{ -A \code{character} vector derived based on the values given in \code{status}: -"NOT STARTED" if \code{status} is "SCREEN FAILURE" or "SCREENING NOT COMPLETED", -"COMPLETED" if \code{status} is "COMPLETED", -"DISCONTINUED" if \code{status} is not in ("COMPLETED","SCREEN FAILURE", -"SCREENING NOT COMPLETED") nor NA, -"ONGOING" otherwise. -} -\description{ -\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} - -This function is \emph{deprecated}. This function is a default for \code{derive_var_disposition_status()} -for the \code{format_new_var} argument. Please define your own function and use that as input for the -\code{cat_fun} argument in \code{derive_var_merged_cat()} instead. - -Define a function to map the disposition status. To be used as an input for -\code{derive_var_disposition_status()}. -} -\details{ -Usually this function can not be used with \verb{\%>\%}. -} -\seealso{ -Other deprecated: -\code{\link{derive_param_extreme_event}()}, -\code{\link{derive_var_basetype}()}, -\code{\link{derive_var_confirmation_flag}()}, -\code{\link{derive_var_disposition_status}()}, -\code{\link{derive_var_last_dose_amt}()}, -\code{\link{derive_var_last_dose_date}()}, -\code{\link{derive_var_last_dose_grp}()}, -\code{\link{derive_var_merged_cat}()}, -\code{\link{derive_var_merged_character}()}, -\code{\link{derive_var_worst_flag}()}, -\code{\link{derive_vars_disposition_reason}()}, -\code{\link{derive_vars_last_dose}()}, -\code{\link{format_reason_default}()} -} -\concept{deprecated} -\keyword{deprecated} diff --git a/man/format_reason_default.Rd b/man/format_reason_default.Rd deleted file mode 100644 index 924db54cab..0000000000 --- a/man/format_reason_default.Rd +++ /dev/null @@ -1,53 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/derive_vars_disposition_reason.R -\name{format_reason_default} -\alias{format_reason_default} -\title{Default Format for the Disposition Reason} -\usage{ -format_reason_default(reason, reason_spe = NULL) -} -\arguments{ -\item{reason}{the disposition variable used for the mapping (e.g. \code{DSDECOD}).} - -\item{reason_spe}{the disposition variable used for the mapping of the details -if required (e.g. \code{DSTERM}).} -} -\value{ -A \code{character} vector -} -\description{ -\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} - -This function is \emph{deprecated}. This function is a default for \code{derive_vars_disposition_reason()} -for the \code{format_new_vars} argument. Please use \code{derive_vars_merged()} and -specify the \code{filter_add} argument to derive the respective variables. - -Define a function to map the disposition reason, to be used as a parameter in -\code{derive_vars_disposition_reason()}. -} -\details{ -\code{format_reason_default(DSDECOD)} returns \code{DSDECOD} when \code{DSDECOD} is not \code{'COMPLETED'} nor \code{NA}. -\cr\code{format_reason_default(DSDECOD, DSTERM)} returns \code{DSTERM} when \code{DSDECOD} is -equal to \code{'OTHER'}. -\cr Usually this function can not be used with \verb{\%>\%}. -} -\seealso{ -\code{\link[=derive_vars_disposition_reason]{derive_vars_disposition_reason()}} - -Other deprecated: -\code{\link{derive_param_extreme_event}()}, -\code{\link{derive_var_basetype}()}, -\code{\link{derive_var_confirmation_flag}()}, -\code{\link{derive_var_disposition_status}()}, -\code{\link{derive_var_last_dose_amt}()}, -\code{\link{derive_var_last_dose_date}()}, -\code{\link{derive_var_last_dose_grp}()}, -\code{\link{derive_var_merged_cat}()}, -\code{\link{derive_var_merged_character}()}, -\code{\link{derive_var_worst_flag}()}, -\code{\link{derive_vars_disposition_reason}()}, -\code{\link{derive_vars_last_dose}()}, -\code{\link{format_eoxxstt_default}()} -} -\concept{deprecated} -\keyword{deprecated} diff --git a/man/get_hori_data.Rd b/man/get_hori_data.Rd index cd78eb0eac..e416b453b9 100644 --- a/man/get_hori_data.Rd +++ b/man/get_hori_data.Rd @@ -4,7 +4,7 @@ \alias{get_hori_data} \title{Creating Temporary Parameters and \verb{.} Variables} \usage{ -get_hori_data(dataset, by_vars, parameters, analysis_value, filter) +get_hori_data(dataset, by_vars, parameters, set_values_to, filter) } \arguments{ \item{dataset}{Input dataset} @@ -20,12 +20,12 @@ expression the observations to select. \emph{Permitted Values:} A character vector of \code{PARAMCD} values or a list of expressions} -\item{analysis_value}{All variables of the form \verb{.} like \code{AVAL.WEIGHT} are +\item{set_values_to}{All variables of the form \verb{.} like \code{AVAL.WEIGHT} are added to the input dataset. They are set to the value of the variable for the parameter. E.g., \code{AVAL.WEIGHT} is set to the value of \code{AVAL} where \code{PARAMCD == "WEIGHT"}. -\emph{Permitted Values:} An unquoted expression} +\emph{Permitted Values:} A list of expressions} \item{filter}{Filter condition used for restricting the input dataset @@ -43,19 +43,4 @@ variables specified for \code{by_vars} and all variables of the form The function creates temporary parameters and variables of the form \verb{.}, e.g., \code{AVAL.WEIGHT}. } -\seealso{ -Other Advanced Functions: -\code{\link{assert_db_requirements}()}, -\code{\link{assert_parameters_argument}()}, -\code{\link{assert_terms}()}, -\code{\link{assert_valid_queries}()}, -\code{\link{extend_source_datasets}()}, -\code{\link{filter_date_sources}()}, -\code{\link{format.basket_select}()}, -\code{\link{list_tte_source_objects}()}, -\code{\link{params}()}, -\code{\link{validate_basket_select}()}, -\code{\link{validate_query}()} -} -\concept{other_advanced} -\keyword{other_advanced} +\keyword{internal} diff --git a/man/get_imputation_target_date.Rd b/man/get_imputation_target_date.Rd index 2f6e41605e..0feacfdc85 100644 --- a/man/get_imputation_target_date.Rd +++ b/man/get_imputation_target_date.Rd @@ -52,4 +52,4 @@ Utilities used for date imputation: \code{\link{restrict_imputed_dtc_dt}()} } \concept{utils_impute} -\keyword{utils_impute} +\keyword{internal} diff --git a/man/get_imputation_target_time.Rd b/man/get_imputation_target_time.Rd index 05b6f1d5d4..5c90cc9acd 100644 --- a/man/get_imputation_target_time.Rd +++ b/man/get_imputation_target_time.Rd @@ -43,4 +43,4 @@ Utilities used for date imputation: \code{\link{restrict_imputed_dtc_dt}()} } \concept{utils_impute} -\keyword{utils_impute} +\keyword{internal} diff --git a/man/get_partialdatetime.Rd b/man/get_partialdatetime.Rd index f000d49929..5bc4459003 100644 --- a/man/get_partialdatetime.Rd +++ b/man/get_partialdatetime.Rd @@ -37,4 +37,4 @@ Utilities used for date imputation: \code{\link{restrict_imputed_dtc_dt}()} } \concept{utils_impute} -\keyword{utils_impute} +\keyword{internal} diff --git a/man/impute_dtc_dt.Rd b/man/impute_dtc_dt.Rd index 06c4ab92a4..a58d9e061d 100644 --- a/man/impute_dtc_dt.Rd +++ b/man/impute_dtc_dt.Rd @@ -133,7 +133,7 @@ impute_dtc_dt( highest_imputation = "M" ) # Same as above -impute_dtc_dtm( +impute_dtc_dt( dtc = dates, highest_imputation = "M", date_imputation = "01-01" diff --git a/man/list_tte_source_objects.Rd b/man/list_tte_source_objects.Rd index 155a926972..c454c02e22 100644 --- a/man/list_tte_source_objects.Rd +++ b/man/list_tte_source_objects.Rd @@ -22,13 +22,11 @@ list_tte_source_objects() \seealso{ Other Advanced Functions: \code{\link{assert_db_requirements}()}, -\code{\link{assert_parameters_argument}()}, \code{\link{assert_terms}()}, \code{\link{assert_valid_queries}()}, \code{\link{extend_source_datasets}()}, \code{\link{filter_date_sources}()}, \code{\link{format.basket_select}()}, -\code{\link{get_hori_data}()}, \code{\link{params}()}, \code{\link{validate_basket_select}()}, \code{\link{validate_query}()} diff --git a/man/params.Rd b/man/params.Rd index 7dc400deea..90c0e8c27d 100644 --- a/man/params.Rd +++ b/man/params.Rd @@ -101,13 +101,11 @@ call_derivation( Other Advanced Functions: \code{\link{assert_db_requirements}()}, -\code{\link{assert_parameters_argument}()}, \code{\link{assert_terms}()}, \code{\link{assert_valid_queries}()}, \code{\link{extend_source_datasets}()}, \code{\link{filter_date_sources}()}, \code{\link{format.basket_select}()}, -\code{\link{get_hori_data}()}, \code{\link{list_tte_source_objects}()}, \code{\link{validate_basket_select}()}, \code{\link{validate_query}()} diff --git a/man/print.adam_templates.Rd b/man/print.adam_templates.Rd index ab3a9ed634..1831b8edfe 100644 --- a/man/print.adam_templates.Rd +++ b/man/print.adam_templates.Rd @@ -30,4 +30,4 @@ Utilities for printing: \code{\link{print_named_list}()} } \concept{utils_print} -\keyword{utils_print} +\keyword{internal} diff --git a/man/print.duplicates.Rd b/man/print.duplicates.Rd index 265921ebe8..554235ba8d 100644 --- a/man/print.duplicates.Rd +++ b/man/print.duplicates.Rd @@ -24,4 +24,4 @@ Utilities for printing: \code{\link{print_named_list}()} } \concept{utils_print} -\keyword{utils_print} +\keyword{internal} diff --git a/man/print.source.Rd b/man/print.source.Rd index f98d455fa1..8b65ebba02 100644 --- a/man/print.source.Rd +++ b/man/print.source.Rd @@ -28,4 +28,4 @@ Utilities for printing: \code{\link{print_named_list}()} } \concept{utils_print} -\keyword{utils_print} +\keyword{internal} diff --git a/man/print_named_list.Rd b/man/print_named_list.Rd index 7fb1cfb352..74689e8e70 100644 --- a/man/print_named_list.Rd +++ b/man/print_named_list.Rd @@ -29,4 +29,4 @@ Utilities for printing: \code{\link{print.source}()} } \concept{utils_print} -\keyword{utils_print} +\keyword{internal} diff --git a/man/query.Rd b/man/query.Rd index 0478406e01..3efe0bfdaf 100644 --- a/man/query.Rd +++ b/man/query.Rd @@ -140,6 +140,7 @@ Source Objects: \code{\link{date_source}()}, \code{\link{death_event}}, \code{\link{dthcaus_source}()}, +\code{\link{event_joined}()}, \code{\link{event_source}()}, \code{\link{event}()}, \code{\link{records_source}()}, diff --git a/man/records_source.Rd b/man/records_source.Rd index f0d011aa39..ec424bd775 100644 --- a/man/records_source.Rd +++ b/man/records_source.Rd @@ -46,6 +46,7 @@ Source Objects: \code{\link{date_source}()}, \code{\link{death_event}}, \code{\link{dthcaus_source}()}, +\code{\link{event_joined}()}, \code{\link{event_source}()}, \code{\link{event}()}, \code{\link{query}()}, diff --git a/man/restrict_imputed_dtc_dt.Rd b/man/restrict_imputed_dtc_dt.Rd index 0f78b1087c..f41697f35d 100644 --- a/man/restrict_imputed_dtc_dt.Rd +++ b/man/restrict_imputed_dtc_dt.Rd @@ -73,4 +73,4 @@ Utilities used for date imputation: \code{\link{restrict_imputed_dtc_dtm}()} } \concept{utils_impute} -\keyword{utils_impute} +\keyword{internal} diff --git a/man/restrict_imputed_dtc_dtm.Rd b/man/restrict_imputed_dtc_dtm.Rd index 5e90e06175..996bf10522 100644 --- a/man/restrict_imputed_dtc_dtm.Rd +++ b/man/restrict_imputed_dtc_dtm.Rd @@ -81,4 +81,4 @@ Utilities used for date imputation: \code{\link{restrict_imputed_dtc_dt}()} } \concept{utils_impute} -\keyword{utils_impute} +\keyword{internal} diff --git a/man/tte_source.Rd b/man/tte_source.Rd index 5051d0de38..780a49b172 100644 --- a/man/tte_source.Rd +++ b/man/tte_source.Rd @@ -46,6 +46,7 @@ Source Objects: \code{\link{date_source}()}, \code{\link{death_event}}, \code{\link{dthcaus_source}()}, +\code{\link{event_joined}()}, \code{\link{event_source}()}, \code{\link{event}()}, \code{\link{query}()}, diff --git a/man/tte_source_objects.Rd b/man/tte_source_objects.Rd index 9608eaab54..9570867e2c 100644 --- a/man/tte_source_objects.Rd +++ b/man/tte_source_objects.Rd @@ -65,6 +65,7 @@ Source Objects: \code{\link{censor_source}()}, \code{\link{date_source}()}, \code{\link{dthcaus_source}()}, +\code{\link{event_joined}()}, \code{\link{event_source}()}, \code{\link{event}()}, \code{\link{query}()}, diff --git a/man/validate_basket_select.Rd b/man/validate_basket_select.Rd index d0aa42bc20..9bfcddca71 100644 --- a/man/validate_basket_select.Rd +++ b/man/validate_basket_select.Rd @@ -20,13 +20,11 @@ Validate an object is indeed a \code{basket_select} object Other Advanced Functions: \code{\link{assert_db_requirements}()}, -\code{\link{assert_parameters_argument}()}, \code{\link{assert_terms}()}, \code{\link{assert_valid_queries}()}, \code{\link{extend_source_datasets}()}, \code{\link{filter_date_sources}()}, \code{\link{format.basket_select}()}, -\code{\link{get_hori_data}()}, \code{\link{list_tte_source_objects}()}, \code{\link{params}()}, \code{\link{validate_query}()} diff --git a/man/validate_query.Rd b/man/validate_query.Rd index 5c835669be..dab7e33c9a 100644 --- a/man/validate_query.Rd +++ b/man/validate_query.Rd @@ -20,13 +20,11 @@ Validate an object is indeed a \code{query} object Other Advanced Functions: \code{\link{assert_db_requirements}()}, -\code{\link{assert_parameters_argument}()}, \code{\link{assert_terms}()}, \code{\link{assert_valid_queries}()}, \code{\link{extend_source_datasets}()}, \code{\link{filter_date_sources}()}, \code{\link{format.basket_select}()}, -\code{\link{get_hori_data}()}, \code{\link{list_tte_source_objects}()}, \code{\link{params}()}, \code{\link{validate_basket_select}()} diff --git a/renv.lock b/renv.lock index 6617448390..5801ed10a5 100644 --- a/renv.lock +++ b/renv.lock @@ -4,7 +4,7 @@ "Repositories": [ { "Name": "CRAN", - "URL": "https://cloud.r-project.org" + "URL": "https://packagemanager.posit.co/cran/latest" }, { "Name": "RSPM", @@ -179,7 +179,7 @@ "Package": "callr", "Version": "3.7.3", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -188,11 +188,23 @@ ], "Hash": "9b2191ede20fa29828139b9900922e51" }, + "cellranger": { + "Package": "cellranger", + "Version": "1.1.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "rematch", + "tibble" + ], + "Hash": "f61dbaec772ccd2e17705c1e872e9e7c" + }, "cli": { "Package": "cli", "Version": "3.4.1", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "utils" @@ -219,6 +231,13 @@ ], "Hash": "019388fc48e48b3da0d3a76ff94608a8" }, + "collections": { + "Package": "collections", + "Version": "0.3.5", + "Source": "Repository", + "Repository": "RSPM", + "Hash": "92537c684a3d2eaa6bd8f65c28ef97f0" + }, "commonmark": { "Package": "commonmark", "Version": "1.8.0", @@ -250,7 +269,7 @@ "Package": "cpp11", "Version": "0.4.3", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Hash": "ed588261931ee3be2c700d22e94a29ab" }, "crayon": { @@ -320,7 +339,7 @@ "Package": "desc", "Version": "1.4.2", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -423,7 +442,7 @@ "Package": "dplyr", "Version": "1.1.1", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -704,7 +723,7 @@ "Package": "knitr", "Version": "1.40", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "evaluate", @@ -717,6 +736,30 @@ ], "Hash": "caea8b0f899a0b1738444b9bc47067e7" }, + "languageserver": { + "Package": "languageserver", + "Version": "0.3.12", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "R6", + "callr", + "collections", + "fs", + "jsonlite", + "lintr", + "parallel", + "roxygen2", + "stringi", + "styler", + "tools", + "utils", + "xml2", + "xmlparsedata" + ], + "Hash": "f62ed8b09fd56cd70291bd077bc52c4b" + }, "later": { "Package": "later", "Version": "1.3.0", @@ -755,7 +798,7 @@ "Package": "lintr", "Version": "3.0.2", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "backports", @@ -841,7 +884,7 @@ "Package": "pillar", "Version": "1.9.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "cli", "fansi", @@ -886,7 +929,7 @@ "Package": "pkgdown", "Version": "2.0.7", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "bslib", @@ -948,7 +991,7 @@ "Package": "processx", "Version": "3.6.1", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -957,6 +1000,19 @@ ], "Hash": "a11891e28c1f1e5ddd773ba1b8c07cf6" }, + "progress": { + "Package": "progress", + "Version": "1.2.2", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R6", + "crayon", + "hms", + "prettyunits" + ], + "Hash": "14dc9f7a3c91ebb14ec5bb9208a07061" + }, "promises": { "Package": "promises", "Version": "1.2.0.1", @@ -1038,6 +1094,27 @@ ], "Hash": "8f25ebe2ec38b1f2aef3b0d2ef76f6c4" }, + "readxl": { + "Package": "readxl", + "Version": "1.3.1", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "Rcpp", + "cellranger", + "progress", + "tibble", + "utils" + ], + "Hash": "63537c483c2dbec8d9e3183b3735254a" + }, + "rematch": { + "Package": "rematch", + "Version": "1.0.1", + "Source": "Repository", + "Repository": "RSPM", + "Hash": "c66b930d20bb6d858cd18e1cebcfae5c" + }, "rematch2": { "Package": "rematch2", "Version": "2.1.2", @@ -1050,7 +1127,7 @@ }, "remotes": { "Package": "remotes", - "Version": "2.4.2", + "Version": "2.4.2.1", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1060,17 +1137,17 @@ "tools", "utils" ], - "Hash": "227045be9aee47e6dda9bb38ac870d67" + "Hash": "63d15047eb239f95160112bcadc4fcb9" }, "renv": { "Package": "renv", - "Version": "0.17.0", + "Version": "1.0.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "utils" ], - "Hash": "ce3065fc1a0b64a859f55ac3998d6927" + "Hash": "c321cd99d56443dbffd1c9e673c0c1a2" }, "rex": { "Package": "rex", @@ -1086,7 +1163,7 @@ "Package": "rlang", "Version": "1.1.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "utils" @@ -1097,7 +1174,7 @@ "Package": "rmarkdown", "Version": "2.17", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "bslib", @@ -1120,7 +1197,7 @@ "Package": "roxygen2", "Version": "7.2.3", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -1257,14 +1334,14 @@ }, "staged.dependencies": { "Package": "staged.dependencies", - "Version": "0.2.8", + "Version": "0.3.1", "Source": "GitHub", "RemoteType": "github", "RemoteHost": "api.github.com", "RemoteUsername": "openpharma", "RemoteRepo": "staged.dependencies", "RemoteRef": "main", - "RemoteSha": "ce7c112ba3d75cf48e4dd6310b3140ab0ec3b486", + "RemoteSha": "1ab184a029bef8839a57bb6acd1c5c919cf1fd89", "Requirements": [ "desc", "devtools", @@ -1285,7 +1362,7 @@ "withr", "yaml" ], - "Hash": "89f2e1d1009601f58f64b7092abcc0d7" + "Hash": "ea298f9fb221a8c7ca4c9e55e9c29b48" }, "stringi": { "Package": "stringi", @@ -1317,7 +1394,7 @@ "Package": "styler", "Version": "1.9.1", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R.cache", @@ -1354,7 +1431,7 @@ "Package": "testthat", "Version": "3.1.7", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -1396,7 +1473,7 @@ "Package": "tibble", "Version": "3.2.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "fansi", @@ -1437,7 +1514,7 @@ "Package": "tidyselect", "Version": "1.2.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -1504,7 +1581,7 @@ "Package": "vctrs", "Version": "0.6.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -1518,7 +1595,7 @@ "Package": "waldo", "Version": "0.4.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "cli", "diffobj", @@ -1555,7 +1632,7 @@ "Package": "xfun", "Version": "0.34", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "stats", "tools" diff --git a/renv/activate.R b/renv/activate.R index 360dd52869..cc742fc96f 100644 --- a/renv/activate.R +++ b/renv/activate.R @@ -2,7 +2,8 @@ local({ # the requested version of renv - version <- "0.17.0" + version <- "1.0.0" + attr(version, "sha") <- NULL # the project directory project <- getwd() @@ -60,21 +61,75 @@ local({ # load bootstrap tools `%||%` <- function(x, y) { - if (is.environment(x) || length(x)) x else y + if (is.null(x)) y else x + } + + catf <- function(fmt, ..., appendLF = TRUE) { + + quiet <- getOption("renv.bootstrap.quiet", default = FALSE) + if (quiet) + return(invisible()) + + msg <- sprintf(fmt, ...) + cat(msg, file = stdout(), sep = if (appendLF) "\n" else "") + + invisible(msg) + + } + + header <- function(label, + ..., + prefix = "#", + suffix = "-", + n = min(getOption("width"), 78)) + { + label <- sprintf(label, ...) + n <- max(n - nchar(label) - nchar(prefix) - 2L, 8L) + if (n <= 0) + return(paste(prefix, label)) + + tail <- paste(rep.int(suffix, n), collapse = "") + paste0(prefix, " ", label, " ", tail) + + } + + startswith <- function(string, prefix) { + substring(string, 1, nchar(prefix)) == prefix } bootstrap <- function(version, library) { + friendly <- renv_bootstrap_version_friendly(version) + section <- header(sprintf("Bootstrapping renv %s", friendly)) + catf(section) + # attempt to download renv - tarball <- tryCatch(renv_bootstrap_download(version), error = identity) - if (inherits(tarball, "error")) - stop("failed to download renv ", version) + catf("- Downloading renv ... ", appendLF = FALSE) + withCallingHandlers( + tarball <- renv_bootstrap_download(version), + error = function(err) { + catf("FAILED") + stop("failed to download:\n", conditionMessage(err)) + } + ) + catf("OK") + on.exit(unlink(tarball), add = TRUE) # now attempt to install - status <- tryCatch(renv_bootstrap_install(version, tarball, library), error = identity) - if (inherits(status, "error")) - stop("failed to install renv ", version) + catf("- Installing renv ... ", appendLF = FALSE) + withCallingHandlers( + status <- renv_bootstrap_install(version, tarball, library), + error = function(err) { + catf("FAILED") + stop("failed to install:\n", conditionMessage(err)) + } + ) + catf("OK") + + # add empty line to break up bootstrapping from normal output + catf("") + return(invisible()) } renv_bootstrap_tests_running <- function() { @@ -83,31 +138,32 @@ local({ renv_bootstrap_repos <- function() { + # get CRAN repository + cran <- getOption("renv.repos.cran", "https://cloud.r-project.org") + # check for repos override repos <- Sys.getenv("RENV_CONFIG_REPOS_OVERRIDE", unset = NA) - if (!is.na(repos)) + if (!is.na(repos)) { + + # check for RSPM; if set, use a fallback repository for renv + rspm <- Sys.getenv("RSPM", unset = NA) + if (identical(rspm, repos)) + repos <- c(RSPM = rspm, CRAN = cran) + return(repos) + } + # check for lockfile repositories repos <- tryCatch(renv_bootstrap_repos_lockfile(), error = identity) if (!inherits(repos, "error") && length(repos)) return(repos) - # if we're testing, re-use the test repositories - if (renv_bootstrap_tests_running()) { - repos <- getOption("renv.tests.repos") - if (!is.null(repos)) - return(repos) - } - # retrieve current repos repos <- getOption("repos") # ensure @CRAN@ entries are resolved - repos[repos == "@CRAN@"] <- getOption( - "renv.repos.cran", - "https://cloud.r-project.org" - ) + repos[repos == "@CRAN@"] <- cran # add in renv.bootstrap.repos if set default <- c(FALLBACK = "https://cloud.r-project.org") @@ -146,33 +202,34 @@ local({ renv_bootstrap_download <- function(version) { - # if the renv version number has 4 components, assume it must - # be retrieved via github - nv <- numeric_version(version) - components <- unclass(nv)[[1]] - - # if this appears to be a development version of 'renv', we'll - # try to restore from github - dev <- length(components) == 4L - - # begin collecting different methods for finding renv - methods <- c( - renv_bootstrap_download_tarball, - if (dev) - renv_bootstrap_download_github - else c( - renv_bootstrap_download_cran_latest, - renv_bootstrap_download_cran_archive + sha <- attr(version, "sha", exact = TRUE) + + methods <- if (!is.null(sha)) { + + # attempting to bootstrap a development version of renv + c( + function() renv_bootstrap_download_tarball(sha), + function() renv_bootstrap_download_github(sha) ) - ) + + } else { + + # attempting to bootstrap a release version of renv + c( + function() renv_bootstrap_download_tarball(version), + function() renv_bootstrap_download_cran_latest(version), + function() renv_bootstrap_download_cran_archive(version) + ) + + } for (method in methods) { - path <- tryCatch(method(version), error = identity) + path <- tryCatch(method(), error = identity) if (is.character(path) && file.exists(path)) return(path) } - stop("failed to download renv ", version) + stop("All download methods failed") } @@ -236,8 +293,6 @@ local({ type <- spec$type repos <- spec$repos - message("* Downloading renv ", version, " ... ", appendLF = FALSE) - baseurl <- utils::contrib.url(repos = repos, type = type) ext <- if (identical(type, "source")) ".tar.gz" @@ -254,13 +309,10 @@ local({ condition = identity ) - if (inherits(status, "condition")) { - message("FAILED") + if (inherits(status, "condition")) return(FALSE) - } # report success and return - message("OK (downloaded ", type, ")") destfile } @@ -317,8 +369,6 @@ local({ urls <- file.path(repos, "src/contrib/Archive/renv", name) destfile <- file.path(tempdir(), name) - message("* Downloading renv ", version, " ... ", appendLF = FALSE) - for (url in urls) { status <- tryCatch( @@ -326,14 +376,11 @@ local({ condition = identity ) - if (identical(status, 0L)) { - message("OK") + if (identical(status, 0L)) return(destfile) - } } - message("FAILED") return(FALSE) } @@ -356,7 +403,7 @@ local({ if (!file.exists(tarball)) { # let the user know we weren't able to honour their request - fmt <- "* RENV_BOOTSTRAP_TARBALL is set (%s) but does not exist." + fmt <- "- RENV_BOOTSTRAP_TARBALL is set (%s) but does not exist." msg <- sprintf(fmt, tarball) warning(msg) @@ -365,10 +412,7 @@ local({ } - fmt <- "* Bootstrapping with tarball at path '%s'." - msg <- sprintf(fmt, tarball) - message(msg) - + catf("- Using local tarball '%s'.", tarball) tarball } @@ -395,8 +439,6 @@ local({ on.exit(do.call(base::options, saved), add = TRUE) } - message("* Downloading renv ", version, " from GitHub ... ", appendLF = FALSE) - url <- file.path("https://api.github.com/repos/rstudio/renv/tarball", version) name <- sprintf("renv_%s.tar.gz", version) destfile <- file.path(tempdir(), name) @@ -406,26 +448,105 @@ local({ condition = identity ) - if (!identical(status, 0L)) { - message("FAILED") + if (!identical(status, 0L)) return(FALSE) - } - message("OK") + renv_bootstrap_download_augment(destfile) + return(destfile) } + # Add Sha to DESCRIPTION. This is stop gap until #890, after which we + # can use renv::install() to fully capture metadata. + renv_bootstrap_download_augment <- function(destfile) { + sha <- renv_bootstrap_git_extract_sha1_tar(destfile) + if (is.null(sha)) { + return() + } + + # Untar + tempdir <- tempfile("renv-github-") + on.exit(unlink(tempdir, recursive = TRUE), add = TRUE) + untar(destfile, exdir = tempdir) + pkgdir <- dir(tempdir, full.names = TRUE)[[1]] + + # Modify description + desc_path <- file.path(pkgdir, "DESCRIPTION") + desc_lines <- readLines(desc_path) + remotes_fields <- c( + "RemoteType: github", + "RemoteHost: api.github.com", + "RemoteRepo: renv", + "RemoteUsername: rstudio", + "RemotePkgRef: rstudio/renv", + paste("RemoteRef: ", sha), + paste("RemoteSha: ", sha) + ) + writeLines(c(desc_lines[desc_lines != ""], remotes_fields), con = desc_path) + + # Re-tar + local({ + old <- setwd(tempdir) + on.exit(setwd(old), add = TRUE) + + tar(destfile, compression = "gzip") + }) + invisible() + } + + # Extract the commit hash from a git archive. Git archives include the SHA1 + # hash as the comment field of the tarball pax extended header + # (see https://www.kernel.org/pub/software/scm/git/docs/git-archive.html) + # For GitHub archives this should be the first header after the default one + # (512 byte) header. + renv_bootstrap_git_extract_sha1_tar <- function(bundle) { + + # open the bundle for reading + # We use gzcon for everything because (from ?gzcon) + # > Reading from a connection which does not supply a ‘gzip’ magic + # > header is equivalent to reading from the original connection + conn <- gzcon(file(bundle, open = "rb", raw = TRUE)) + on.exit(close(conn)) + + # The default pax header is 512 bytes long and the first pax extended header + # with the comment should be 51 bytes long + # `52 comment=` (11 chars) + 40 byte SHA1 hash + len <- 0x200 + 0x33 + res <- rawToChar(readBin(conn, "raw", n = len)[0x201:len]) + + if (grepl("^52 comment=", res)) { + sub("52 comment=", "", res) + } else { + NULL + } + } + renv_bootstrap_install <- function(version, tarball, library) { # attempt to install it into project library - message("* Installing renv ", version, " ... ", appendLF = FALSE) dir.create(library, showWarnings = FALSE, recursive = TRUE) + output <- renv_bootstrap_install_impl(library, tarball) + + # check for successful install + status <- attr(output, "status") + if (is.null(status) || identical(status, 0L)) + return(status) + + # an error occurred; report it + header <- "installation of renv failed" + lines <- paste(rep.int("=", nchar(header)), collapse = "") + text <- paste(c(header, lines, output), collapse = "\n") + stop(text) + + } + + renv_bootstrap_install_impl <- function(library, tarball) { # invoke using system2 so we can capture and report output bin <- R.home("bin") exe <- if (Sys.info()[["sysname"]] == "Windows") "R.exe" else "R" - r <- file.path(bin, exe) + R <- file.path(bin, exe) args <- c( "--vanilla", "CMD", "INSTALL", "--no-multiarch", @@ -433,19 +554,7 @@ local({ shQuote(path.expand(tarball)) ) - output <- system2(r, args, stdout = TRUE, stderr = TRUE) - message("Done!") - - # check for successful install - status <- attr(output, "status") - if (is.numeric(status) && !identical(status, 0L)) { - header <- "Error installing renv:" - lines <- paste(rep.int("=", nchar(header)), collapse = "") - text <- c(header, lines, output) - writeLines(text, con = stderr()) - } - - status + system2(R, args, stdout = TRUE, stderr = TRUE) } @@ -655,34 +764,60 @@ local({ } - renv_bootstrap_validate_version <- function(version) { + renv_bootstrap_validate_version <- function(version, description = NULL) { - loadedversion <- utils::packageDescription("renv", fields = "Version") - if (version == loadedversion) - return(TRUE) + # resolve description file + description <- description %||% { + path <- getNamespaceInfo("renv", "path") + packageDescription("renv", lib.loc = dirname(path)) + } - # assume four-component versions are from GitHub; - # three-component versions are from CRAN - components <- strsplit(loadedversion, "[.-]")[[1]] - remote <- if (length(components) == 4L) - paste("rstudio/renv", loadedversion, sep = "@") + # check whether requested version 'version' matches loaded version of renv + sha <- attr(version, "sha", exact = TRUE) + valid <- if (!is.null(sha)) + renv_bootstrap_validate_version_dev(sha, description) else - paste("renv", loadedversion, sep = "@") + renv_bootstrap_validate_version_release(version, description) + + if (valid) + return(TRUE) + + # the loaded version of renv doesn't match the requested version; + # give the user instructions on how to proceed + remote <- if (!is.null(description[["RemoteSha"]])) { + paste("rstudio/renv", description[["RemoteSha"]], sep = "@") + } else { + paste("renv", description[["Version"]], sep = "@") + } + + # display both loaded version + sha if available + friendly <- renv_bootstrap_version_friendly( + version = description[["Version"]], + sha = description[["RemoteSha"]] + ) fmt <- paste( "renv %1$s was loaded from project library, but this project is configured to use renv %2$s.", - "Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile.", - "Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library.", + "- Use `renv::record(\"%3$s\")` to record renv %1$s in the lockfile.", + "- Use `renv::restore(packages = \"renv\")` to install renv %2$s into the project library.", sep = "\n" ) - - msg <- sprintf(fmt, loadedversion, version, remote) - warning(msg, call. = FALSE) + catf(fmt, friendly, renv_bootstrap_version_friendly(version), remote) FALSE } + renv_bootstrap_validate_version_dev <- function(version, description) { + expected <- description[["RemoteSha"]] + is.character(expected) && startswith(expected, version) + } + + renv_bootstrap_validate_version_release <- function(version, description) { + expected <- description[["Version"]] + is.character(expected) && identical(expected, version) + } + renv_bootstrap_hash_text <- function(text) { hashfile <- tempfile("renv-hash-") @@ -847,6 +982,40 @@ local({ } + renv_bootstrap_version_friendly <- function(version, sha = NULL) { + sha <- sha %||% attr(version, "sha", exact = TRUE) + parts <- c(version, sprintf("[sha: %s]", substring(sha, 1L, 7L))) + paste(parts, collapse = " ") + } + + renv_bootstrap_run <- function(version, libpath) { + + # perform bootstrap + bootstrap(version, libpath) + + # exit early if we're just testing bootstrap + if (!is.na(Sys.getenv("RENV_BOOTSTRAP_INSTALL_ONLY", unset = NA))) + return(TRUE) + + # try again to load + if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) { + return(renv::load(project = getwd())) + } + + # failed to download or load renv; warn the user + msg <- c( + "Failed to find an renv installation: the project will not be loaded.", + "Use `renv::activate()` to re-initialize the project." + ) + + warning(paste(msg, collapse = "\n"), call. = FALSE) + + } + + + renv_bootstrap_in_rstudio <- function() { + commandArgs()[[1]] == "RStudio" + } renv_json_read <- function(file = NULL, text = NULL) { @@ -990,31 +1159,23 @@ local({ if (renv_bootstrap_load(project, libpath, version)) return(TRUE) - # load failed; inform user we're about to bootstrap - prefix <- paste("# Bootstrapping renv", version) - postfix <- paste(rep.int("-", 77L - nchar(prefix)), collapse = "") - header <- paste(prefix, postfix) - message(header) - - # perform bootstrap - bootstrap(version, libpath) - - # exit early if we're just testing bootstrap - if (!is.na(Sys.getenv("RENV_BOOTSTRAP_INSTALL_ONLY", unset = NA))) - return(TRUE) + if (renv_bootstrap_in_rstudio()) { + setHook("rstudio.sessionInit", function(...) { + renv_bootstrap_run(version, libpath) - # try again to load - if (requireNamespace("renv", lib.loc = libpath, quietly = TRUE)) { - message("* Successfully installed and loaded renv ", version, ".") - return(renv::load()) + # Work around buglet in RStudio if hook uses readline + tryCatch( + { + tools <- as.environment("tools:rstudio") + tools$.rs.api.sendToConsole("", echo = FALSE, focus = FALSE) + }, + error = function(cnd) {} + ) + }) + } else { + renv_bootstrap_run(version, libpath) } - # failed to download or load renv; warn the user - msg <- c( - "Failed to find an renv installation: the project will not be loaded.", - "Use `renv::activate()` to re-initialize the project." - ) - - warning(paste(msg, collapse = "\n"), call. = FALSE) + invisible() }) diff --git a/renv/profiles/4.1/renv.lock b/renv/profiles/4.1/renv.lock index 0f3ac2c8a4..5801ed10a5 100644 --- a/renv/profiles/4.1/renv.lock +++ b/renv/profiles/4.1/renv.lock @@ -4,7 +4,7 @@ "Repositories": [ { "Name": "CRAN", - "URL": "https://cloud.r-project.org" + "URL": "https://packagemanager.posit.co/cran/latest" }, { "Name": "RSPM", @@ -179,7 +179,7 @@ "Package": "callr", "Version": "3.7.3", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -188,11 +188,23 @@ ], "Hash": "9b2191ede20fa29828139b9900922e51" }, + "cellranger": { + "Package": "cellranger", + "Version": "1.1.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "rematch", + "tibble" + ], + "Hash": "f61dbaec772ccd2e17705c1e872e9e7c" + }, "cli": { "Package": "cli", "Version": "3.4.1", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "utils" @@ -219,6 +231,13 @@ ], "Hash": "019388fc48e48b3da0d3a76ff94608a8" }, + "collections": { + "Package": "collections", + "Version": "0.3.5", + "Source": "Repository", + "Repository": "RSPM", + "Hash": "92537c684a3d2eaa6bd8f65c28ef97f0" + }, "commonmark": { "Package": "commonmark", "Version": "1.8.0", @@ -250,7 +269,7 @@ "Package": "cpp11", "Version": "0.4.3", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Hash": "ed588261931ee3be2c700d22e94a29ab" }, "crayon": { @@ -320,7 +339,7 @@ "Package": "desc", "Version": "1.4.2", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -423,7 +442,7 @@ "Package": "dplyr", "Version": "1.1.1", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -704,7 +723,7 @@ "Package": "knitr", "Version": "1.40", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "evaluate", @@ -717,6 +736,30 @@ ], "Hash": "caea8b0f899a0b1738444b9bc47067e7" }, + "languageserver": { + "Package": "languageserver", + "Version": "0.3.12", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "R6", + "callr", + "collections", + "fs", + "jsonlite", + "lintr", + "parallel", + "roxygen2", + "stringi", + "styler", + "tools", + "utils", + "xml2", + "xmlparsedata" + ], + "Hash": "f62ed8b09fd56cd70291bd077bc52c4b" + }, "later": { "Package": "later", "Version": "1.3.0", @@ -742,7 +785,7 @@ "Package": "lifecycle", "Version": "1.0.3", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -755,7 +798,7 @@ "Package": "lintr", "Version": "3.0.2", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "backports", @@ -841,7 +884,7 @@ "Package": "pillar", "Version": "1.9.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "cli", "fansi", @@ -886,7 +929,7 @@ "Package": "pkgdown", "Version": "2.0.7", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "bslib", @@ -948,7 +991,7 @@ "Package": "processx", "Version": "3.6.1", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -957,6 +1000,19 @@ ], "Hash": "a11891e28c1f1e5ddd773ba1b8c07cf6" }, + "progress": { + "Package": "progress", + "Version": "1.2.2", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R6", + "crayon", + "hms", + "prettyunits" + ], + "Hash": "14dc9f7a3c91ebb14ec5bb9208a07061" + }, "promises": { "Package": "promises", "Version": "1.2.0.1", @@ -1038,6 +1094,27 @@ ], "Hash": "8f25ebe2ec38b1f2aef3b0d2ef76f6c4" }, + "readxl": { + "Package": "readxl", + "Version": "1.3.1", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "Rcpp", + "cellranger", + "progress", + "tibble", + "utils" + ], + "Hash": "63537c483c2dbec8d9e3183b3735254a" + }, + "rematch": { + "Package": "rematch", + "Version": "1.0.1", + "Source": "Repository", + "Repository": "RSPM", + "Hash": "c66b930d20bb6d858cd18e1cebcfae5c" + }, "rematch2": { "Package": "rematch2", "Version": "2.1.2", @@ -1050,7 +1127,7 @@ }, "remotes": { "Package": "remotes", - "Version": "2.4.2", + "Version": "2.4.2.1", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1060,17 +1137,17 @@ "tools", "utils" ], - "Hash": "227045be9aee47e6dda9bb38ac870d67" + "Hash": "63d15047eb239f95160112bcadc4fcb9" }, "renv": { "Package": "renv", - "Version": "0.17.0", + "Version": "1.0.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "utils" ], - "Hash": "ce3065fc1a0b64a859f55ac3998d6927" + "Hash": "c321cd99d56443dbffd1c9e673c0c1a2" }, "rex": { "Package": "rex", @@ -1086,7 +1163,7 @@ "Package": "rlang", "Version": "1.1.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "utils" @@ -1097,7 +1174,7 @@ "Package": "rmarkdown", "Version": "2.17", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "bslib", @@ -1120,7 +1197,7 @@ "Package": "roxygen2", "Version": "7.2.3", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -1257,14 +1334,14 @@ }, "staged.dependencies": { "Package": "staged.dependencies", - "Version": "0.2.8", + "Version": "0.3.1", "Source": "GitHub", "RemoteType": "github", "RemoteHost": "api.github.com", "RemoteUsername": "openpharma", "RemoteRepo": "staged.dependencies", "RemoteRef": "main", - "RemoteSha": "ce7c112ba3d75cf48e4dd6310b3140ab0ec3b486", + "RemoteSha": "1ab184a029bef8839a57bb6acd1c5c919cf1fd89", "Requirements": [ "desc", "devtools", @@ -1285,7 +1362,7 @@ "withr", "yaml" ], - "Hash": "89f2e1d1009601f58f64b7092abcc0d7" + "Hash": "ea298f9fb221a8c7ca4c9e55e9c29b48" }, "stringi": { "Package": "stringi", @@ -1317,7 +1394,7 @@ "Package": "styler", "Version": "1.9.1", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R.cache", @@ -1354,7 +1431,7 @@ "Package": "testthat", "Version": "3.1.7", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -1396,7 +1473,7 @@ "Package": "tibble", "Version": "3.2.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "fansi", @@ -1437,7 +1514,7 @@ "Package": "tidyselect", "Version": "1.2.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -1504,7 +1581,7 @@ "Package": "vctrs", "Version": "0.6.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "cli", @@ -1518,7 +1595,7 @@ "Package": "waldo", "Version": "0.4.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "cli", "diffobj", @@ -1555,7 +1632,7 @@ "Package": "xfun", "Version": "0.34", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "stats", "tools" diff --git a/renv/profiles/4.1/renv/settings.dcf b/renv/profiles/4.1/renv/settings.dcf deleted file mode 100644 index fd205f802c..0000000000 --- a/renv/profiles/4.1/renv/settings.dcf +++ /dev/null @@ -1,10 +0,0 @@ -bioconductor.version: -external.libraries: -ignored.packages: admiral, admiraldev, admiral.test, admiralci -package.dependency.fields: Imports, Depends, LinkingTo -r.version: -snapshot.type: implicit -use.cache: TRUE -vcs.ignore.cellar: TRUE -vcs.ignore.library: TRUE -vcs.ignore.local: TRUE diff --git a/renv/profiles/4.1/renv/settings.json b/renv/profiles/4.1/renv/settings.json new file mode 100644 index 0000000000..4922677e15 --- /dev/null +++ b/renv/profiles/4.1/renv/settings.json @@ -0,0 +1,25 @@ +{ + "bioconductor.version": null, + "external.libraries": [], + "ignored.packages": [ + "admiral", + "admiraldev", + "admiral.test", + "admiralci", + "pharmaversesdtm" + ], + "package.dependency.fields": [ + "Imports", + "Depends", + "LinkingTo" + ], + "ppm.enabled": null, + "ppm.ignored.urls": [], + "r.version": null, + "snapshot.type": "custom", + "use.cache": true, + "vcs.ignore.cellar": true, + "vcs.ignore.library": true, + "vcs.ignore.local": true, + "vcs.manage.ignores": true +} diff --git a/renv/profiles/4.2/renv.lock b/renv/profiles/4.2/renv.lock index 0bb8fc5653..7661270b89 100644 --- a/renv/profiles/4.2/renv.lock +++ b/renv/profiles/4.2/renv.lock @@ -4,7 +4,7 @@ "Repositories": [ { "Name": "CRAN", - "URL": "https://cloud.r-project.org" + "URL": "https://packagemanager.posit.co/cran/latest" }, { "Name": "RSPM", @@ -192,6 +192,18 @@ ], "Hash": "9b2191ede20fa29828139b9900922e51" }, + "cellranger": { + "Package": "cellranger", + "Version": "1.1.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "rematch", + "tibble" + ], + "Hash": "f61dbaec772ccd2e17705c1e872e9e7c" + }, "cli": { "Package": "cli", "Version": "3.6.0", @@ -223,6 +235,13 @@ ], "Hash": "c089a619a7fae175d149d89164f8c7d8" }, + "collections": { + "Package": "collections", + "Version": "0.3.7", + "Source": "Repository", + "Repository": "RSPM", + "Hash": "90a0eda114ab0bef170ddbf5ef0cd93f" + }, "commonmark": { "Package": "commonmark", "Version": "1.8.1", @@ -429,7 +448,7 @@ "Package": "dplyr", "Version": "1.1.1", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -749,6 +768,30 @@ ], "Hash": "8329a9bcc82943c8069104d4be3ee22d" }, + "languageserver": { + "Package": "languageserver", + "Version": "0.3.15", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "R6", + "callr", + "collections", + "fs", + "jsonlite", + "lintr", + "parallel", + "roxygen2", + "stringi", + "styler", + "tools", + "utils", + "xml2", + "xmlparsedata" + ], + "Hash": "fbea0dd12b4f5dedbe3654e4b9cbbddc" + }, "later": { "Package": "later", "Version": "1.3.0", @@ -876,7 +919,7 @@ "Package": "pillar", "Version": "1.9.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "cli", "fansi", @@ -1007,6 +1050,19 @@ ], "Hash": "e9d21e79848e02e524bea6f5bd53e7e4" }, + "progress": { + "Package": "progress", + "Version": "1.2.2", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R6", + "crayon", + "hms", + "prettyunits" + ], + "Hash": "14dc9f7a3c91ebb14ec5bb9208a07061" + }, "promises": { "Package": "promises", "Version": "1.2.0.1", @@ -1091,6 +1147,28 @@ ], "Hash": "8f25ebe2ec38b1f2aef3b0d2ef76f6c4" }, + "readxl": { + "Package": "readxl", + "Version": "1.4.2", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "cellranger", + "cpp11", + "progress", + "tibble", + "utils" + ], + "Hash": "2e6020b1399d95f947ed867045e9ca17" + }, + "rematch": { + "Package": "rematch", + "Version": "1.0.1", + "Source": "Repository", + "Repository": "RSPM", + "Hash": "c66b930d20bb6d858cd18e1cebcfae5c" + }, "rematch2": { "Package": "rematch2", "Version": "2.1.2", @@ -1103,7 +1181,7 @@ }, "remotes": { "Package": "remotes", - "Version": "2.4.2", + "Version": "2.4.2.1", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1113,17 +1191,17 @@ "tools", "utils" ], - "Hash": "227045be9aee47e6dda9bb38ac870d67" + "Hash": "63d15047eb239f95160112bcadc4fcb9" }, "renv": { "Package": "renv", - "Version": "0.17.0", + "Version": "1.0.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "utils" ], - "Hash": "ce3065fc1a0b64a859f55ac3998d6927" + "Hash": "c321cd99d56443dbffd1c9e673c0c1a2" }, "rex": { "Package": "rex", @@ -1173,7 +1251,7 @@ "Package": "roxygen2", "Version": "7.2.3", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -1310,14 +1388,14 @@ }, "staged.dependencies": { "Package": "staged.dependencies", - "Version": "0.2.8", + "Version": "0.3.1", "Source": "GitHub", "RemoteType": "github", "RemoteHost": "api.github.com", "RemoteUsername": "openpharma", "RemoteRepo": "staged.dependencies", "RemoteRef": "main", - "RemoteSha": "ce7c112ba3d75cf48e4dd6310b3140ab0ec3b486", + "RemoteSha": "1ab184a029bef8839a57bb6acd1c5c919cf1fd89", "Requirements": [ "desc", "devtools", @@ -1338,7 +1416,7 @@ "withr", "yaml" ], - "Hash": "89f2e1d1009601f58f64b7092abcc0d7" + "Hash": "ea298f9fb221a8c7ca4c9e55e9c29b48" }, "stringi": { "Package": "stringi", @@ -1587,7 +1665,7 @@ "Package": "vctrs", "Version": "0.6.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "cli", diff --git a/renv/profiles/4.2/renv/settings.dcf b/renv/profiles/4.2/renv/settings.dcf deleted file mode 100644 index fd205f802c..0000000000 --- a/renv/profiles/4.2/renv/settings.dcf +++ /dev/null @@ -1,10 +0,0 @@ -bioconductor.version: -external.libraries: -ignored.packages: admiral, admiraldev, admiral.test, admiralci -package.dependency.fields: Imports, Depends, LinkingTo -r.version: -snapshot.type: implicit -use.cache: TRUE -vcs.ignore.cellar: TRUE -vcs.ignore.library: TRUE -vcs.ignore.local: TRUE diff --git a/renv/profiles/4.2/renv/settings.json b/renv/profiles/4.2/renv/settings.json new file mode 100644 index 0000000000..4922677e15 --- /dev/null +++ b/renv/profiles/4.2/renv/settings.json @@ -0,0 +1,25 @@ +{ + "bioconductor.version": null, + "external.libraries": [], + "ignored.packages": [ + "admiral", + "admiraldev", + "admiral.test", + "admiralci", + "pharmaversesdtm" + ], + "package.dependency.fields": [ + "Imports", + "Depends", + "LinkingTo" + ], + "ppm.enabled": null, + "ppm.ignored.urls": [], + "r.version": null, + "snapshot.type": "custom", + "use.cache": true, + "vcs.ignore.cellar": true, + "vcs.ignore.library": true, + "vcs.ignore.local": true, + "vcs.manage.ignores": true +} diff --git a/renv/profiles/4.3/renv.lock b/renv/profiles/4.3/renv.lock index b875a5b89e..1ce40dbace 100644 --- a/renv/profiles/4.3/renv.lock +++ b/renv/profiles/4.3/renv.lock @@ -1,10 +1,10 @@ { "R": { - "Version": "4.3.0", + "Version": "4.3.1", "Repositories": [ { "Name": "CRAN", - "URL": "https://cloud.r-project.org" + "URL": "https://packagemanager.posit.co/cran/latest" }, { "Name": "RSPM", @@ -192,6 +192,18 @@ ], "Hash": "9b2191ede20fa29828139b9900922e51" }, + "cellranger": { + "Package": "cellranger", + "Version": "1.1.0", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "rematch", + "tibble" + ], + "Hash": "f61dbaec772ccd2e17705c1e872e9e7c" + }, "cli": { "Package": "cli", "Version": "3.6.1", @@ -223,6 +235,13 @@ ], "Hash": "c089a619a7fae175d149d89164f8c7d8" }, + "collections": { + "Package": "collections", + "Version": "0.3.7", + "Source": "Repository", + "Repository": "RSPM", + "Hash": "90a0eda114ab0bef170ddbf5ef0cd93f" + }, "commonmark": { "Package": "commonmark", "Version": "1.9.0", @@ -748,6 +767,30 @@ ], "Hash": "8329a9bcc82943c8069104d4be3ee22d" }, + "languageserver": { + "Package": "languageserver", + "Version": "0.3.15", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "R6", + "callr", + "collections", + "fs", + "jsonlite", + "lintr", + "parallel", + "roxygen2", + "stringi", + "styler", + "tools", + "utils", + "xml2", + "xmlparsedata" + ], + "Hash": "fbea0dd12b4f5dedbe3654e4b9cbbddc" + }, "later": { "Package": "later", "Version": "1.3.0", @@ -1006,6 +1049,19 @@ ], "Hash": "e9d21e79848e02e524bea6f5bd53e7e4" }, + "progress": { + "Package": "progress", + "Version": "1.2.2", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R6", + "crayon", + "hms", + "prettyunits" + ], + "Hash": "14dc9f7a3c91ebb14ec5bb9208a07061" + }, "promises": { "Package": "promises", "Version": "1.2.0.1", @@ -1090,6 +1146,28 @@ ], "Hash": "8f25ebe2ec38b1f2aef3b0d2ef76f6c4" }, + "readxl": { + "Package": "readxl", + "Version": "1.4.2", + "Source": "Repository", + "Repository": "RSPM", + "Requirements": [ + "R", + "cellranger", + "cpp11", + "progress", + "tibble", + "utils" + ], + "Hash": "2e6020b1399d95f947ed867045e9ca17" + }, + "rematch": { + "Package": "rematch", + "Version": "1.0.1", + "Source": "Repository", + "Repository": "RSPM", + "Hash": "c66b930d20bb6d858cd18e1cebcfae5c" + }, "rematch2": { "Package": "rematch2", "Version": "2.1.2", @@ -1102,7 +1180,7 @@ }, "remotes": { "Package": "remotes", - "Version": "2.4.2", + "Version": "2.4.2.1", "Source": "Repository", "Repository": "RSPM", "Requirements": [ @@ -1112,17 +1190,17 @@ "tools", "utils" ], - "Hash": "227045be9aee47e6dda9bb38ac870d67" + "Hash": "63d15047eb239f95160112bcadc4fcb9" }, "renv": { "Package": "renv", - "Version": "0.17.0", + "Version": "1.0.0", "Source": "Repository", "Repository": "RSPM", "Requirements": [ "utils" ], - "Hash": "ce3065fc1a0b64a859f55ac3998d6927" + "Hash": "c321cd99d56443dbffd1c9e673c0c1a2" }, "rex": { "Package": "rex", @@ -1173,7 +1251,7 @@ "Package": "roxygen2", "Version": "7.2.3", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "R6", @@ -1310,14 +1388,14 @@ }, "staged.dependencies": { "Package": "staged.dependencies", - "Version": "0.2.8", + "Version": "0.3.1", "Source": "GitHub", "RemoteType": "github", "RemoteHost": "api.github.com", "RemoteUsername": "openpharma", "RemoteRepo": "staged.dependencies", "RemoteRef": "main", - "RemoteSha": "ce7c112ba3d75cf48e4dd6310b3140ab0ec3b486", + "RemoteSha": "1ab184a029bef8839a57bb6acd1c5c919cf1fd89", "Requirements": [ "desc", "devtools", @@ -1338,7 +1416,7 @@ "withr", "yaml" ], - "Hash": "89f2e1d1009601f58f64b7092abcc0d7" + "Hash": "ea298f9fb221a8c7ca4c9e55e9c29b48" }, "stringi": { "Package": "stringi", diff --git a/renv/profiles/4.3/renv/settings.dcf b/renv/profiles/4.3/renv/settings.dcf deleted file mode 100644 index fd205f802c..0000000000 --- a/renv/profiles/4.3/renv/settings.dcf +++ /dev/null @@ -1,10 +0,0 @@ -bioconductor.version: -external.libraries: -ignored.packages: admiral, admiraldev, admiral.test, admiralci -package.dependency.fields: Imports, Depends, LinkingTo -r.version: -snapshot.type: implicit -use.cache: TRUE -vcs.ignore.cellar: TRUE -vcs.ignore.library: TRUE -vcs.ignore.local: TRUE diff --git a/renv/profiles/4.3/renv/settings.json b/renv/profiles/4.3/renv/settings.json new file mode 100644 index 0000000000..4922677e15 --- /dev/null +++ b/renv/profiles/4.3/renv/settings.json @@ -0,0 +1,25 @@ +{ + "bioconductor.version": null, + "external.libraries": [], + "ignored.packages": [ + "admiral", + "admiraldev", + "admiral.test", + "admiralci", + "pharmaversesdtm" + ], + "package.dependency.fields": [ + "Imports", + "Depends", + "LinkingTo" + ], + "ppm.enabled": null, + "ppm.ignored.urls": [], + "r.version": null, + "snapshot.type": "custom", + "use.cache": true, + "vcs.ignore.cellar": true, + "vcs.ignore.library": true, + "vcs.ignore.local": true, + "vcs.manage.ignores": true +} diff --git a/renv/settings.dcf b/renv/settings.dcf deleted file mode 100644 index fd205f802c..0000000000 --- a/renv/settings.dcf +++ /dev/null @@ -1,10 +0,0 @@ -bioconductor.version: -external.libraries: -ignored.packages: admiral, admiraldev, admiral.test, admiralci -package.dependency.fields: Imports, Depends, LinkingTo -r.version: -snapshot.type: implicit -use.cache: TRUE -vcs.ignore.cellar: TRUE -vcs.ignore.library: TRUE -vcs.ignore.local: TRUE diff --git a/renv/settings.json b/renv/settings.json new file mode 100644 index 0000000000..3462f3b093 --- /dev/null +++ b/renv/settings.json @@ -0,0 +1,24 @@ +{ + "bioconductor.version": null, + "external.libraries": [], + "ignored.packages": [ + "admiral", + "admiraldev", + "admiral.test", + "admiralci" + ], + "package.dependency.fields": [ + "Imports", + "Depends", + "LinkingTo" + ], + "ppm.enabled": null, + "ppm.ignored.urls": [], + "r.version": null, + "snapshot.type": "custom", + "use.cache": true, + "vcs.ignore.cellar": true, + "vcs.ignore.library": true, + "vcs.ignore.local": true, + "vcs.manage.ignores": true +} diff --git a/staged_dependencies.yaml b/staged_dependencies.yaml index 0a29129f89..b6caaf8357 100644 --- a/staged_dependencies.yaml +++ b/staged_dependencies.yaml @@ -1,6 +1,6 @@ --- upstream_repos: -- repo: pharmaverse/admiral.test +- repo: pharmaverse/pharmaversesdtm host: https://github.com - repo: pharmaverse/admiraldev host: https://github.com diff --git a/tests/testthat/_snaps/derive_var_ontrtfl.md b/tests/testthat/_snaps/derive_var_ontrtfl.md new file mode 100644 index 0000000000..3691a7a12f --- /dev/null +++ b/tests/testthat/_snaps/derive_var_ontrtfl.md @@ -0,0 +1,24 @@ +# derive_var_ontrtfl Test 15: if trt end date is missing, the obs may still be flagged + + Code + derive_var_ontrtfl(adcm, start_date = ASTDT, end_date = AENDT, ref_start_date = TRTSDT, + ref_end_date = TRTEDT, span_period = TRUE) + Output + USUBJID ASTDT TRTSDT TRTEDT AENDT ONTRTFL + 1 P01 2018-03-15 2019-01-01 NA 2022-12-01 Y + 2 P02 2020-04-30 2019-01-01 NA 2022-03-15 Y + 3 P03 2020-04-30 2019-01-01 NA Y + 4 P04 2020-04-30 NA + +--- + + Code + derive_var_ontrtfl(adcm, start_date = ASTDT, end_date = AENDT, ref_start_date = TRTSDT, + ref_end_date = TRTEDT) + Output + USUBJID ASTDT TRTSDT TRTEDT AENDT ONTRTFL + 1 P01 2018-03-15 2019-01-01 NA 2022-12-01 + 2 P02 2020-04-30 2019-01-01 NA 2022-03-15 Y + 3 P03 2020-04-30 2019-01-01 NA Y + 4 P04 2020-04-30 NA + diff --git a/tests/testthat/_snaps/duplicates.md b/tests/testthat/_snaps/duplicates.md new file mode 100644 index 0000000000..3c06d4b273 --- /dev/null +++ b/tests/testthat/_snaps/duplicates.md @@ -0,0 +1,14 @@ +# signal_duplicate_records Test 2: dataset of duplicate records can be accessed using `get_duplicates_dataset()` + + Code + get_duplicates_dataset() + Output + Duplicate records with respect to `USUBJID`. + # A tibble: 4 x 3 + USUBJID COUNTRY AAGE + * + 1 P01 GER 22 + 2 P01 JPN 34 + 3 P04 BRA 21 + 4 P04 BRA 21 + diff --git a/tests/testthat/_snaps/user_utils.md b/tests/testthat/_snaps/user_utils.md new file mode 100644 index 0000000000..6242fdd888 --- /dev/null +++ b/tests/testthat/_snaps/user_utils.md @@ -0,0 +1,12 @@ +# print_named_list Test 18: named list with unamed list + + Code + print_named_list(list(list_item = list("Hello World!", expr(universe), list(42)), + another_one = ymd("2020-02-02"))) + Output + list_item: + "Hello World!" + universe + 42 + another_one: 2020-02-02 + diff --git a/tests/testthat/test-call_derivation.R b/tests/testthat/test-call_derivation.R index 85df65f2e9..3fedf501fc 100644 --- a/tests/testthat/test-call_derivation.R +++ b/tests/testthat/test-call_derivation.R @@ -1,7 +1,7 @@ ## Test 1: Test that call_derivation generates expected summary ---- # ---- call_derivation Test 1: Test that call_derivation generates expected summary ---- test_that("call_derivation Test 1: Test that call_derivation generates expected summary", { - input <- admiral.test::admiral_vs[sample(seq_len(nrow(admiral.test::admiral_vs)), 1000), ] + input <- pharmaversesdtm::vs[sample(seq_len(nrow(pharmaversesdtm::vs)), 1000), ] expected_output <- input %>% derive_summary_records( @@ -58,7 +58,7 @@ test_that("call_derivation Test 1: Test that call_derivation generates expected ## Test 2: Test that call_derivation generates expected imputation ---- # ---- call_derivation Test 2: Test that call_derivation generates expected imputation ---- test_that("call_derivation Test 2: Test that call_derivation generates expected imputation", { - input <- admiral.test::admiral_ae[sample(seq_len(nrow(admiral.test::admiral_ae)), 1000), ] %>% + input <- pharmaversesdtm::ae[sample(seq_len(nrow(pharmaversesdtm::ae)), 1000), ] %>% left_join(admiral_adsl, by = "USUBJID") expected_output <- input %>% @@ -94,7 +94,7 @@ test_that("call_derivation Test 2: Test that call_derivation generates expected ## Test 3: Test that Error is thrown if ... has no arguments ---- # ---- call_derivation Test 3: Test that Error is thrown if ... has no arguments ---- test_that("call_derivation Test 3: Test that Error is thrown if ... has no arguments", { - input <- admiral.test::admiral_ae[sample(seq_len(nrow(admiral.test::admiral_ae)), 1000), ] %>% + input <- pharmaversesdtm::ae[sample(seq_len(nrow(pharmaversesdtm::ae)), 1000), ] %>% left_join(admiral_adsl, by = "USUBJID") expect_error( @@ -112,7 +112,7 @@ test_that("call_derivation Test 3: Test that Error is thrown if ... has no argum ## Test 4: Error is thrown if ... arguments are not properly named ---- # ---- call_derivation Test 4: Error is thrown if ... arguments are not properly named ---- test_that("call_derivation Test 4: Error is thrown if ... arguments are not properly named", { - input <- admiral.test::admiral_ae[sample(seq_len(nrow(admiral.test::admiral_ae)), 1000), ] %>% + input <- pharmaversesdtm::ae[sample(seq_len(nrow(pharmaversesdtm::ae)), 1000), ] %>% left_join(admiral_adsl, by = "USUBJID") expect_error( @@ -132,7 +132,7 @@ test_that("call_derivation Test 4: Error is thrown if ... arguments are not prop ## Test 5: Error is thrown params is empty ---- # ---- call_derivation Test 5: Error is thrown params is empty ---- test_that("call_derivation Test 5: Error is thrown params is empty", { - input <- admiral.test::admiral_ae[sample(seq_len(nrow(admiral.test::admiral_ae)), 1000), ] %>% + input <- pharmaversesdtm::ae[sample(seq_len(nrow(pharmaversesdtm::ae)), 1000), ] %>% left_join(admiral_adsl, by = "USUBJID") expect_error( @@ -152,7 +152,7 @@ test_that("call_derivation Test 5: Error is thrown params is empty", { ## Test 6: Error is thrown if passed params are not properly named ---- # ---- call_derivation Test 6: Error is thrown if passed params are not properly named ---- test_that("call_derivation Test 6: Error is thrown if passed params are not properly named", { - input <- admiral.test::admiral_ae[sample(seq_len(nrow(admiral.test::admiral_ae)), 1000), ] %>% + input <- pharmaversesdtm::ae[sample(seq_len(nrow(pharmaversesdtm::ae)), 1000), ] %>% left_join(admiral_adsl, by = "USUBJID") expect_error( @@ -173,7 +173,7 @@ test_that("call_derivation Test 6: Error is thrown if passed params are not prop ## Test 7: Error is thrown if `...` arguments are not properly named ---- # ---- call_derivation Test 7: Error is thrown if `...` arguments are not properly named ---- test_that("call_derivation Test 7: Error is thrown if `...` arguments are not properly named", { - input <- admiral.test::admiral_ae[sample(seq_len(nrow(admiral.test::admiral_ae)), 1000), ] %>% + input <- pharmaversesdtm::ae[sample(seq_len(nrow(pharmaversesdtm::ae)), 1000), ] %>% left_join(admiral_adsl, by = "USUBJID") expect_error( diff --git a/tests/testthat/test-compute_age_years.R b/tests/testthat/test-compute_age_years.R index 00a4a9a539..e96d04bff6 100644 --- a/tests/testthat/test-compute_age_years.R +++ b/tests/testthat/test-compute_age_years.R @@ -16,10 +16,10 @@ test_that("compute_age_years Test 1: compute_age_years() works when `age_unit` i ## Test 2: compute_age_years() works when `age_unit` is a vector ---- test_that("compute_age_years Test 2: compute_age_years() works when `age_unit` is a vector", { - age_input <- c(28, 1461, 10227) - age_unit_input <- c("YEARS", "WEEKS", "DAYS") + age_input <- c(28, 1461, 10227, 32) + age_unit_input <- c("YEARS", "WEEKS", "DAYS", NA_character_) - expected_output <- rep(28, 3) + expected_output <- c(28, 28, 28, NA) expect_equal( compute_age_years( diff --git a/tests/testthat/test-compute_duration.R b/tests/testthat/test-compute_duration.R index 1fd49c0307..83e7deb486 100644 --- a/tests/testthat/test-compute_duration.R +++ b/tests/testthat/test-compute_duration.R @@ -1,3 +1,6 @@ +# compute_duration ---- + +## Test 1: Default duration, i.e., relative day ---- test_that("compute_duration Test 1: Default duration, i.e., relative day", { expect_equal( compute_duration( @@ -8,6 +11,7 @@ test_that("compute_duration Test 1: Default duration, i.e., relative day", { ) }) +## Test 2: Fractional duration ---- test_that("compute_duration Test 2: Fractional duration", { expect_equal( compute_duration( @@ -20,6 +24,7 @@ test_that("compute_duration Test 2: Fractional duration", { ) }) +## Test 3: Age in years ---- test_that("compute_duration Test 3: Age in years", { expect_equal( compute_duration( @@ -33,6 +38,7 @@ test_that("compute_duration Test 3: Age in years", { ) }) +## Test 4: Age in months ---- test_that("compute_duration Test 4: Age in months", { expect_equal( compute_duration( @@ -46,6 +52,7 @@ test_that("compute_duration Test 4: Age in months", { ) }) +## Test 5: Age in weeks ---- test_that("compute_duration Test 5: Age in weeks", { expect_equal( compute_duration( @@ -59,6 +66,7 @@ test_that("compute_duration Test 5: Age in weeks", { ) }) +## Test 6: Duration in hours ---- test_that("compute_duration Test 6: Duration in hours", { expect_equal( compute_duration( @@ -71,3 +79,151 @@ test_that("compute_duration Test 6: Duration in hours", { 4.5 ) }) + + +## Test 7: Duration in minutes (minutes option) ---- +test_that("compute_duration Test 7: Duration in minutes (minutes option)", { + expect_equal( + compute_duration( + ymd_hms("2020-12-06T13:00:00"), + ymd_hms("2020-12-06T13:30:00"), + out_unit = "minutes", + floor_in = FALSE, + add_one = FALSE + ), + 30 + ) +}) + +## Test 8: Duration in minutes (min option) ---- +test_that("compute_duration Test 8: Duration in minutes (min option)", { + expect_equal( + compute_duration( + ymd_hms("2020-12-06T13:00:00"), + ymd_hms("2020-12-06T13:30:00"), + out_unit = "min", + floor_in = FALSE, + add_one = FALSE + ), + 30 + ) +}) + + +## Test 9: Duration in seconds (seconds option) ---- +test_that("compute_duration Test 9: Duration in seconds (seconds option)", { + expect_equal( + compute_duration( + ymd_hms("2020-12-06T13:30:00"), + ymd_hms("2020-12-06T13:30:29"), + out_unit = "seconds", + floor_in = FALSE, + add_one = FALSE + ), + 29 + ) +}) + + + +## Test 10: Duration in seconds (sec option) ---- +test_that("compute_duration Test 10: Duration in seconds (sec option)", { + expect_equal( + compute_duration( + ymd_hms("2020-12-06T13:30:00"), + ymd_hms("2020-12-06T13:30:29"), + out_unit = "sec", + floor_in = FALSE, + add_one = FALSE + ), + 29 + ) +}) + + +## Test 11: Duration (instead of interval) ---- +test_that("compute_duration Test 11: Duration (instead of interval)", { + expect_equal( + compute_duration( + ymd("2000-02-01"), + ymd("2000-03-01"), + out_unit = "months", + add_one = FALSE, + type = "duration" + ), + 29 / (365.25 / 12) # 29 days divided by the average month length + ) + + expect_equal( + compute_duration( + ymd("2000-02-01"), + ymd("2001-02-01"), + out_unit = "years", + add_one = FALSE, + type = "duration" + ), + 366 / 365.25 # 366 days in this leap year divided by the average year length + ) +}) + +## Test 12: Interval (instead of duration) ---- +test_that("compute_duration Test 12: Interval (instead of duration)", { + expect_equal( + compute_duration( + ymd("2000-02-01"), + ymd("2000-03-01"), + out_unit = "months", + add_one = FALSE, + type = "interval" + ), + 1 + ) + + expect_equal( + compute_duration( + ymd("2000-02-01"), + ymd("2001-02-01"), + out_unit = "years", + add_one = FALSE, + type = "interval" + ), + 1 + ) +}) + +## Test 13: Interval with duration/interval invariant units ---- +test_that("compute_duration Test 13: Interval with duration/interval invariant units", { + expect_equal( + compute_duration( + ymd("2000-02-01"), + ymd("2000-03-01"), + out_unit = "days", + add_one = FALSE, + type = "interval" + ), + compute_duration( + ymd("2000-02-01"), + ymd("2000-03-01"), + out_unit = "days", + add_one = FALSE, + type = "duration" + ) + ) + + expect_equal( + compute_duration( + ymd("2000-02-01"), + ymd("2001-02-01"), + out_unit = "weeks", + add_one = FALSE, + type = "interval" + ), + compute_duration( + ymd("2000-02-01"), + ymd("2001-02-01"), + out_unit = "weeks", + add_one = FALSE, + type = "duration" + ) + ) +}) diff --git a/tests/testthat/test-compute_kidney.R b/tests/testthat/test-compute_kidney.R index 426fe80da2..f5e1dedc1f 100644 --- a/tests/testthat/test-compute_kidney.R +++ b/tests/testthat/test-compute_kidney.R @@ -27,7 +27,7 @@ test_that("compute_egfr Test 3: CRCL calculation", { # CRCL Cockcroft and Gault (1973) calculator at # https://www.kidney.org/professionals/kdoqi/gfr_calculatorCoc expect_equal(round(compute_egfr( - creat = 1.09, creatu = "mg/dL", age = 55, sex = "M", wt = 90, method = "CRCL" + creat = 1.09, creatu = "mg/dL", age = 55, sex = "M", weight = 90, method = "CRCL" ), 0L), 97) }) @@ -38,7 +38,7 @@ test_that("compute_egfr Test 4: CRCL calculation", { # CRCL Cockcroft and Gault (1973) calculator at # https://www.kidney.org/professionals/kdoqi/gfr_calculatorCoc expect_equal(round(compute_egfr( - creat = 85, creatu = "umol/L", age = 65, sex = "F", wt = 60, method = "CRCL" + creat = 85, creatu = "umol/L", age = 65, sex = "F", weight = 60, method = "CRCL" ), 0L), 55) }) @@ -49,7 +49,7 @@ test_that("compute_egfr Test 5: EGFR MDRD calculation", { # MDRD GFR calculator at # https://www.mdcalc.com/calc/76/mdrd-gfr-equation expect_equal(round(compute_egfr( - creat = 1.09, creatu = "mg/dL", age = 55, sex = "M", wt = 90, race = "WHITE", + creat = 1.09, creatu = "mg/dL", age = 55, sex = "M", weight = 90, race = "WHITE", method = "MDRD" ), 1L), 70.2) }) @@ -87,7 +87,7 @@ test_that("compute_egfr Test 7: CKD-EPI calculated on input data", { egfr <- input %>% dplyr::mutate( EGFR = compute_egfr( - creat = CREATBL, creatu = CREATBLU, age = AGE, wt = WTBL, sex = SEX, + creat = CREATBL, creatu = CREATBLU, age = AGE, weight = WTBL, sex = SEX, method = "CKD-EPI" ), EGFR = round(EGFR, 4L) @@ -99,3 +99,13 @@ test_that("compute_egfr Test 7: CKD-EPI calculated on input data", { keys = c("USUBJID") ) }) + +## Test 8: Deprecate wt ---- +test_that("compute_egfr Test 8: 'wt' argument deprecation warning", { + # expect deprecation warning + expect_warning( + compute_egfr( + creat = 1.09, creatu = "mg/dL", age = 55, sex = "M", wt = 90, method = "CRCL" + ) + ) +}) diff --git a/tests/testthat/test-derive_advs_params.R b/tests/testthat/test-derive_advs_params.R index 0bec22a8d4..06ab54534a 100644 --- a/tests/testthat/test-derive_advs_params.R +++ b/tests/testthat/test-derive_advs_params.R @@ -1,20 +1,23 @@ -# compute_bmi: (Test 01.xx) ---- +# compute_bmi ---- -test_that("compute_bmi Test 01.01: BMI calculation - single height and weight values", { +## 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_that("compute_bmi Test 01.02: BMI calculation - height and weight vectors", { +## 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_that("compute_bmi Test 01.03: BMI calculation - height and weight vectors - missing values", { +## 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_) @@ -23,48 +26,54 @@ test_that("compute_bmi Test 01.03: BMI calculation - height and weight vectors - # compute_bsa ---- -## compute_bsa: Mosteller method (Test 01.xx) ---- +## compute_bsa: Mosteller method ---- # sqrt (Height x Weight / 3600) -test_that("compute_bsa Test 01.01: Mosteller method - single height and weight values", { +## 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_that("compute_bsa Test 01.02: Mosteller method - height and weight vectors", { +## 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_that("compute_bsa Test 01.03: Mosteller method - height and weight vectors - missing values", { +## 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 (Test 02.xx) ---- +## compute_bsa: DuBois-DuBois method ---- # FORMULA : 0.20247 x (HGT/100)^0.725 x WGT^0.425 -test_that("compute_bsa Test 02.01: DuBois-DuBois method - single height and weight values", { +## 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_that("compute_bsa Test 02.02: DuBois-DuBois method - height and weight vectors", { +## 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_that("compute_bsa Test 02.03: DuBois-DuBois method - hgt and wgt vectors - missing values", { +## 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_) @@ -74,129 +83,142 @@ test_that("compute_bsa Test 02.03: DuBois-DuBois method - hgt and wgt vectors - ## compute_bsa: Haycock method (Test 03.xx) ---- # 0.024265 x HGT^0.3964 x WGT^0.5378 -test_that("compute_bsa Test 03.01: Haycock method - single height and weight values", { +## 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_that("compute_bsa Test 03.02: Haycock method - height and weight vectors", { +## 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_that("compute_bsa Test 03.03: Haycock method - height and weight vectors - missing values", { +## 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 (Test 04.xx) ---- +## compute_bsa: Gehan-George method ---- # 0.0235 x HGT^0.42246 x WGT^0.51456 -test_that("compute_bsa Test 04.01: Gehan-George method - single height and weight values", { +## 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_that("compute_bsa Test 04.02: Gehan-George method - height and weight vectors", { +## 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_that(paste( - "compute_bsa Test 04.03: Gehan-George method - height and", - "weight vectors - missing values" -), { +## 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 (Test 05.xx) ---- +## compute_bsa: Boyd method ---- # 0.0003207 x (HGT^0.3) x (1000 x WGT)^(0.7285 - (0.0188 x log10(1000 x WGT))) -test_that("compute_bsa Test 05.01: Boyd method - single height and weight values", { +## 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_that("compute_bsa Test 05.02: Boyd method - height and weight vectors", { +## 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_that("compute_bsa Test 05.03: Boyd method - height and weight vectors - missing values", { +## 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 (Test 06.xx) ---- +## compute_bsa: Fujimoto method ---- # 0.008883 x HGT^0.663 x WGT^0.444 -test_that("compute_bsa Test 06.01: Fujimoto method - single height and weight values", { +## 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_that("compute_bsa Test 06.02: Fujimoto method - height and weight vectors", { +## 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_that("compute_bsa Test 06.03: Fujimoto method - height and weight vectors - missing values", { +## 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 (Test 07.xx) ---- +## compute_bsa: Takahira method ---- # 0.007241 x HGT^0.725 x WGT^0.425 -test_that("compute_bsa Test 07.01: Takahira method - single height and weight values", { +## 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_that("compute_bsa Test 07.02: Takahira method - height and weight vectors", { +## 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_that("compute_bsa Test 07.03: Takahira method - height and weight vectors - missing values", { +## 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 08.xx) ---- +## compute_bsa: Check error messages ---- -test_that("compute_bsa Test 08.01: an error is issued if an invalid method is specified", { +## 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"), paste( @@ -208,74 +230,60 @@ test_that("compute_bsa Test 08.01: an error is issued if an invalid method is sp # compute_map ---- -## compute_map: DBP & SBP (Test 01.xx) ---- +## compute_map: DBP & SBP ---- # ((2 x DBP) + SBP) / 3 -test_that(paste( - "compute_map Test 01.01: Mean Arterial Pressure based on diastolic", - "& systolic BP - single values" -), { +## 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_that(paste( - "compute_map Test 01.02: Mean Arterial Pressure based on diastolic", - "& systolic BP - vectors" -), { +## 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_that(paste( - "compute_map Test 01.03: Mean Arterial Pressure based on diastolic", - "& systolic BP - vectors with missing values" -), { +## 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 (Test 02.xx) ---- +## compute_map: DBP, SBP & HR ---- # DBP + 0.01 x exp(4.14 - 40.74 / PULSE) x (SBP - DBP) -test_that(paste( - "compute_map Test 02.01: Mean Arterial Pressure based on diastolic,", - "systolic BP & heart rate - single values" -), { +## 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_that(paste( - "compute_map Test 02.02: Mean Arterial Pressure based on diastolic,", - "systolic BP & heart rate - vectors" -), { +## 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_that(paste( - "compute_map Test 02.03: Mean Arterial Pressure based on diastolic,", - "systolic blood BP & heart rate - vectors with missing values" -), { +## 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 ---- -## derive_param_bmi: Error checks (Test 01.xx) ---- +## derive_param_bmi: Error checks ---- -test_that(paste( - "derive_param_bmi Test 01.01: BMI parameter NOT added to input dataset", - "- wrong unit for hgt" -), { +## 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 @@ -292,10 +300,8 @@ test_that(paste( ) }) -test_that(paste( - "derive_param_bmi Test 01.02: BMI parameter NOT added to input dataset", - "- wrong unit for wgt" -), { +## 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, @@ -312,10 +318,8 @@ test_that(paste( ) }) -test_that(paste( - "derive_param_bmi Test 01.03: BMI parameter NOT added to input dataset", - "- multiple unit for wgt" -), { +## 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, @@ -333,10 +337,8 @@ test_that(paste( ) }) -test_that(paste( - "derive_param_bmi Test 01.04: BMI parameter NOT added to input dataset", - "- PARAMCD not set" -), { +## 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, @@ -354,9 +356,10 @@ test_that(paste( ) }) -## derive_param_bmi: No obs added (Test 02.xx) ---- +## derive_param_bmi: No obs added ---- -test_that("derive_param_bmi Test 02.01: BMI parameter NOT added to input dataset", { +## 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, @@ -378,13 +381,14 @@ test_that("derive_param_bmi Test 02.01: BMI parameter NOT added to input dataset ) }) -## derive_param_bmi: Obs created (Test 03.xx) ---- +## derive_param_bmi: Obs created ---- bmi <- function(hgt, wgt) { wgt / (hgt / 100)^2 } -test_that("derive_param_bmi Test 03.01: BMI parameter is correctly added to input dataset", { +## 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, @@ -410,14 +414,61 @@ test_that("derive_param_bmi Test 03.01: BMI parameter is correctly added to inpu ) }) + +# 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 01.xx) ---- +## derive_param_bsa: Error checks ---- -test_that(paste( - "derive_param_bsa Test 01.01: BSA parameter NOT added to input dataset", - "- wrong unit for height" -), { +## 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 @@ -439,10 +490,8 @@ test_that(paste( ) }) -test_that(paste( - "derive_param_bsa Test 01.02: BSA parameter NOT added to input dataset", - "- wrong unit for weight" -), { +## 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, @@ -464,10 +513,8 @@ test_that(paste( ) }) -test_that(paste( - "derive_param_bsa Test 01.03: BSA parameter NOT added to input dataset", - "- multiple unit for weight" -), { +## 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, @@ -490,10 +537,8 @@ test_that(paste( ) }) -test_that(paste( - "derive_param_bsa Test 01.04: BSA parameter NOT added to input dataset", - "- PARAMCD not set" -), { +## 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, @@ -515,9 +560,10 @@ test_that(paste( ) }) -## derive_param_bsa: No obs added (Test 02.xx) ---- +## derive_param_bsa: No obs added ---- -test_that("derive_param_bsa Test 02.01: BSA parameter NOT added to input dataset", { +## 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, @@ -544,16 +590,14 @@ test_that("derive_param_bsa Test 02.01: BSA parameter NOT added to input dataset ) }) -## derive_param_bsa: Obs created (Test 03.xx) ---- +## derive_param_bsa: Obs created ---- mosteller <- function(hgt, wgt) { sqrt(hgt * wgt / 3600) } -test_that(paste( - "derive_param_bsa Test 03.01: BSA parameter (Mosteller method) is", - "correctly added to input dataset" -), { +## 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, @@ -587,10 +631,8 @@ dubois <- function(hgt, wgt) { 0.20247 * (hgt / 100)^0.725 * wgt^0.425 } -test_that(paste( - "derive_param_bsa Test 03.02: BSA parameter (DuBois-DuBois method)", - "is correctly added to input dataset" -), { +## 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, @@ -625,10 +667,8 @@ haycock <- function(hgt, wgt) { 0.024265 * hgt^0.3964 * wgt^0.5378 } -test_that(paste( - "derive_param_bsa Test 03.03: BSA parameter (Haycock method) is", - "correctly added to input dataset" -), { +## 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, @@ -662,10 +702,8 @@ gehan <- function(hgt, wgt) { 0.0235 * hgt^0.42246 * wgt^0.51456 } -test_that(paste( - "derive_param_bsa Test 03.04: BSA parameter (Gehan-George method)", - "is correctly added to input dataset" -), { +## 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, @@ -700,10 +738,8 @@ boyd <- function(hgt, wgt) { 0.0003207 * (hgt^0.3) * (1000 * wgt)^(0.7285 - (0.0188 * log10(1000 * wgt))) # nolint } -test_that(paste( - "derive_param_bsa Test 03.05: BSA parameter (Boyd method) is ", - "correctly added to input dataset" -), { +## 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, @@ -737,10 +773,8 @@ fujimoto <- function(hgt, wgt) { 0.008883 * hgt^0.663 * wgt^0.444 } -test_that(paste( - "derive_param_bsa Test 03.06: BSA parameter (Fujimoto method) is", - "correctly added to input dataset" -), { +## 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, @@ -774,10 +808,9 @@ test_that(paste( takahira <- function(hgt, wgt) { 0.007241 * hgt^0.725 * wgt^0.425 } -test_that(paste( - "derive_param_bsa Test 03.07: BSA parameter (Takahira method) is", - "correctly added to input dataset" -), { + +## 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, @@ -808,14 +841,62 @@ test_that(paste( ) }) +## 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 01.xx) ---- +## derive_param_map: Error checks ---- -test_that(paste( - "derive_param_map Test 01.01: MAP parameter NOT added to input dataset", - "- wrong unit for DIABP" -), { +## 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", @@ -835,10 +916,8 @@ test_that(paste( ) }) -test_that(paste( - "derive_param_map Test 01.02: MAP parameter NOT added to input dataset", - "- wrong unit for SYSBP" -), { +## 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", @@ -858,10 +937,8 @@ test_that(paste( ) }) -test_that(paste( - "derive_param_map Test 01.03: MAP parameter NOT added to input dataset", - "- wrong unit for PULSE" -), { +## 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", @@ -883,10 +960,8 @@ test_that(paste( ) }) -test_that(paste( - "derive_param_map Test 01.04: MAP parameter NOT added to input dataset", - "- PARAMCD not set" -), { +## 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", @@ -907,9 +982,10 @@ test_that(paste( ) }) -## derive_param_map: No obs added (Test 02.xx) ---- +## derive_param_map: No obs added ---- -test_that("derive_param_map Test 02.01: MAP parameter NOT added to input dataset", { +## 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", @@ -937,16 +1013,14 @@ test_that("derive_param_map Test 02.01: MAP parameter NOT added to input dataset ) }) -## derive_param_map: Obs created (Test 03.xx) ---- +## derive_param_map: Obs created ---- maphr <- function(sbp, dbp, hr) { dbp + 0.01 * exp(4.14 - 40.74 / hr) * (sbp - dbp) } -test_that(paste( - "derive_param_map Test 03.01: MAP parameter (DBP/SBP/PULSE) is correctly", - "added to input dataset" -), { +## 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, @@ -981,10 +1055,8 @@ map <- function(sbp, dbp) { (2 * dbp + sbp) / 3 } -test_that(paste( - "derive_param_map Test 03.02: MAP parameter (DBP/SBP) is correctly", - "added to input dataset" -), { +## 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, diff --git a/tests/testthat/test-derive_date_vars.R b/tests/testthat/test-derive_date_vars.R index 30946a5ad6..a063f390ee 100644 --- a/tests/testthat/test-derive_date_vars.R +++ b/tests/testthat/test-derive_date_vars.R @@ -532,13 +532,23 @@ inputdtc <- c( "2019-07-18", "2019-02", "2019", - "2019---07" + "2019---07", + "2019---06T00:00", + "2019----T00:00", + "2019-06--T00:00", + "--06-06T00:00", + "-----T00:00" ) inputdt <- c( as.Date("2019-07-18"), as.Date("2019-02-01"), as.Date("2019-01-01"), - as.Date("2019-01-01") + as.Date("2019-01-01"), + as.Date("2019-06-06"), + as.Date("2019-06-06"), + as.Date("2019-06-06"), + as.Date("2019-06-06"), + as.Date("2019-06-06") ) ## Test 29: compute DTF ---- @@ -547,7 +557,12 @@ test_that("compute_dtf Test 29: compute DTF", { NA_character_, "D", "M", - "M" + "M", + "M", + "M", + "D", + "Y", + "Y" ) expect_equal( compute_dtf( diff --git a/tests/testthat/test-derive_expected_records.R b/tests/testthat/test-derive_expected_records.R index 05f0e003bc..0937a4a92c 100644 --- a/tests/testthat/test-derive_expected_records.R +++ b/tests/testthat/test-derive_expected_records.R @@ -30,7 +30,7 @@ test_that("derive_expected_records Test 1: missing values in `by_vars`", { actual_output <- derive_expected_records( dataset = input, - dataset_expected_obs = expected_obsv, + dataset_ref = expected_obsv, by_vars = exprs(USUBJID), set_values_to = exprs(DTYPE = "DERIVED") ) @@ -71,7 +71,7 @@ test_that("derive_expected_records Test 2: `by_vars` = NULL", { actual_output <- derive_expected_records( dataset = input, - dataset_expected_obs = expected_obsv, + dataset_ref = expected_obsv, by_vars = NULL, set_values_to = exprs(DTYPE = "DERIVED") ) @@ -114,7 +114,7 @@ test_that("derive_expected_records Test 3: visit variables are parameter indepen actual_output <- derive_expected_records( dataset = input, - dataset_expected_obs = expected_obsv, + dataset_ref = expected_obsv, by_vars = exprs(USUBJID, PARAMCD), set_values_to = exprs(DTYPE = "DERIVED") ) @@ -157,7 +157,7 @@ test_that("derive_expected_records Test 4: visit variables are parameter depende actual_output <- derive_expected_records( dataset = input, - dataset_expected_obs = expected_obsv, + dataset_ref = expected_obsv, by_vars = exprs(USUBJID), set_values_to = exprs(DTYPE = "DERIVED") ) diff --git a/tests/testthat/test-derive_extreme_event.R b/tests/testthat/test-derive_extreme_event.R index 8905d88e17..426f1f8382 100644 --- a/tests/testthat/test-derive_extreme_event.R +++ b/tests/testthat/test-derive_extreme_event.R @@ -130,3 +130,435 @@ test_that("derive_extreme_records Test 2: `mode` = last", { keys = c("USUBJID", "PARAMCD", "ADY") ) }) + +## Test 3: `source_datasets` works ---- +test_that("derive_extreme_records Test 3: `source_datasets` works", { + adsl <- tibble::tribble( + ~USUBJID, ~TRTSDTC, + "1", "2020-01-01", + "2", "2019-12-12", + "3", "2019-11-11", + "4", "2019-12-30", + "5", "2020-01-01", + "6", "2020-02-02", + "7", "2020-02-02", + "8", "2020-04-01" + ) %>% + mutate( + TRTSDT = lubridate::ymd(TRTSDTC), + STUDYID = "XX1234" + ) + + adrs <- tibble::tribble( + ~USUBJID, ~ADTC, ~AVALC, + "1", "2020-01-01", "PR", + "1", "2020-02-01", "CR", + "1", "2020-02-16", "NE", + "1", "2020-03-01", "CR", + "1", "2020-04-01", "SD", + "2", "2020-01-01", "SD", + "2", "2020-02-01", "PR", + "2", "2020-03-01", "SD", + "2", "2020-03-13", "CR", + "3", "2019-11-12", "CR", + "3", "2019-12-02", "CR", + "3", "2020-01-01", "SD", + "4", "2020-01-01", "PR", + "4", "2020-03-01", "SD", + "4", "2020-04-01", "SD", + "4", "2020-05-01", "PR", + "4", "2020-05-15", "NON-CR/NON-PD", + "5", "2020-01-01", "PR", + "5", "2020-01-10", "SD", + "5", "2020-01-20", "PR", + "5", "2020-05-15", "NON-CR/NON-PD", + "6", "2020-02-06", "PR", + "6", "2020-02-16", "CR", + "6", "2020-03-30", "PR", + "7", "2020-02-06", "PR", + "7", "2020-02-16", "CR", + "7", "2020-04-01", "NE" + ) %>% + mutate( + PARAMCD = "OVR", + ADT = lubridate::ymd(ADTC), + STUDYID = "XX1234" + ) %>% + select(-ADTC) %>% + derive_vars_merged( + dataset_add = adsl, + by_vars = exprs(STUDYID, USUBJID), + new_vars = exprs(TRTSDT) + ) + expected <- bind_rows( + adrs, + tibble::tribble( + ~USUBJID, ~ADTC, ~AVALC, ~TRTSDTC, + "1", "2020-02-01", "CR", "2020-01-01", + "2", "2020-03-13", "CR", "2019-12-12", + "3", "2019-11-12", "CR", "2019-11-11", + "4", "2020-01-01", "PR", "2019-12-30", + "5", "2020-01-01", "PR", "2020-01-01", + "6", "2020-02-16", "CR", "2020-02-02", + "7", "2020-02-16", "CR", "2020-02-02", + "8", "", "MISSING", "2020-04-01" + ) %>% + mutate( + ADT = lubridate::ymd(ADTC), + TRTSDT = lubridate::ymd(TRTSDTC), + STUDYID = "XX1234", + PARAMCD = "BOR", + PARAM = "Best Overall Response" + ) %>% + select(-ADTC, -TRTSDTC) + ) + + actual <- derive_extreme_event( + dataset = adrs, + by_vars = exprs(STUDYID, USUBJID), + order = exprs(ADT), + mode = "first", + source_datasets = list(adsl = adsl), + events = list( + event( + condition = AVALC == "CR", + set_values_to = exprs( + AVALC = "CR" + ) + ), + event( + condition = AVALC == "PR", + set_values_to = exprs( + AVALC = "PR" + ) + ), + event( + condition = AVALC == "SD" & ADT >= TRTSDT + 28, + set_values_to = exprs( + AVALC = "SD" + ) + ), + event( + condition = AVALC == "NON-CR/NON-PD" & ADT >= TRTSDT + 28, + set_values_to = exprs( + AVALC = "NON-CR/NON-PD" + ) + ), + event( + condition = AVALC == "PD", + set_values_to = exprs( + AVALC = "PD" + ) + ), + event( + condition = AVALC %in% c("SD", "NON-CR/NON-PD"), + set_values_to = exprs( + AVALC = "NE" + ) + ), + event( + dataset_name = "adsl", + condition = TRUE, + set_values_to = exprs( + AVALC = "MISSING" + ), + keep_source_vars = exprs(TRTSDT) + ) + ), + set_values_to = exprs( + PARAMCD = "BOR", + PARAM = "Best Overall Response" + ) + ) + + expect_dfs_equal( + base = expected, + compare = actual, + keys = c("USUBJID", "PARAMCD", "ADT") + ) +}) + +## Test 4: event-specific mode ---- +test_that("derive_extreme_records Test 4: event-specific mode", { + adhy <- tibble::tribble( + ~USUBJID, ~AVISITN, ~CRIT1FL, + "1", 1, "Y", + "1", 2, "Y", + "2", 1, "Y", + "2", 2, NA_character_, + "2", 3, "Y", + "2", 4, NA_character_ + ) %>% + mutate( + PARAMCD = "ALKPH", + PARAM = "Alkaline Phosphatase (U/L)" + ) + + actual <- derive_extreme_event( + adhy, + by_vars = exprs(USUBJID), + events = list( + event( + condition = is.na(CRIT1FL), + set_values_to = exprs(AVALC = "N") + ), + event( + condition = CRIT1FL == "Y", + mode = "last", + set_values_to = exprs(AVALC = "Y") + ) + ), + order = exprs(AVISITN), + mode = "first", + keep_source_vars = exprs(AVISITN), + set_values_to = exprs( + PARAMCD = "ALK2", + PARAM = "ALKPH <= 2 times ULN" + ) + ) + + expected <- bind_rows( + adhy, + tribble( + ~USUBJID, ~AVISITN, ~AVALC, + "1", 2, "Y", + "2", 2, "N" + ) %>% + mutate( + PARAMCD = "ALK2", + PARAM = "ALKPH <= 2 times ULN" + ) + ) + + expect_dfs_equal( + base = expected, + compare = actual, + keys = c("USUBJID", "AVISITN", "PARAMCD") + ) +}) + +## Test 5: event_joined() is handled correctly ---- +test_that("derive_extreme_records Test 5: event_joined() is handled correctly", { + adsl <- tibble::tribble( + ~USUBJID, ~TRTSDTC, + "1", "2020-01-01", + "2", "2019-12-12", + "3", "2019-11-11", + "4", "2019-12-30", + "5", "2020-01-01", + "6", "2020-02-02", + "7", "2020-02-02", + "8", "2020-04-01", + "9", "2020-02-01" + ) %>% + mutate( + TRTSDT = lubridate::ymd(TRTSDTC), + STUDYID = "XX1234" + ) + + adrs <- tibble::tribble( + ~USUBJID, ~ADTC, ~AVALC, + "1", "2020-01-01", "PR", + "1", "2020-02-01", "CR", + "1", "2020-02-16", "NE", + "1", "2020-03-01", "CR", + "1", "2020-04-01", "SD", + "2", "2020-01-01", "SD", + "2", "2020-02-01", "PR", + "2", "2020-03-01", "SD", + "2", "2020-03-13", "CR", + "3", "2019-11-12", "CR", + "3", "2019-12-02", "CR", + "3", "2020-01-01", "SD", + "4", "2020-01-01", "PR", + "4", "2020-03-01", "SD", + "4", "2020-04-01", "SD", + "4", "2020-05-01", "PR", + "4", "2020-05-15", "NON-CR/NON-PD", + "5", "2020-01-01", "PR", + "5", "2020-01-10", "SD", + "5", "2020-01-20", "PR", + "5", "2020-05-15", "NON-CR/NON-PD", + "6", "2020-02-06", "PR", + "6", "2020-02-16", "CR", + "6", "2020-03-30", "PR", + "7", "2020-02-06", "PR", + "7", "2020-02-16", "CR", + "7", "2020-04-01", "NE", + "9", "2020-02-16", "PD" + ) %>% + mutate( + PARAMCD = "OVR", + ADT = lubridate::ymd(ADTC), + STUDYID = "XX1234" + ) %>% + derive_vars_merged( + dataset_add = adsl, + by_vars = exprs(STUDYID, USUBJID), + new_vars = exprs(TRTSDT) + ) + + actual <- + derive_extreme_event( + adrs, + by_vars = exprs(STUDYID, USUBJID), + order = exprs(ADT), + mode = "first", + source_datasets = list(adsl = adsl), + events = list( + event_joined( + join_vars = exprs(AVALC, ADT), + join_type = "after", + first_cond = AVALC.join == "CR" & + ADT.join >= ADT + 28, + condition = AVALC == "CR" & + all(AVALC.join %in% c("CR", "NE")) & + count_vals(var = AVALC.join, val = "NE") <= 1, + set_values_to = exprs( + AVALC = "CR" + ) + ), + event_joined( + join_vars = exprs(AVALC, ADT), + join_type = "after", + first_cond = AVALC.join %in% c("CR", "PR") & + ADT.join >= ADT + 28, + condition = AVALC == "PR" & + all(AVALC.join %in% c("CR", "PR", "NE")) & + count_vals(var = AVALC.join, val = "NE") <= 1 & + ( + min_cond( + var = ADT.join, + cond = AVALC.join == "CR" + ) > max_cond(var = ADT.join, cond = AVALC.join == "PR") | + count_vals(var = AVALC.join, val = "CR") == 0 | + count_vals(var = AVALC.join, val = "PR") == 0 + ), + set_values_to = exprs( + AVALC = "PR" + ) + ), + event( + condition = AVALC %in% c("CR", "PR", "SD") & ADT >= TRTSDT + 28, + set_values_to = exprs( + AVALC = "SD" + ) + ), + event( + condition = AVALC == "NON-CR/NON-PD" & ADT >= TRTSDT + 28, + set_values_to = exprs( + AVALC = "NON-CR/NON-PD" + ) + ), + event( + condition = AVALC == "PD", + set_values_to = exprs( + AVALC = "PD" + ) + ), + event( + condition = AVALC %in% c("CR", "PR", "SD", "NON-CR/NON-PD", "NE"), + set_values_to = exprs( + AVALC = "NE" + ) + ), + event( + dataset_name = "adsl", + condition = TRUE, + set_values_to = exprs( + AVALC = "MISSING" + ), + keep_source_vars = exprs(TRTSDT) + ) + ), + set_values_to = exprs( + PARAMCD = "CBOR", + PARAM = "Best Confirmed Overall Response by Investigator" + ) + ) + + expected <- bind_rows( + adrs, + tibble::tribble( + ~USUBJID, ~ADTC, ~AVALC, + "1", "2020-02-01", "CR", + "2", "2020-02-01", "SD", + "3", "2020-01-01", "SD", + "4", "2020-03-01", "SD", + "5", "2020-05-15", "NON-CR/NON-PD", + "6", "2020-03-30", "SD", + "7", "2020-02-06", "NE", + "8", NA_character_, "MISSING", + "9", "2020-02-16", "PD" + ) %>% + mutate( + ADT = lubridate::ymd(ADTC), + STUDYID = "XX1234", + PARAMCD = "CBOR", + PARAM = "Best Confirmed Overall Response by Investigator" + ) %>% + derive_vars_merged( + dataset_add = adsl, + by_vars = exprs(STUDYID, USUBJID), + new_vars = exprs(TRTSDT) + ) + ) + + expect_dfs_equal( + base = expected, + compare = actual, + keys = c("USUBJID", "PARAMCD", "ADT") + ) +}) + +## Test 6: ignore_event_order ---- +test_that("derive_extreme_records Test 6: ignore_event_order", { + adrs <- tibble::tribble( + ~USUBJID, ~AVISITN, ~AVALC, + "1", 1, "PR", + "1", 2, "CR", + "1", 3, "CR" + ) %>% + mutate(PARAMCD = "OVR") + + actual <- derive_extreme_event( + adrs, + by_vars = exprs(USUBJID), + order = exprs(AVISITN), + mode = "first", + events = list( + event_joined( + join_vars = exprs(AVALC), + join_type = "after", + first_cond = AVALC.join == "CR", + condition = AVALC == "CR", + set_values_to = exprs(AVALC = "Y") + ), + event_joined( + join_vars = exprs(AVALC), + join_type = "after", + first_cond = AVALC.join %in% c("CR", "PR"), + condition = AVALC == "PR", + set_values_to = exprs(AVALC = "Y") + ) + ), + ignore_event_order = TRUE, + set_values_to = exprs( + PARAMCD = "CRSP" + ) + ) + + expected <- bind_rows( + adrs, + tibble::tribble( + ~USUBJID, ~AVISITN, ~AVALC, ~PARAMCD, + "1", 1, "Y", "CRSP" + ) + ) + + expect_dfs_equal( + base = expected, + compare = actual, + keys = c("USUBJID", "PARAMCD", "AVISITN") + ) +}) diff --git a/tests/testthat/test-derive_extreme_records.R b/tests/testthat/test-derive_extreme_records.R index 3e1dea4c83..8f2a7b801d 100644 --- a/tests/testthat/test-derive_extreme_records.R +++ b/tests/testthat/test-derive_extreme_records.R @@ -342,7 +342,7 @@ test_that("derive_extreme_records Test 6: warning if filter argument is used", { ) ) - expect_warning( + expect_error( derive_extreme_records( adrs, dataset_ref = adsl, @@ -358,7 +358,7 @@ test_that("derive_extreme_records Test 6: warning if filter argument is used", { ADT = ADT ) ), - class = "lifecycle_warning_deprecated" + class = "lifecycle_error_deprecated" ) }) @@ -376,3 +376,80 @@ test_that("derive_extreme_records Test 7: error if no input data", { fixed = TRUE ) }) + +## Test 8: keep vars in `keep_source_vars` in the new records ---- +test_that("derive_extreme_records Test 8: keep vars in `keep_source_vars` in the new records", { + input <- tibble::tribble( + ~USUBJID, ~AVISITN, ~AVAL, ~LBSEQ, + 1, 1, 12, 1, + 1, 3, 9, 2, + 2, 2, 42, 1, + 3, 3, 14, 1, + 3, 3, 10, 2 + ) + + expected_output <- bind_rows( + input, + tibble::tribble( + ~USUBJID, ~AVISITN, ~AVAL, ~LBSEQ, + 1, 3, 9, 2, + 2, 2, 42, 1, + 3, 3, 10, 2 + ) %>% + select(USUBJID, AVISITN, AVAL) %>% + mutate(DTYPE = "LOV") + ) + + actual_output <- derive_extreme_records( + input, + order = exprs(AVISITN, LBSEQ), + by_vars = exprs(USUBJID), + mode = "last", + keep_source_vars = exprs(AVISITN, AVAL), + set_values_to = exprs(DTYPE = "LOV") + ) + + expect_dfs_equal( + base = expected_output, + compare = actual_output, + keys = c("USUBJID", "AVISITN", "LBSEQ", "DTYPE") + ) +}) + +## Test 9: keep all vars in the new records when `keep_source_vars` is 'exprs(everything())' ---- +test_that("derive_extreme_records Test 9: keep all vars in the new records when `keep_source_vars` is 'exprs(everything())'", { # nolint + input <- tibble::tribble( + ~USUBJID, ~AVISITN, ~AVAL, ~LBSEQ, + 1, 1, 12, 1, + 1, 3, 9, 2, + 2, 2, 42, 1, + 3, 3, 14, 1, + 3, 3, 10, 2 + ) + + expected_output <- bind_rows( + input, + tibble::tribble( + ~USUBJID, ~AVISITN, ~AVAL, ~LBSEQ, + 1, 3, 9, 2, + 2, 2, 42, 1, + 3, 3, 10, 2 + ) %>% + mutate(DTYPE = "LOV") + ) + + actual_output <- derive_extreme_records( + input, + order = exprs(AVISITN, LBSEQ), + by_vars = exprs(USUBJID), + mode = "last", + keep_source_vars = exprs(everything()), + set_values_to = exprs(DTYPE = "LOV") + ) + + expect_dfs_equal( + base = expected_output, + compare = actual_output, + keys = c("USUBJID", "AVISITN", "LBSEQ", "DTYPE") + ) +}) diff --git a/tests/testthat/test-derive_joined.R b/tests/testthat/test-derive_joined.R index 8574f3b564..eeb1afcc23 100644 --- a/tests/testthat/test-derive_joined.R +++ b/tests/testthat/test-derive_joined.R @@ -242,3 +242,94 @@ test_that("derive_vars_joined Test 7: new_vars expressions using variables from keys = c("USUBJID", "AESEQ") ) }) + +## Test 8: error if new_vars are already in dataset ---- +test_that("derive_vars_joined Test 8: error if new_vars are already in dataset", { + myd <- data.frame(day = c(1, 2, 3), val = c(0, 17, 21)) + expect_error( + derive_vars_joined( + myd, + dataset_add = myd, + order = exprs(day), + mode = "last", + filter_join = day < day.join + ), + regexp = paste( + "The following columns in `dataset_add` have naming conflicts with `dataset`" + ) + ) +}) + +## Test 9: fixing a bug from issue 1966 ---- +test_that("derive_vars_joined Test 9: fixing a bug from issue 1966", { # nolint + adlb_ast <- tribble( + ~ADT, ~ASEQ, + "2002-01-01", 1, + "2002-02-02", 2, + "2002-02-02", 3 + ) %>% + mutate( + STUDYID = "ABC", + USUBJID = "1", + ADT = ymd(ADT), + ADTM = as_datetime(ADT) + ) + + adlb_tbili_pbl <- tribble( + ~ADT, ~ASEQ, + "2002-01-01", 4, + "2002-02-02", 5, + "2002-02-02", 6 + ) %>% + mutate( + STUDYID = "ABC", + USUBJID = "1", + ADT = ymd(ADT), + ADTM = as_datetime(ADT) + ) + + adlb_joined <- derive_vars_joined( + adlb_ast, + dataset_add = adlb_tbili_pbl, + by_vars = exprs(STUDYID, USUBJID), + order = exprs(ADTM, ASEQ), + new_vars = exprs(TBILI_ADT = ADT), + filter_join = ADT <= ADT.join, + mode = "first" + ) + + expected <- adlb_ast %>% + mutate(TBILI_ADT = as.Date(c("2002-01-01", "2002-02-02", "2002-02-02"), "%Y-%m-%d")) + + expect_dfs_equal( + base = expected, + compare = adlb_joined, + keys = c("ADT", "ASEQ", "STUDYID", "USUBJID", "ADTM", "TBILI_ADT") + ) +}) + +## Test 10: order vars are selected properly in function body ---- +test_that("derive_vars_joined Test 10: order vars are selected properly in function body", { + myd <- data.frame(day = c(1, 2, 3), val = c(0, 17, 21)) + actual <- derive_vars_joined( + myd, + dataset_add = myd, + new_vars = exprs(first_val = val), + join_vars = exprs(day), + order = exprs(-day), + mode = "last", + filter_join = day < day.join + ) + expected <- tribble( + ~day, ~val, ~first_val, + 1, 0, 17, + 2, 17, 21, + 3, 21, NA + ) + + expect_dfs_equal( + base = expected, + compare = actual, + keys = c("day", "val", "first_val") + ) +}) diff --git a/tests/testthat/test-derive_locf_records.R b/tests/testthat/test-derive_locf_records.R index 61c9a103a6..9443e970c8 100644 --- a/tests/testthat/test-derive_locf_records.R +++ b/tests/testthat/test-derive_locf_records.R @@ -32,7 +32,7 @@ test_that("derive_locf_records Test 1: visits are missing", { actual_output <- derive_locf_records( input, - dataset_expected_obs = advs_expected_obsv, + dataset_ref = advs_expected_obsv, by_vars = exprs(STUDYID, USUBJID, PARAM, PARAMCD), order = exprs(AVISITN, AVISIT) ) @@ -82,7 +82,7 @@ test_that("derive_locf_records Test 2: some visits have missing AVAL", { actual_output <- derive_locf_records( input, - dataset_expected_obs = advs_expected_obsv, + dataset_ref = advs_expected_obsv, by_vars = exprs(STUDYID, USUBJID, PARAM, PARAMCD), order = exprs(AVISITN, AVISIT) ) @@ -142,7 +142,7 @@ test_that("derive_locf_records Test 3: visits are missing - and DTYPE already ex actual_output <- derive_locf_records( input, - dataset_expected_obs = advs_expected_obsv, + dataset_ref = advs_expected_obsv, by_vars = exprs(STUDYID, USUBJID, PARAM, PARAMCD), order = exprs(AVISITN, AVISIT) ) @@ -190,7 +190,7 @@ test_that("derive_locf_records Test 4: visit variables are parameter independent actual_output <- derive_locf_records( input, - dataset_expected_obs = advs_expected_obsv, + dataset_ref = advs_expected_obsv, by_vars = exprs(STUDYID, USUBJID, PARAM, PARAMCD), order = exprs(AVISITN, AVISIT) ) @@ -246,7 +246,7 @@ test_that("derive_locf_records Test 5: visit variables are parameter dependent", actual_output <- derive_locf_records( input, - dataset_expected_obs = advs_expected_obsv, + dataset_ref = advs_expected_obsv, by_vars = exprs(STUDYID, USUBJID, PARAM, PARAMCD), order = exprs(AVISITN, AVISIT) ) @@ -290,7 +290,7 @@ test_that("derive_locf_records Test 6: populate VISITNUM for LOCF records", { actual_output <- derive_locf_records( input, - dataset_expected_obs = advs_expected_obsv, + dataset_ref = advs_expected_obsv, by_vars = exprs(STUDYID, USUBJID, PARAM, PARAMCD), analysis_var = AVALC, order = exprs(AVISITN, AVISIT), diff --git a/tests/testthat/test-derive_merged.R b/tests/testthat/test-derive_merged.R index bddabe58f4..ef069a52c8 100644 --- a/tests/testthat/test-derive_merged.R +++ b/tests/testthat/test-derive_merged.R @@ -256,35 +256,13 @@ test_that("derive_vars_merged Test 10: error if variables in missing_values but # derive_var_merged_cat ---- -## Test 11: deprecation warning ---- -test_that("derive_var_merged_cat Test 11: deprecation warning", { +## Test 11: deprecation error ---- +test_that("derive_var_merged_cat Test 11: deprecation error", { get_vscat <- function(x) { if_else(x == "BASELINE", "BASELINE", "POST-BASELINE") } - expect_warning( - derive_var_merged_cat( - adsl, - dataset_add = advs, - by_vars = exprs(USUBJID), - new_var = LSTVSCAT, - source_var = AVISIT, - cat_fun = get_vscat, - order = exprs(AVISIT), - mode = "last", - missing_value = "MISSING" - ), - class = "lifecycle_warning_deprecated" - ) -}) - -## Test 12: define value for non-matched by groups ---- -test_that("derive_var_merged_cat Test 12: define value for non-matched by groups", { - get_vscat <- function(x) { - if_else(x == "BASELINE", "BASELINE", "POST-BASELINE") - } - - actual <- suppress_warning( + expect_error( derive_var_merged_cat( adsl, dataset_add = advs, @@ -296,60 +274,14 @@ test_that("derive_var_merged_cat Test 12: define value for non-matched by groups mode = "last", missing_value = "MISSING" ), - regexpr = "was deprecated" - ) - - expected <- - mutate(adsl, - LSTVSCAT = c("POST-BASELINE", "BASELINE", "POST-BASELINE", "MISSING") - ) - - expect_dfs_equal( - base = expected, - compare = actual, - keys = c("USUBJID") + class = "lifecycle_error_deprecated" ) }) -## Test 13: by_vars with rename ---- -test_that("derive_var_merged_cat Test 13: by_vars with rename", { - get_region <- function(x) { - if_else(x %in% c("AUT", "NOR"), "EUROPE", "AFRICA") - } - - actual <- suppress_warning( - derive_var_merged_cat( - advs, - dataset_add = adsl1, - by_vars = exprs(USUBJID = ID), - new_var = REGION, - source_var = COUNTRY, - cat_fun = get_region, - filter_add = SEX == "M" - ), - regexpr = "was deprecated" - ) - - adsl_1 <- adsl1 %>% filter(SEX == "M") - expected <- left_join(advs, select(adsl_1, ID, COUNTRY), by = c("USUBJID" = "ID")) %>% - mutate(REGION = get_region(COUNTRY)) %>% - mutate(REGION = case_when( - !is.na(COUNTRY) ~ REGION, - TRUE ~ NA_character_ - )) %>% - select(-COUNTRY) - - - expect_dfs_equal( - base = expected, - compare = actual, - keys = c("USUBJID", "AVISIT") - ) -}) # derive_var_merged_exist_flag ---- -## Test 14: merge existence flag ---- -test_that("derive_var_merged_exist_flag Test 14: merge existence flag", { +## Test 12: merge existence flag ---- +test_that("derive_var_merged_exist_flag Test 12: merge existence flag", { actual <- derive_var_merged_exist_flag( adsl, dataset_add = advs, @@ -369,8 +301,8 @@ test_that("derive_var_merged_exist_flag Test 14: merge existence flag", { ) }) -## Test 15: by_vars with rename ---- -test_that("derive_var_merged_exist_flag Test 15: by_vars with rename", { +## Test 13: by_vars with rename ---- +test_that("derive_var_merged_exist_flag Test 13: by_vars with rename", { actual <- derive_var_merged_exist_flag( adsl, dataset_add = advs1, @@ -392,106 +324,9 @@ test_that("derive_var_merged_exist_flag Test 15: by_vars with rename", { # derive_var_merged_character ---- -## Test 16: deprecation warning ---- -test_that("derive_var_merged_character Test 16: deprecation warning", { - expect_warning( - derive_var_merged_character( - adsl, - dataset_add = advs, - by_vars = exprs(USUBJID), - order = exprs(AVISIT), - new_var = LASTVIS, - source_var = AVISIT, - mode = "last" - ), - class = "lifecycle_warning_deprecated" - ) -}) - -## Test 17: no transformation ---- -test_that("derive_var_merged_character Test 17: no transformation", { - actual <- suppress_warning( - derive_var_merged_character( - adsl, - dataset_add = advs, - by_vars = exprs(USUBJID), - order = exprs(AVISIT), - new_var = LASTVIS, - source_var = AVISIT, - mode = "last" - ), - regexpr = "was deprecated" - ) - - expected <- - mutate(adsl, LASTVIS = c("Week 2", "BASELINE", "Week 4", NA_character_)) - - - expect_dfs_equal( - base = expected, - compare = actual, - keys = "USUBJID" - ) -}) - -## Test 18: upper case ---- -test_that("derive_var_merged_character Test 18: upper case", { - actual <- suppress_warning( - derive_var_merged_character( - adsl, - dataset_add = advs, - by_vars = exprs(USUBJID), - order = exprs(AVISIT), - new_var = LASTVIS, - source_var = AVISIT, - mode = "last", - case = "upper", - missing_value = "UNKNOWN" - ), - regexpr = "was deprecated" - ) - - expected <- - mutate(adsl, LASTVIS = c("WEEK 2", "BASELINE", "WEEK 4", "UNKNOWN")) - - - expect_dfs_equal( - base = expected, - compare = actual, - keys = "USUBJID" - ) -}) - -## Test 19: lower case ---- -test_that("derive_var_merged_character Test 19: lower case", { - actual <- suppress_warning( - derive_var_merged_character( - adsl, - dataset_add = advs, - by_vars = exprs(USUBJID), - order = exprs(AVISIT), - new_var = LASTVIS, - source_var = AVISIT, - mode = "last", - case = "lower" - ), - regexpr = "was deprecated" - ) - - expected <- - mutate(adsl, LASTVIS = c("week 2", "baseline", "week 4", NA_character_)) - - - expect_dfs_equal( - base = expected, - compare = actual, - keys = "USUBJID" - ) -}) - -## Test 20: title case ---- -test_that("derive_var_merged_character Test 20: title case", { - actual <- suppress_warning( +## Test 14: deprecation error ---- +test_that("derive_var_merged_character Test 14: deprecation error", { + expect_error( derive_var_merged_character( adsl, dataset_add = advs, @@ -499,53 +334,16 @@ test_that("derive_var_merged_character Test 20: title case", { order = exprs(AVISIT), new_var = LASTVIS, source_var = AVISIT, - mode = "last", - case = "title" - ), - regexpr = "was deprecated" - ) - - expected <- - mutate(adsl, LASTVIS = c("Week 2", "Baseline", "Week 4", NA_character_)) - - - expect_dfs_equal( - base = expected, - compare = actual, - keys = "USUBJID" - ) -}) - -## Test 21: by_vars with rename ---- -test_that("derive_var_merged_character Test 21: by_vars with rename", { - actual <- suppress_warning( - derive_var_merged_character( - adsl, - dataset_add = advs1, - by_vars = exprs(USUBJID = ID), - order = exprs(AVISIT), - new_var = LASTVIS, - source_var = AVISIT, mode = "last" ), - regexpr = "was deprecated" - ) - - expected <- - mutate(adsl, LASTVIS = c("Week 2", "BASELINE", "Week 4", NA_character_)) - - - expect_dfs_equal( - base = expected, - compare = actual, - keys = "USUBJID" + class = "lifecycle_error_deprecated" ) }) # derive_vars_merged_lookup ---- -## Test 22: merge lookup table ---- -test_that("derive_vars_merged_lookup Test 22: merge lookup table", { +## Test 15: merge lookup table ---- +test_that("derive_vars_merged_lookup Test 15: merge lookup table", { param_lookup <- tibble::tribble( ~VSTESTCD, ~VSTEST, ~PARAMCD, ~DESCRIPTION, "WEIGHT", "Weight", "WEIGHT", "Weight (kg)", @@ -582,8 +380,8 @@ test_that("derive_vars_merged_lookup Test 22: merge lookup table", { ## the lookup table -## Test 23: all by_vars have records in the lookup table ---- -test_that("derive_vars_merged_lookup Test 23: all by_vars have records in the lookup table", { +## Test 16: all by_vars have records in the lookup table ---- +test_that("derive_vars_merged_lookup Test 16: all by_vars have records in the lookup table", { param_lookup <- tibble::tribble( ~VSTESTCD, ~VSTEST, ~PARAMCD, ~DESCRIPTION, "WEIGHT", "Weight", "WEIGHT", "Weight (kg)", @@ -618,8 +416,8 @@ test_that("derive_vars_merged_lookup Test 23: all by_vars have records in the l ) }) -## Test 24: by_vars with rename ---- -test_that("derive_vars_merged_lookup Test 24: by_vars with rename", { +## Test 17: by_vars with rename ---- +test_that("derive_vars_merged_lookup Test 17: by_vars with rename", { param_lookup <- tibble::tribble( ~TESTCD, ~VSTEST, ~PARAMCD, ~DESCRIPTION, "WEIGHT", "Weight", "WEIGHT", "Weight (kg)", @@ -655,8 +453,8 @@ test_that("derive_vars_merged_lookup Test 24: by_vars with rename", { # get_not_mapped ---- -## Test 25: not all by_vars have records in the lookup table ---- -test_that("get_not_mapped Test 25: not all by_vars have records in the lookup table", { +## Test 18: not all by_vars have records in the lookup table ---- +test_that("get_not_mapped Test 18: not all by_vars have records in the lookup table", { param_lookup <- tibble::tribble( ~VSTESTCD, ~VSTEST, ~PARAMCD, ~DESCRIPTION, "WEIGHT", "Weight", "WEIGHT", "Weight (kg)", @@ -694,8 +492,8 @@ test_that("get_not_mapped Test 25: not all by_vars have records in the lookup ta }) # derive_var_merged_summary ---- -## Test 26: dataset == dataset_add, no filter ---- -test_that("derive_var_merged_summary Test 26: dataset == dataset_add, no filter", { +## Test 19: dataset == dataset_add, no filter ---- +test_that("derive_var_merged_summary Test 19: dataset == dataset_add, no filter", { expected <- tibble::tribble( ~AVISIT, ~ASEQ, ~AVAL, ~MEANVIS, "WEEK 1", 1, 10, 10, @@ -723,8 +521,8 @@ test_that("derive_var_merged_summary Test 26: dataset == dataset_add, no filter" ) }) -## Test 27: dataset != dataset_add, filter ---- -test_that("derive_var_merged_summary Test 27: dataset != dataset_add, filter", { +## Test 20: dataset != dataset_add, filter ---- +test_that("derive_var_merged_summary Test 20: dataset != dataset_add, filter", { expected <- tibble::tribble( ~USUBJID, ~MEANPBL, "1", 13.5, @@ -757,8 +555,8 @@ test_that("derive_var_merged_summary Test 27: dataset != dataset_add, filter", { ) }) -## Test 28: by_vars with rename ---- -test_that("derive_var_merged_summary Test 28: by_vars with rename", { +## Test 21: by_vars with rename ---- +test_that("derive_var_merged_summary Test 21: by_vars with rename", { expected <- tibble::tribble( ~AVISIT, ~ASEQ, ~AVAL, ~MEANVIS, "WEEK 1", 1, 10, 10, diff --git a/tests/testthat/test-derive_param_computed.R b/tests/testthat/test-derive_param_computed.R index e1d5ada537..3a56d901bb 100644 --- a/tests/testthat/test-derive_param_computed.R +++ b/tests/testthat/test-derive_param_computed.R @@ -14,7 +14,8 @@ test_that("derive_param_computed Test 1: new observations are derived correctly" ) new_obs <- - inner_join(input %>% filter(PARAMCD == "DIABP") %>% select(USUBJID, VISIT, AVAL), + inner_join( + input %>% filter(PARAMCD == "DIABP") %>% select(USUBJID, VISIT, AVAL), input %>% filter(PARAMCD == "SYSBP") %>% select(USUBJID, VISIT, AVAL), by = c("USUBJID", "VISIT"), suffix = c(".DIABP", ".SYSBP") @@ -33,8 +34,8 @@ test_that("derive_param_computed Test 1: new observations are derived correctly" input, parameters = exprs(SYSBP, DIABP), by_vars = exprs(USUBJID, VISIT), - analysis_value = (AVAL.SYSBP + 2 * AVAL.DIABP) / 3, set_values_to = exprs( + AVAL = (AVAL.SYSBP + 2 * AVAL.DIABP) / 3, PARAMCD = "MAP", PARAM = "Mean arterial pressure (mmHg)", AVALU = "mmHg" @@ -81,8 +82,8 @@ test_that("derive_param_computed Test 2: new observations with constant paramete by_vars = exprs(USUBJID, VISIT), constant_parameters = c("HEIGHT"), constant_by_vars = exprs(USUBJID), - analysis_value = AVAL.WEIGHT / (AVAL.HEIGHT / 100)^2, set_values_to = exprs( + AVAL = AVAL.WEIGHT / (AVAL.HEIGHT / 100)^2, PARAMCD = "BMI", PARAM = "Body Mass Index (kg/m2)", AVALU = "kg/m2" @@ -113,8 +114,8 @@ test_that("derive_param_computed Test 3: no new observations if filtered dataset filter = VISIT == "WEEK 24", parameters = c("SYSBP", "DIABP"), by_vars = exprs(USUBJID, VISIT), - analysis_value = (AVAL.SYSBP + 2 * AVAL.DIABP) / 3, set_values_to = exprs( + AVAL = (AVAL.SYSBP + 2 * AVAL.DIABP) / 3, PARAMCD = "MAP", PARAM = "Mean arterial pressure (mmHg)", AVALU = "mmHg" @@ -147,8 +148,8 @@ test_that("derive_param_computed Test 4: no new observations are added if a para filter = PARAMCD == "DIABP", parameters = exprs(SYSBP, DIABP), by_vars = exprs(USUBJID, VISIT), - analysis_value = (AVAL.SYSBP + 2 * AVAL.DIABP) / 3, set_values_to = exprs( + AVAL = (AVAL.SYSBP + 2 * AVAL.DIABP) / 3, PARAMCD = "MAP", PARAM = "Mean arterial pressure (mmHg)", AVALU = "mmHg" @@ -176,11 +177,13 @@ test_that("derive_param_computed Test 5: `dataset_add`, creating new parameters" ) adchsf <- tibble::tribble( - ~USUBJID, ~AVISIT, ~PARAMCD, ~QSORRES, ~QSSTRESN, ~AVAL, - "1", "WEEK 2", "CHSF12", NA, 1, 6, - "1", "WEEK 2", "CHSF14", NA, 1, 6, - "1", "WEEK 4", "CHSF12", NA, 2, 12, - "1", "WEEK 4", "CHSF14", NA, 1, 6 + ~USUBJID, ~AVISIT, ~PARAMCD, ~QSSTRESN, ~AVAL, + "1", "WEEK 2", "CHSF12", 1, 6, + "1", "WEEK 2", "CHSF14", 1, 6, + "1", "WEEK 4", "CHSF12", 2, 12, + "1", "WEEK 4", "CHSF14", 1, 6 + ) %>% mutate( + QSORRES = NA_character_ ) expected <- bind_rows( @@ -199,16 +202,18 @@ test_that("derive_param_computed Test 5: `dataset_add`, creating new parameters" dataset_add = qs, by_vars = exprs(USUBJID, AVISIT), parameters = exprs(CHSF12, CHSF13 = QSTESTCD %in% c("CHSF113", "CHSF213"), CHSF14), - analysis_value = case_when( - QSORRES.CHSF13 == "Not applicable" ~ 0, - QSORRES.CHSF13 == "Yes" ~ 38, - QSORRES.CHSF13 == "No" ~ if_else( - QSSTRESN.CHSF12 > QSSTRESN.CHSF14, - 25, - 0 - ) - ), - set_values_to = exprs(PARAMCD = "CHSF13") + set_values_to = exprs( + AVAL = case_when( + QSORRES.CHSF13 == "Not applicable" ~ 0, + QSORRES.CHSF13 == "Yes" ~ 38, + QSORRES.CHSF13 == "No" ~ if_else( + QSSTRESN.CHSF12 > QSSTRESN.CHSF14, + 25, + 0 + ) + ), + PARAMCD = "CHSF13" + ) ), keys = c("USUBJID", "PARAMCD", "AVISIT") ) @@ -242,16 +247,18 @@ test_that("derive_param_computed Test 6: no input dataset", { CHSF13 = QSTESTCD %in% c("CHSF113", "CHSF213"), CHSF14 = QSTESTCD == "CHSF114" ), - analysis_value = case_when( - QSORRES.CHSF13 == "Not applicable" ~ 0, - QSORRES.CHSF13 == "Yes" ~ 38, - QSORRES.CHSF13 == "No" ~ if_else( - QSSTRESN.CHSF12 > QSSTRESN.CHSF14, - 25, - 0 - ) - ), - set_values_to = exprs(PARAMCD = "CHSF13") + set_values_to = exprs( + AVAL = case_when( + QSORRES.CHSF13 == "Not applicable" ~ 0, + QSORRES.CHSF13 == "Yes" ~ 38, + QSORRES.CHSF13 == "No" ~ if_else( + QSSTRESN.CHSF12 > QSSTRESN.CHSF14, + 25, + 0 + ) + ), + PARAMCD = "CHSF13" + ) ), keys = c("USUBJID", "PARAMCD", "AVISIT") ) @@ -298,8 +305,8 @@ test_that("derive_param_computed Test 7: expression in constant_parameters", { by_vars = exprs(USUBJID, VISIT), constant_parameters = exprs("HEIGHT" = VSTESTCD == "HGHT"), constant_by_vars = exprs(USUBJID), - analysis_value = AVAL.WEIGHT / (VSSTRESN.HEIGHT / 100)^2, set_values_to = exprs( + AVAL = AVAL.WEIGHT / (VSSTRESN.HEIGHT / 100)^2, PARAMCD = "BMI", PARAM = "Body Mass Index (kg/m2)", AVALU = "kg/m2" @@ -329,8 +336,8 @@ test_that("derive_param_computed Test 8: no new observations if a constant param by_vars = exprs(USUBJID, VISIT), constant_parameters = c("HEIGHT"), constant_by_vars = exprs(USUBJID), - analysis_value = AVAL.WEIGHT / (AVAL.HEIGHT / 100)^2, set_values_to = exprs( + AVAL = AVAL.WEIGHT / (AVAL.HEIGHT / 100)^2, PARAMCD = "BMI", PARAM = "Body Mass Index (kg/m2)", AVALU = "kg/m2" @@ -354,9 +361,121 @@ test_that("derive_param_computed Test 8: no new observations if a constant param ) }) +## Test 9: compute multiple variables ---- +test_that("derive_param_computed Test 9: compute multiple variables, keep_nas", { + adlb_tbilialk <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~AVALC, ~ADTM, ~ADTF, + "1", "ALK2", "Y", "2021-05-13", NA_character_, + "1", "TBILI2", "Y", "2021-06-30", "D", + "2", "ALK2", "Y", "2021-12-31", "M", + "2", "TBILI2", "N", "2021-11-11", NA_character_, + "3", "ALK2", "N", "2021-04-03", NA_character_, + "3", "TBILI2", "N", "2021-04-04", NA_character_ + ) %>% + mutate(ADTM = lubridate::ymd(ADTM)) + + expected <- tibble::tribble( + ~USUBJID, ~AVALC, ~ADTM, ~ADTF, + "1", "Y", "2021-06-30", "D", + "2", "N", "2021-12-31", "M", + "3", "N", "2021-04-04", NA_character_ + ) %>% + mutate( + ADTM = lubridate::ymd(ADTM), + PARAMCD = "TB2AK2", + PARAM = "TBILI > 2 times ULN and ALKPH <= 2 times ULN" + ) + + actual <- derive_param_computed( + dataset_add = adlb_tbilialk, + by_vars = exprs(USUBJID), + parameters = c("ALK2", "TBILI2"), + set_values_to = exprs( + AVALC = if_else(AVALC.TBILI2 == "Y" & AVALC.ALK2 == "Y", "Y", "N"), + ADTM = pmax(ADTM.TBILI2, ADTM.ALK2), + ADTF = if_else(ADTM == ADTM.TBILI2, ADTF.TBILI2, ADTF.ALK2), + PARAMCD = "TB2AK2", + PARAM = "TBILI > 2 times ULN and ALKPH <= 2 times ULN" + ), + keep_nas = TRUE + ) + + expect_dfs_equal( + base = expected, + compare = actual, + keys = c("USUBJID") + ) +}) + +## Test 10: deprecation warning if analysis_value is used ---- +test_that("derive_param_computed Test 10: deprecation warning if analysis_value is used", { + input <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~AVALU, ~VISIT, + "01-701-1015", "DIABP", "Diastolic Blood Pressure (mmHg)", 51, "mmHg", "BASELINE", + "01-701-1015", "DIABP", "Diastolic Blood Pressure (mmHg)", 50, "mmHg", "WEEK 2", + "01-701-1015", "SYSBP", "Systolic Blood Pressure (mmHg)", 121, "mmHg", "BASELINE", + "01-701-1015", "SYSBP", "Systolic Blood Pressure (mmHg)", 121, "mmHg", "WEEK 2", + "01-701-1028", "DIABP", "Diastolic Blood Pressure (mmHg)", 79, "mmHg", "BASELINE", + "01-701-1028", "DIABP", "Diastolic Blood Pressure (mmHg)", 80, "mmHg", "WEEK 2", + "01-701-1028", "SYSBP", "Systolic Blood Pressure (mmHg)", 130, "mmHg", "BASELINE", + "01-701-1028", "SYSBP", "Systolic Blood Pressure (mmHg)", 132, "mmHg", "WEEK 2" + ) + + new_obs <- + inner_join( + input %>% filter(PARAMCD == "DIABP") %>% select(USUBJID, VISIT, AVAL), + input %>% filter(PARAMCD == "SYSBP") %>% select(USUBJID, VISIT, AVAL), + by = c("USUBJID", "VISIT"), + suffix = c(".DIABP", ".SYSBP") + ) %>% + mutate( + AVAL = (2 * AVAL.DIABP + AVAL.SYSBP) / 3, + PARAMCD = "MAP", + PARAM = "Mean arterial pressure (mmHg)", + AVALU = "mmHg" + ) %>% + select(-AVAL.DIABP, -AVAL.SYSBP) + expected_output <- bind_rows(input, new_obs) + + expect_warning( + derive_param_computed( + input, + parameters = exprs(SYSBP, DIABP), + by_vars = exprs(USUBJID, VISIT), + analysis_value = (AVAL.SYSBP + 2 * AVAL.DIABP) / 3, + set_values_to = exprs( + PARAMCD = "MAP", + PARAM = "Mean arterial pressure (mmHg)", + AVALU = "mmHg" + ) + ), + class = "lifecycle_warning_deprecated" + ) + + expect_dfs_equal( + suppress_warning( + derive_param_computed( + input, + parameters = exprs(SYSBP, DIABP), + by_vars = exprs(USUBJID, VISIT), + analysis_value = (AVAL.SYSBP + 2 * AVAL.DIABP) / 3, + set_values_to = exprs( + PARAMCD = "MAP", + PARAM = "Mean arterial pressure (mmHg)", + AVALU = "mmHg" + ) + ), + regexpr = "is deprecated" + ), + expected_output, + keys = c("USUBJID", "PARAMCD", "VISIT") + ) +}) + + # assert_parameters_argument ---- -## Test 9: error if argument is of wrong type ---- -test_that("assert_parameters_argument Test 9: error if argument is of wrong type", { +## Test 11: error if argument is of wrong type ---- +test_that("assert_parameters_argument Test 11: error if argument is of wrong type", { expect_error( assert_parameters_argument(myparameters <- c(1, 2, 3)), regexp = paste( @@ -368,8 +487,8 @@ test_that("assert_parameters_argument Test 9: error if argument is of wrong type }) # get_hori_data ---- -## Test 10: error if variables with more than one dot ---- -test_that("get_hori_data Test 10: error if variables with more than one dot", { +## Test 12: error if variables with more than one dot ---- +test_that("get_hori_data Test 12: error if variables with more than one dot", { input <- tibble::tribble( ~USUBJID, ~PARAMCD, ~PARAM, ~AVAL, ~AVALU, ~VISIT, "01-701-1015", "DIABP", "Diastolic Blood Pressure (mmHg)", 51, "mmHg", "BASELINE", @@ -387,11 +506,11 @@ test_that("get_hori_data Test 10: error if variables with more than one dot", { input, parameters = exprs(SYSBP, DIABP), by_vars = exprs(USUBJID, VISIT), - analysis_value = (AVAL.SYSBP + 2 * AVAL.DIA.BP) / 3, + set_values_to = exprs(AVAL = (AVAL.SYSBP + 2 * AVAL.DIA.BP) / 3), filter = NULL ), regexp = paste( - "The `analysis_value` argument contains variable names with more than on dot:", + "The `set_values_to` argument contains variable names with more than on dot:", "`AVAL.DIA.BP`", sep = "\n" ), diff --git a/tests/testthat/test-derive_param_exist_flag.R b/tests/testthat/test-derive_param_exist_flag.R index 0d35c71744..a67093ec6e 100644 --- a/tests/testthat/test-derive_param_exist_flag.R +++ b/tests/testthat/test-derive_param_exist_flag.R @@ -89,33 +89,39 @@ test_that("derive_param_exist_flag Test 3: error is issued if paramter already e -## derive_param_merge_exist_flag Test 4: warning for deprecated parameter ---- -test_that("derive_param_exist_flag Test 4: warning for deprecated param `dataset_adsl`", { - expect_warning(derive_param_exist_flag( - dataset_adsl = adsl, - dataset_add = adrs, - filter_add = PARAMCD == "OVR", - condition = AVALC == "PD", - false_value = "N", - set_values_to = exprs( - PARAMCD = "PD", - ANL01FL = "Y" - ) - )) +## derive_param_merge_exist_flag Test 4: error for deprecated parameter ---- +test_that("derive_param_exist_flag Test 4: error for deprecated param `dataset_adsl`", { + expect_error( + derive_param_exist_flag( + dataset_adsl = adsl, + dataset_add = adrs, + filter_add = PARAMCD == "OVR", + condition = AVALC == "PD", + false_value = "N", + set_values_to = exprs( + PARAMCD = "PD", + ANL01FL = "Y" + ) + ), + class = "lifecycle_error_deprecated" + ) }) -## derive_param_merge_exist_flag Test 5: warning for deprecated parameter ---- -test_that("derive_param_exist_flag Test 5: warning for deprecated param `subject_keys`", { - expect_warning(derive_param_exist_flag( - dataset_ref = adsl, - dataset_add = adrs, - subject_keys = get_admiral_option("subject_keys"), - filter_add = PARAMCD == "OVR", - condition = AVALC == "PD", - false_value = "N", - set_values_to = exprs( - PARAMCD = "PD", - ANL01FL = "Y" - ) - )) +## derive_param_merge_exist_flag Test 5: error for deprecated parameter ---- +test_that("derive_param_exist_flag Test 5: error for deprecated param `subject_keys`", { + expect_error( + derive_param_exist_flag( + dataset_ref = adsl, + dataset_add = adrs, + subject_keys = get_admiral_option("subject_keys"), + filter_add = PARAMCD == "OVR", + condition = AVALC == "PD", + false_value = "N", + set_values_to = exprs( + PARAMCD = "PD", + ANL01FL = "Y" + ) + ), + class = "lifecycle_error_deprecated" + ) }) diff --git a/tests/testthat/test-derive_param_extreme_event.R b/tests/testthat/test-derive_param_extreme_event.R index 1ad3ee80bc..c7bf98d854 100644 --- a/tests/testthat/test-derive_param_extreme_event.R +++ b/tests/testthat/test-derive_param_extreme_event.R @@ -30,9 +30,9 @@ adrs <- tibble::tribble( select(-ADTC) # derive_param_extreme_event ---- -## Test 1: deprecation warning if function is called ---- -test_that("derive_param_extreme_event Test 1: deprecation warning if function is called", { - expect_warning( +## Test 1: deprecation error if function is called ---- +test_that("derive_param_extreme_event Test 1: deprecation error if function is called", { + expect_error( derive_param_extreme_event( adrs, dataset_adsl = adsl, @@ -46,197 +46,6 @@ test_that("derive_param_extreme_event Test 1: deprecation warning if function is ADT = ADT ) ), - class = "lifecycle_warning_deprecated" - ) -}) - -## Test 2: derive first PD date ---- -test_that("derive_param_extreme_event Test 2: derive first PD date", { - actual <- suppress_warning( - derive_param_extreme_event( - adrs, - dataset_adsl = adsl, - dataset_source = adrs, - filter_source = PARAMCD == "OVR" & AVALC == "PD", - new_var = AVALC, - order = exprs(ADT), - set_values_to = exprs( - PARAMCD = "PD", - ANL01FL = "Y", - ADT = ADT - ) - ), - regexpr = "was deprecated" - ) - - expected <- bind_rows( - adrs, - tibble::tribble( - ~USUBJID, ~ADT, ~AVALC, - "1", ymd(""), "N", - "2", ymd("2021-07-16"), "Y", - "3", ymd(""), "N" - ) %>% - mutate( - STUDYID = "XX1234", - PARAMCD = "PD", - ANL01FL = "Y" - ) - ) - - expect_dfs_equal( - base = expected, - comp = actual, - keys = c("USUBJID", "PARAMCD", "ADT") - ) -}) - -## Test 3: derive death date parameter ---- -test_that("derive_param_extreme_event Test 3: derive death date parameter", { - actual <- suppress_warning( - derive_param_extreme_event( - dataset_adsl = adsl, - dataset_source = adsl, - filter_source = !is.na(DTHDT), - new_var = AVAL, - true_value = 1, - false_value = 0, - mode = "first", - set_values_to = exprs( - PARAMCD = "DEATH", - ANL01FL = "Y", - ADT = DTHDT - ) - ), - regexpr = "was deprecated" - ) - - expected <- tibble::tribble( - ~USUBJID, ~ADT, ~AVAL, ~DTHDT, - "1", ymd("2022-05-13"), 1, ymd("2022-05-13"), - "2", ymd(""), 0, ymd(""), - "3", ymd(""), 0, ymd("") - ) %>% - mutate( - STUDYID = "XX1234", - PARAMCD = "DEATH", - ANL01FL = "Y" - ) - - expect_dfs_equal( - base = expected, - comp = actual, - keys = c("USUBJID", "PARAMCD", "ADT") - ) -}) - -adrs <- tibble::tribble( - ~USUBJID, ~ADTC, ~AVALC, ~PARAMCD, - "1", "2020-01-02", "PR", "OVR", - "1", "2020-02-01", "CR", "OVR", - "1", "2020-03-01", "NE", "OVR", - "1", "2020-04-01", "SD", "OVR", - "2", "2021-06-15", "SD", "OVR", - "2", "2021-07-16", "SD", "OVR", - "2", "2021-09-14", "NE", "OVR", - "3", "2021-08-03", "NE", "OVR", - "1", "2020-01-02", "PR", "OVRF", - "1", "2020-02-01", "CR", "OVRF", - "1", "2020-03-01", "NE", "OVRF", - "1", "2020-04-01", "SD", "OVRF", - "2", "2021-06-15", "SD", "OVRF", - "2", "2021-07-16", "SD", "OVRF", - "2", "2021-09-14", "NE", "OVRF", - "3", "2021-08-03", "NE", "OVRF" -) %>% - mutate( - STUDYID = "XX1234", - ADT = ymd(ADTC) - ) %>% - select(-ADTC) - -## Test 4: latest evaluable tumor assessment date parameter ---- -test_that("derive_param_extreme_event Test 4: latest evaluable tumor assessment date parameter", { - actual <- suppress_warning( - derive_param_extreme_event( - dataset = adrs, - dataset_adsl = adsl, - dataset_source = adrs, - filter_source = PARAMCD == "OVR" & AVALC != "NE", - order = exprs(ADT), - new_var = AVALC, - true_value = "Y", - false_value = "N", - mode = "last", - set_values_to = exprs( - PARAMCD = "LSTEVLDT", - ANL01FL = "Y", - ADT = ADT - ) - ), - regexpr = "was deprecated" - ) - - expected <- bind_rows( - adrs, - tibble::tribble( - ~USUBJID, ~ADT, ~AVALC, - "1", ymd("2020-04-01"), "Y", - "2", ymd("2021-07-16"), "Y", - "3", ymd(""), "N" - ) %>% - mutate( - STUDYID = "XX1234", - PARAMCD = "LSTEVLDT", - ANL01FL = "Y" - ) - ) - - expect_dfs_equal( - base = expected, - comp = actual, - keys = c("USUBJID", "PARAMCD", "ADT") - ) -}) - -## Test 5: latest evaluable tumor assessment date parameter without overwriting existing result ---- -test_that("derive_param_extreme_event Test 5: latest evaluable tumor assessment date parameter without overwriting existing result", { # nolint - actual <- suppress_warning( - derive_param_extreme_event( - dataset = adrs, - dataset_adsl = adsl, - dataset_source = adrs, - filter_source = PARAMCD == "OVR" & AVALC != "NE", - order = exprs(ADT), - new_var = NULL, - mode = "last", - set_values_to = exprs( - PARAMCD = "LSTEVLDT", - ANL01FL = "Y", - ADT = ADT - ) - ), - regexpr = "was deprecated" - ) - - expected <- bind_rows( - adrs, - tibble::tribble( - ~USUBJID, ~ADT, ~AVALC, - "1", ymd("2020-04-01"), "SD", - "2", ymd("2021-07-16"), "SD", - "3", ymd(""), NA - ) %>% - mutate( - STUDYID = "XX1234", - PARAMCD = "LSTEVLDT", - ANL01FL = "Y" - ) - ) - - expect_dfs_equal( - base = expected, - comp = actual, - keys = c("USUBJID", "PARAMCD", "ADT") + class = "lifecycle_error_deprecated" ) }) diff --git a/tests/testthat/test-derive_var_atoxgr.R b/tests/testthat/test-derive_var_atoxgr.R index 7c876c96d9..c82e2b7bba 100644 --- a/tests/testthat/test-derive_var_atoxgr.R +++ b/tests/testthat/test-derive_var_atoxgr.R @@ -1,5 +1,5 @@ -# ---- derive_var_atoxgr, test 1: ATOXGR cannot be graded ---- -test_that("derive_var_atoxgr, test 1: ATOXGR cannot be graded", { +## Test 1: ATOXGR cannot be graded ---- +test_that("derive_var_atoxgr Test 1: ATOXGR cannot be graded", { exp_out_1 <- tibble::tribble( ~ATOXDSCL, ~ATOXDSCH, ~ATOXGRL, ~ATOXGRH, ~ATOXGR, NA_character_, NA_character_, NA_character_, NA_character_, NA_character_, @@ -25,8 +25,8 @@ test_that("derive_var_atoxgr, test 1: ATOXGR cannot be graded", { ) }) -# ---- derive_var_atoxgr, test 2: derive_var_atoxgr, ATOXGR = 0 (normal) ---- -test_that("derive_var_atoxgr, test 2: derive_var_atoxgr, ATOXGR = 0 (normal)", { +## Test 2: ATOXGR = 0 (normal) ---- +test_that("derive_var_atoxgr Test 2: ATOXGR = 0 (normal)", { exp_out_2 <- tibble::tribble( ~ATOXDSCL, ~ATOXDSCH, ~ATOXGRL, ~ATOXGRH, ~ATOXGR, "Hypoglycemia", "Hyperglycemia", "0", "0", "0", @@ -47,8 +47,8 @@ test_that("derive_var_atoxgr, test 2: derive_var_atoxgr, ATOXGR = 0 (normal)", { ) }) -# ---- derive_var_atoxgr, test 3: ATOXGR > 0 (HYPER) ---- -test_that("derive_var_atoxgr, test 3: ATOXGR > 0 (HYPER)", { +## Test 3: ATOXGR > 0 (HYPER) ---- +test_that("derive_var_atoxgr Test 3: ATOXGR > 0 (HYPER)", { exp_out_3 <- tibble::tribble( ~ATOXDSCL, ~ATOXDSCH, ~ATOXGRL, ~ATOXGRH, ~ATOXGR, "Hypoglycemia", "Hyperglycemia", NA_character_, "1", "1", @@ -69,8 +69,8 @@ test_that("derive_var_atoxgr, test 3: ATOXGR > 0 (HYPER)", { ) }) -# ---- derive_var_atoxgr, test 4: ATOXGR < 0 (HYPO) ---- -test_that("derive_var_atoxgr, test 4: ATOXGR < 0 (HYPO)", { +## Test 4: ATOXGR < 0 (HYPO) ---- +test_that("derive_var_atoxgr Test 4: ATOXGR < 0 (HYPO)", { exp_out_4 <- tibble::tribble( ~ATOXDSCL, ~ATOXDSCH, ~ATOXGRL, ~ATOXGRH, ~ATOXGR, "Hypoglycemia", "Hyperglycemia", "3", NA_character_, "-3", @@ -131,8 +131,8 @@ expected_anemia <- tibble::tribble( input_anemia <- expected_anemia %>% select(-ATOXGRL) -# ---- derive_var_atoxgr, test 5: CTCAEv4 Anemia ---- -test_that("derive_var_atoxgr, test 5: CTCAEv4 Anemia", { +## Test 5: CTCAEv4 Anemia ---- +test_that("derive_var_atoxgr Test 5: CTCAEv4 Anemia", { actual_anemia_ctcv4 <- derive_var_atoxgr_dir( input_anemia, new_var = ATOXGRL, @@ -149,8 +149,8 @@ test_that("derive_var_atoxgr, test 5: CTCAEv4 Anemia", { ) }) -# ---- derive_var_atoxgr, test 6: CTCAEv5 Anemia ---- -test_that("derive_var_atoxgr, test 6: CTCAEv5 Anemia", { +## Test 6: CTCAEv5 Anemia ---- +test_that("derive_var_atoxgr Test 6: CTCAEv5 Anemia", { actual_anemia_ctcv5 <- derive_var_atoxgr_dir( input_anemia, new_var = ATOXGRL, @@ -190,8 +190,8 @@ input_leukocytosis <- expected_leukocytosis %>% select(-ATOXGRH) -# ---- derive_var_atoxgr, test 7: CTCAEv4 Leukocytosis ---- -test_that("derive_var_atoxgr, test 7: CTCAEv4 Leukocytosis", { +## Test 7: CTCAEv4 Leukocytosis ---- +test_that("derive_var_atoxgr Test 7: CTCAEv4 Leukocytosis", { actual_leukocytosis <- derive_var_atoxgr_dir( input_leukocytosis, new_var = ATOXGRH, @@ -208,8 +208,8 @@ test_that("derive_var_atoxgr, test 7: CTCAEv4 Leukocytosis", { ) }) -# ---- derive_var_atoxgr, test 8: CTCAEv5 Leukocytosis ---- -test_that("derive_var_atoxgr, test 8: CTCAEv5 Leukocytosis", { +## Test 8: CTCAEv5 Leukocytosis ---- +test_that("derive_var_atoxgr Test 8: CTCAEv5 Leukocytosis", { actual_leukocytosis <- derive_var_atoxgr_dir( input_leukocytosis, new_var = ATOXGRH, @@ -252,8 +252,8 @@ expected_aptt <- tibble::tribble( input_aptt <- expected_aptt %>% select(-ATOXGRH) -# ---- derive_var_atoxgr, test 9: CTCAEv4 Activated partial thromboplastin time prolonged ---- -test_that("derive_var_atoxgr, test 9: CTCAEv4 Activated partial thromboplastin time prolonged", { +## Test 9: CTCAEv4 Activated partial thromboplastin time prolonged ---- +test_that("derive_var_atoxgr Test 9: CTCAEv4 Activated partial thromboplastin time prolonged", { actual_aptt <- derive_var_atoxgr_dir( input_aptt, new_var = ATOXGRH, @@ -270,8 +270,8 @@ test_that("derive_var_atoxgr, test 9: CTCAEv4 Activated partial thromboplastin t ) }) -# ---- derive_var_atoxgr, test 10: CTCAEv5 Activated partial thromboplastin time prolonged ---- -test_that("derive_var_atoxgr, test 10: CTCAEv5 Activated partial thromboplastin time prolonged", { +## Test 10: CTCAEv5 Activated partial thromboplastin time prolonged ---- +test_that("derive_var_atoxgr Test 10: CTCAEv5 Activated partial thromboplastin time prolonged", { actual_aptt <- derive_var_atoxgr_dir( input_aptt, new_var = ATOXGRH, @@ -314,8 +314,8 @@ expected_alt_ctcv4 <- tibble::tribble( "Alanine aminotransferase Increased", NA, 40, NA_character_, NA, ) -# ---- derive_var_atoxgr, test 11: CTCAEv4 Alanine aminotransferase increased ---- -test_that("derive_var_atoxgr, test 11: CTCAEv4 Alanine aminotransferase increased", { +## Test 11: CTCAEv4 Alanine aminotransferase increased ---- +test_that("derive_var_atoxgr Test 11: CTCAEv4 Alanine aminotransferase increased", { input_alt <- expected_alt_ctcv4 %>% select(-ATOXGRH) @@ -342,8 +342,8 @@ test_that("derive_var_atoxgr, test 11: CTCAEv4 Alanine aminotransferase increase ### Grade 2: >3.0 - 5.0 x ULN if BL was normal OR >3.0 - 5.0 x BL if BL was abnormal ### Grade 1: >ULN - 3.0 x ULN if BL was normal OR >1.5 - 3.0 x BL if BL was abnormal -# ---- derive_var_atoxgr, test 12: CTCAEv5 Alanine aminotransferase increased ---- -test_that("derive_var_atoxgr, test 12: CTCAEv5 Alanine aminotransferase increased", { +## Test 12: CTCAEv5 Alanine aminotransferase increased ---- +test_that("derive_var_atoxgr Test 12: CTCAEv5 Alanine aminotransferase increased", { # V5 and V4 criteria identical when BASELINE normal expected_alt_ctcv5_norm <- expected_alt_ctcv4 %>% # set BASE to be normal and create FLAG @@ -426,8 +426,8 @@ expected_alkph_ctcv4 <- tibble::tribble( ) -# ---- derive_var_atoxgr, test 13: CTCAEv4 Alkaline phosphatase increased ---- -test_that("derive_var_atoxgr, test 13: CTCAEv4 Alkaline phosphatase increased", { +## Test 13: CTCAEv4 Alkaline phosphatase increased ---- +test_that("derive_var_atoxgr Test 13: CTCAEv4 Alkaline phosphatase increased", { input_alkph <- expected_alkph_ctcv4 %>% select(-ATOXGRH) @@ -454,8 +454,8 @@ test_that("derive_var_atoxgr, test 13: CTCAEv4 Alkaline phosphatase increased", ### Grade 2: >2.5 - 5.0 x ULN if BL was normal OR >2.5 - 5.0 x BL if BL was abnormal ### Grade 1: >ULN - 2.5 x ULN if BL was normal OR >2.0 - 2.5 x BL if BL was abnormal -# ---- derive_var_atoxgr, test 14: CTCAEv5 Alkaline phosphatase increased ---- -test_that("derive_var_atoxgr, test 14: CTCAEv5 Alkaline phosphatase increased", { +## Test 14: CTCAEv5 Alkaline phosphatase increased ---- +test_that("derive_var_atoxgr Test 14: CTCAEv5 Alkaline phosphatase increased", { # V5 and V4 criteria identical when BASELINE normal expected_alkph_ctcv5_norm <- expected_alkph_ctcv4 %>% # set BASE to be normal and create FLAG @@ -538,8 +538,8 @@ expected_ast_ctcv4 <- tibble::tribble( "Aspartate aminotransferase Increased", NA, 40, NA_character_, NA, ) -# ---- derive_var_atoxgr, test 15: CTCAEv4 Aspartate aminotransferase increased ---- -test_that("derive_var_atoxgr, test 15: CTCAEv4 Aspartate aminotransferase increased", { +## Test 15: CTCAEv4 Aspartate aminotransferase increased ---- +test_that("derive_var_atoxgr Test 15: CTCAEv4 Aspartate aminotransferase increased", { input_ast <- expected_ast_ctcv4 %>% select(-ATOXGRH) @@ -565,8 +565,8 @@ test_that("derive_var_atoxgr, test 15: CTCAEv4 Aspartate aminotransferase increa ### Grade 2: >3.0 - 5.0 x ULN if BL was normal OR >3.0 - 5.0 x BL if BL was abnormal ### Grade 1: >ULN - 3.0 x ULN if BL was normal OR >1.5 - 3.0 x BL if BL was abnormal -# ---- derive_var_atoxgr, test 16: CTCAEv5 Aspartate aminotransferase increased ---- -test_that("derive_var_atoxgr, test 16: CTCAEv5 Aspartate aminotransferase increased", { +## Test 16: CTCAEv5 Aspartate aminotransferase increased ---- +test_that("derive_var_atoxgr Test 16: CTCAEv5 Aspartate aminotransferase increased", { # V5 and V4 criteria identical when BASELINE normal expected_ast_ctcv5_norm <- expected_ast_ctcv4 %>% # set BASE to be normal and create FLAG @@ -652,8 +652,8 @@ expected_bili_ctcv4 <- tibble::tribble( "Blood bilirubin increased", NA, 40, NA_character_, NA, ) -# ---- derive_var_atoxgr, test 17: CTCAEv4 Blood bilirubin increased ---- -test_that("derive_var_atoxgr, test 17: CTCAEv4 Blood bilirubin increased", { +## Test 17: CTCAEv4 Blood bilirubin increased ---- +test_that("derive_var_atoxgr Test 17: CTCAEv4 Blood bilirubin increased", { input_bili <- expected_bili_ctcv4 %>% select(-ATOXGRH) @@ -680,8 +680,8 @@ test_that("derive_var_atoxgr, test 17: CTCAEv4 Blood bilirubin increased", { ### Grade 2: >1.5 - 3.0 x ULN if BL was normal OR >1.5 - 3.0 x BL ### Grade 1: >ULN - 1.5 x ULN if BL was normal OR >1.0 - 1.5 x BL -# ---- derive_var_atoxgr, test 18: CTCAEv5 Blood bilirubin increased ---- -test_that("derive_var_atoxgr, test 18: CTCAEv5 Blood bilirubin increased", { +## Test 18: CTCAEv5 Blood bilirubin increased ---- +test_that("derive_var_atoxgr Test 18: CTCAEv5 Blood bilirubin increased", { # V5 and V4 criteria identical when BASELINE normal expected_bili_ctcv5_norm <- expected_bili_ctcv4 %>% # set BASE to be normal and create FLAG @@ -761,8 +761,8 @@ expected_cd4 <- tibble::tribble( input_cd4 <- expected_cd4 %>% select(-ATOXGRL) -# ---- derive_var_atoxgr, test 19: CTCAEv4 CD4 Lymphocytes decreased ---- -test_that("derive_var_atoxgr, test 19: CTCAEv4 CD4 Lymphocytes decreased", { +## Test 19: CTCAEv4 CD4 Lymphocytes decreased ---- +test_that("derive_var_atoxgr Test 19: CTCAEv4 CD4 Lymphocytes decreased", { actual_cd4 <- derive_var_atoxgr_dir( input_cd4, new_var = ATOXGRL, @@ -779,8 +779,8 @@ test_that("derive_var_atoxgr, test 19: CTCAEv4 CD4 Lymphocytes decreased", { ) }) -# ---- derive_var_atoxgr, test 20: CTCAEv5 CD4 Lymphocytes decreased ---- -test_that("derive_var_atoxgr, test 20: CTCAEv5 CD4 Lymphocytes decreased", { +## Test 20: CTCAEv5 CD4 Lymphocytes decreased ---- +test_that("derive_var_atoxgr Test 20: CTCAEv5 CD4 Lymphocytes decreased", { actual_cd4 <- derive_var_atoxgr_dir( input_cd4, new_var = ATOXGRL, @@ -836,8 +836,8 @@ expected_choles <- tibble::tribble( input_choles <- expected_choles %>% select(-ATOXGRH) -# ---- derive_var_atoxgr, test 21: CTCAEv4 Cholesterol high ---- -test_that("derive_var_atoxgr, test 21: CTCAEv4 Cholesterol high", { +## Test 21: CTCAEv4 Cholesterol high ---- +test_that("derive_var_atoxgr Test 21: CTCAEv4 Cholesterol high", { actual_choles <- derive_var_atoxgr_dir( input_choles, new_var = ATOXGRH, @@ -854,8 +854,8 @@ test_that("derive_var_atoxgr, test 21: CTCAEv4 Cholesterol high", { ) }) -# ---- derive_var_atoxgr, test 22: CTCAEv5 Cholesterol high ---- -test_that("derive_var_atoxgr, test 22: CTCAEv5 Cholesterol high", { +## Test 22: CTCAEv5 Cholesterol high ---- +test_that("derive_var_atoxgr Test 22: CTCAEv5 Cholesterol high", { actual_choles <- derive_var_atoxgr_dir( input_choles, new_var = ATOXGRH, @@ -899,8 +899,8 @@ expected_cpk <- tibble::tribble( input_cpk <- expected_cpk %>% select(-ATOXGRH) -# ---- derive_var_atoxgr, test 23: CTCAEv4 CPK increased ---- -test_that("derive_var_atoxgr, test 23: CTCAEv4 CPK increased", { +## Test 23: CTCAEv4 CPK increased ---- +test_that("derive_var_atoxgr Test 23: CTCAEv4 CPK increased", { actual_cpk <- derive_var_atoxgr_dir( input_cpk, new_var = ATOXGRH, @@ -917,8 +917,8 @@ test_that("derive_var_atoxgr, test 23: CTCAEv4 CPK increased", { ) }) -# ---- derive_var_atoxgr, test 24: CTCAEv5 CPK increased ---- -test_that("derive_var_atoxgr, test 24: CTCAEv5 CPK increased", { +## Test 24: CTCAEv5 CPK increased ---- +test_that("derive_var_atoxgr Test 24: CTCAEv5 CPK increased", { actual_cpk <- derive_var_atoxgr_dir( input_cpk, new_var = ATOXGRH, @@ -972,8 +972,8 @@ expected_creatn <- tibble::tribble( "Creatinine increased", NA, 0, 40, NA_character_, NA, "Y", "Y", ) -# ---- derive_var_atoxgr, test 25: CTCAEv4 Creatinine increased ---- -test_that("derive_var_atoxgr, test 25: CTCAEv4 Creatinine increased", { +## Test 25: CTCAEv4 Creatinine increased ---- +test_that("derive_var_atoxgr Test 25: CTCAEv4 Creatinine increased", { input_creatn <- expected_creatn %>% select(-ATOXGRH) @@ -1000,8 +1000,8 @@ test_that("derive_var_atoxgr, test 25: CTCAEv4 Creatinine increased", { ### Grade 2: >1.5 - 3.0 x baseline; >1.5 - 3.0 x ULN ### Grade 1: >ULN - 1.5 x ULN -# ---- derive_var_atoxgr, test 26: CTCAEv4 Creatinine increased ---- -test_that("derive_var_atoxgr, test 26: CTCAEv4 Creatinine increased", { +## Test 26: CTCAEv4 Creatinine increased ---- +test_that("derive_var_atoxgr Test 26: CTCAEv4 Creatinine increased", { expected_creatn <- expected_creatn %>% filter(V5 == "Y") @@ -1030,8 +1030,8 @@ test_that("derive_var_atoxgr, test 26: CTCAEv4 Creatinine increased", { ### Grade 2: <0.75 - 0.5 x LLN or 25 - <50% decrease from baseline ### Grade 1: <1.0 - 0.75 x LLN or <25% decrease from baseline -# ---- derive_var_atoxgr, test 27: CTCAEv4 Fibrinogen decreased ---- -test_that("derive_var_atoxgr, test 27: CTCAEv4 Fibrinogen decreased", { +## Test 27: CTCAEv4 Fibrinogen decreased ---- +test_that("derive_var_atoxgr Test 27: CTCAEv4 Fibrinogen decreased", { expected_fib <- tibble::tribble( ~ATOXDSCL, ~AVAL, ~ANRLO, ~PCHG, ~AVALU, ~ATOXGRL, "Not a term", 9, 10, 40, "g/L", NA, @@ -1110,8 +1110,8 @@ test_that("derive_var_atoxgr, test 27: CTCAEv4 Fibrinogen decreased", { ### Grade 2: <0.75 - 0.5 x LLN OR if abnormal, 25 - <50% dec. from BL ### Grade 1: <1.0 - 0.75 x LLN OR if abnormal, <25% dec. from BL -# ---- derive_var_atoxgr, test 28: CTCAEv5 Fibrinogen decreased ---- -test_that("derive_var_atoxgr, test 28: CTCAEv5 Fibrinogen decreased", { +## Test 28: CTCAEv5 Fibrinogen decreased ---- +test_that("derive_var_atoxgr Test 28: CTCAEv5 Fibrinogen decreased", { expected_fib <- tibble::tribble( ~ATOXDSCL, ~AVAL, ~ANRLO, ~PCHG, ~AVALU, ~ATOXGRL, "Not a term", 9, 10, 40, "g/L", NA, @@ -1209,8 +1209,8 @@ expected_ggt_ctcv4 <- tibble::tribble( "GGT increased", NA, 0, NA, NA_character_, NA, ) -# ---- derive_var_atoxgr, test 29: CTCAEv4 GGT increased ---- -test_that("derive_var_atoxgr, test 29: CTCAEv4 GGT increased", { +## Test 29: CTCAEv4 GGT increased ---- +test_that("derive_var_atoxgr Test 29: CTCAEv4 GGT increased", { input_ggt <- expected_ggt_ctcv4 %>% select(-ATOXGRH) @@ -1237,8 +1237,8 @@ test_that("derive_var_atoxgr, test 29: CTCAEv4 GGT increased", { ### Grade 2: >2.5 - 5.0 x ULN if BL was normal OR >2.5 - 5.0 x BL if BL was abnormal ### Grade 1: >ULN - 2.5 x ULN if BL was normal OR >2.0 - 2.5 x BL if BL was abnormal -# ---- derive_var_atoxgr, test 30: CTCAEv5 GGT increased ---- -test_that("derive_var_atoxgr, test 30: CTCAEv5 GGT increased", { +## Test 30: CTCAEv5 GGT increased ---- +test_that("derive_var_atoxgr Test 30: CTCAEv5 GGT increased", { # V5 and V4 criteria identical when BASELINE normal expected_ggt_ctcv5_norm <- expected_ggt_ctcv4 %>% # set BASE to be normal and create FLAG @@ -1315,8 +1315,8 @@ expected_hapt <- tibble::tribble( input_hapt <- expected_hapt %>% select(-ATOXGRL) -# ---- derive_var_atoxgr, test 31: CTCAEv4 Haptoglobin decreased ---- -test_that("derive_var_atoxgr, test 31: CTCAEv4 Haptoglobin decreased", { +## Test 31: CTCAEv4 Haptoglobin decreased ---- +test_that("derive_var_atoxgr Test 31: CTCAEv4 Haptoglobin decreased", { actual_hapt <- derive_var_atoxgr_dir( input_hapt, new_var = ATOXGRL, @@ -1333,8 +1333,8 @@ test_that("derive_var_atoxgr, test 31: CTCAEv4 Haptoglobin decreased", { ) }) -# ---- derive_var_atoxgr, test 32: CTCAEv5 Haptoglobin decreased ---- -test_that("derive_var_atoxgr, test 32: CTCAEv5 Haptoglobin decreased", { +## Test 32: CTCAEv5 Haptoglobin decreased ---- +test_that("derive_var_atoxgr Test 32: CTCAEv5 Haptoglobin decreased", { actual_hapt <- derive_var_atoxgr_dir( input_hapt, new_var = ATOXGRL, @@ -1393,8 +1393,8 @@ expected_hgbi <- tibble::tribble( "Hemoglobin increased", NA, 60, 65, "g/L", NA, 26, "Y", ) -# ---- derive_var_atoxgr, test 33: CTCAEv4 Hemoglobin increased ---- -test_that("derive_var_atoxgr, test 33: CTCAEv4 Hemoglobin increased", { +## Test 33: CTCAEv4 Hemoglobin increased ---- +test_that("derive_var_atoxgr Test 33: CTCAEv4 Hemoglobin increased", { input_hgbi <- expected_hgbi %>% select(-ATOXGRH) @@ -1414,8 +1414,8 @@ test_that("derive_var_atoxgr, test 33: CTCAEv4 Hemoglobin increased", { ) }) -# ---- derive_var_atoxgr, test 34: CTCAEv5 Hemoglobin increased ---- -test_that("derive_var_atoxgr, test 34: CTCAEv5 Hemoglobin increased", { +## Test 34: CTCAEv5 Hemoglobin increased ---- +test_that("derive_var_atoxgr Test 34: CTCAEv5 Hemoglobin increased", { expected_hgbi <- expected_hgbi %>% filter(V5 == "Y") @@ -1444,8 +1444,8 @@ test_that("derive_var_atoxgr, test 34: CTCAEv5 Hemoglobin increased", { ### Grade 2: >1.5 - 2.5 x ULN; >1.5 - 2.5 times above baseline if on anticoagulation ### Grade 1: >1 - 1.5 x ULN; >1 - 1.5 times above baseline if on anticoagulation -# ---- derive_var_atoxgr, test 35: CTCAEv4 INR increased ---- -test_that("derive_var_atoxgr, test 35: CTCAEv4 INR increased", { +## Test 35: CTCAEv4 INR increased ---- +test_that("derive_var_atoxgr Test 35: CTCAEv4 INR increased", { expected_inri <- tibble::tribble( ~ATOXDSCH, ~AVAL, ~BASE, ~ANRHI, ~AVALU, ~ATOXGRH, ~TESTNUM, "Not a term", 80, 120, 200, NA_character_, NA, 1, @@ -1496,8 +1496,8 @@ test_that("derive_var_atoxgr, test 35: CTCAEv4 INR increased", { ### Grade 2: >1.5 - 2.5 x ULN; >1.5 - 2.5 times above baseline if on anticoagulation ### Grade 1: >1.2 - 1.5 x ULN; >1 - 1.5 times above baseline if on anticoagulation -# ---- derive_var_atoxgr, test 36: CTCAEv5 INR increased ---- -test_that("derive_var_atoxgr, test 36: CTCAEv5 INR increased", { +## Test 36: CTCAEv5 INR increased ---- +test_that("derive_var_atoxgr Test 36: CTCAEv5 INR increased", { expected_inri <- tibble::tribble( ~ATOXDSCH, ~AVAL, ~BASE, ~ANRHI, ~AVALU, ~ATOXGRH, ~TESTNUM, "Not a term", 80, 120, 200, NA_character_, NA, 1, @@ -1569,8 +1569,8 @@ expected_lip <- tibble::tribble( input_lip <- expected_lip %>% select(-ATOXGRH) -# ---- derive_var_atoxgr, test 37: CTCAEv4 Lipase increased ---- -test_that("derive_var_atoxgr, test 37: CTCAEv4 Lipase increased", { +## Test 37: CTCAEv4 Lipase increased ---- +test_that("derive_var_atoxgr Test 37: CTCAEv4 Lipase increased", { actual_lip <- derive_var_atoxgr_dir( input_lip, new_var = ATOXGRH, @@ -1587,8 +1587,8 @@ test_that("derive_var_atoxgr, test 37: CTCAEv4 Lipase increased", { ) }) -# ---- derive_var_atoxgr, test 38: CTCAEv5 Lipase increased ---- -test_that("derive_var_atoxgr, test 38: CTCAEv5 Lipase increased", { +## Test 38: CTCAEv5 Lipase increased ---- +test_that("derive_var_atoxgr Test 38: CTCAEv5 Lipase increased", { actual_lip <- derive_var_atoxgr_dir( input_lip, new_var = ATOXGRH, @@ -1644,8 +1644,8 @@ expected_lymd <- tibble::tribble( input_lymd <- expected_lymd %>% select(-ATOXGRL) -# ---- derive_var_atoxgr, test 39: CTCAEv4 Lymphocyte count decreased ---- -test_that("derive_var_atoxgr, test 39: CTCAEv4 Lymphocyte count decreased", { +## Test 39: CTCAEv4 Lymphocyte count decreased ---- +test_that("derive_var_atoxgr Test 39: CTCAEv4 Lymphocyte count decreased", { actual_lymd <- derive_var_atoxgr_dir( input_lymd, new_var = ATOXGRL, @@ -1662,8 +1662,8 @@ test_that("derive_var_atoxgr, test 39: CTCAEv4 Lymphocyte count decreased", { ) }) -# ---- derive_var_atoxgr, test 40: CTCAEv5 Lymphocyte count decreased ---- -test_that("derive_var_atoxgr, test 40: CTCAEv5 Lymphocyte count decreased", { +## Test 40: CTCAEv5 Lymphocyte count decreased ---- +test_that("derive_var_atoxgr Test 40: CTCAEv5 Lymphocyte count decreased", { actual_lymd <- derive_var_atoxgr_dir( input_lymd, new_var = ATOXGRL, @@ -1701,8 +1701,8 @@ expected_lymi <- tibble::tribble( input_lymi <- expected_lymi %>% select(-ATOXGRH) -# ---- derive_var_atoxgr, test 41: CTCAEv4 Lymphocyte count increased ---- -test_that("derive_var_atoxgr, test 41: CTCAEv4 Lymphocyte count increased", { +## Test 41: CTCAEv4 Lymphocyte count increased ---- +test_that("derive_var_atoxgr Test 41: CTCAEv4 Lymphocyte count increased", { actual_lymi <- derive_var_atoxgr_dir( input_lymi, new_var = ATOXGRH, @@ -1719,8 +1719,8 @@ test_that("derive_var_atoxgr, test 41: CTCAEv4 Lymphocyte count increased", { ) }) -# ---- derive_var_atoxgr, test 42: CTCAEv5 Lymphocyte count increased ---- -test_that("derive_var_atoxgr, test 42: CTCAEv5 Lymphocyte count increased", { +## Test 42: CTCAEv5 Lymphocyte count increased ---- +test_that("derive_var_atoxgr Test 42: CTCAEv5 Lymphocyte count increased", { actual_lymi <- derive_var_atoxgr_dir( input_lymi, new_var = ATOXGRH, @@ -1776,8 +1776,8 @@ input_neut <- expected_neut %>% select(-ATOXGRL) -# ---- derive_var_atoxgr, test 43: CTCAEv4 Neutrophil count decreased ---- -test_that("derive_var_atoxgr, test 43: CTCAEv4 Neutrophil count decreased", { +## Test 43: CTCAEv4 Neutrophil count decreased ---- +test_that("derive_var_atoxgr Test 43: CTCAEv4 Neutrophil count decreased", { actual_neut <- derive_var_atoxgr_dir( input_neut, new_var = ATOXGRL, @@ -1794,8 +1794,8 @@ test_that("derive_var_atoxgr, test 43: CTCAEv4 Neutrophil count decreased", { ) }) -# ---- derive_var_atoxgr, test 44: CTCAEv5 Neutrophil count decreased ---- -test_that("derive_var_atoxgr, test 44: CTCAEv5 Neutrophil count decreased", { +## Test 44: CTCAEv5 Neutrophil count decreased ---- +test_that("derive_var_atoxgr Test 44: CTCAEv5 Neutrophil count decreased", { actual_neut <- derive_var_atoxgr_dir( input_neut, new_var = ATOXGRL, @@ -1850,8 +1850,8 @@ expected_plate <- tibble::tribble( input_plate <- expected_plate %>% select(-ATOXGRL) -# ---- derive_var_atoxgr, test 45: CTCAEv4 Platelet count decreased ---- -test_that("derive_var_atoxgr, test 45: CTCAEv4 Platelet count decreased", { +## Test 45: CTCAEv4 Platelet count decreased ---- +test_that("derive_var_atoxgr Test 45: CTCAEv4 Platelet count decreased", { actual_plate <- derive_var_atoxgr_dir( input_plate, new_var = ATOXGRL, @@ -1868,8 +1868,8 @@ test_that("derive_var_atoxgr, test 45: CTCAEv4 Platelet count decreased", { ) }) -# ---- derive_var_atoxgr, test 46: CTCAEv5 Platelet count decreased ---- -test_that("derive_var_atoxgr, test 46: CTCAEv5 Platelet count decreased", { +## Test 46: CTCAEv5 Platelet count decreased ---- +test_that("derive_var_atoxgr Test 46: CTCAEv5 Platelet count decreased", { actual_plate <- derive_var_atoxgr_dir( input_plate, new_var = ATOXGRL, @@ -1913,8 +1913,8 @@ expected_seri <- tibble::tribble( input_seri <- expected_seri %>% select(-ATOXGRH) -# ---- derive_var_atoxgr, test 47: CTCAEv4 Serum amylase increased ---- -test_that("derive_var_atoxgr, test 47: CTCAEv4 Serum amylase increased", { +## Test 47: CTCAEv4 Serum amylase increased ---- +test_that("derive_var_atoxgr Test 47: CTCAEv4 Serum amylase increased", { actual_seri <- derive_var_atoxgr_dir( input_seri, new_var = ATOXGRH, @@ -1931,8 +1931,8 @@ test_that("derive_var_atoxgr, test 47: CTCAEv4 Serum amylase increased", { ) }) -# ---- derive_var_atoxgr, test 48: CTCAEv5 Serum amylase increased ---- -test_that("derive_var_atoxgr, test 48: CTCAEv5 Serum amylase increased", { +## Test 48: CTCAEv5 Serum amylase increased ---- +test_that("derive_var_atoxgr Test 48: CTCAEv5 Serum amylase increased", { actual_seri <- derive_var_atoxgr_dir( input_seri, new_var = ATOXGRH, @@ -1987,8 +1987,8 @@ expected_wbcd <- tibble::tribble( input_wbcd <- expected_wbcd %>% select(-ATOXGRL) -# ---- derive_var_atoxgr, test 49: CTCAEv4 White blood cell decreased ---- -test_that("derive_var_atoxgr, test 49: CTCAEv4 White blood cell decreased", { +## Test 49: CTCAEv4 White blood cell decreased ---- +test_that("derive_var_atoxgr Test 49: CTCAEv4 White blood cell decreased", { actual_wbcd <- derive_var_atoxgr_dir( input_wbcd, new_var = ATOXGRL, @@ -2005,8 +2005,8 @@ test_that("derive_var_atoxgr, test 49: CTCAEv4 White blood cell decreased", { ) }) -# ---- derive_var_atoxgr, test 50: CTCAEv5 White blood cell decreased ---- -test_that("derive_var_atoxgr, test 50: CTCAEv5 White blood cell decreased", { +## Test 50: CTCAEv5 White blood cell decreased ---- +test_that("derive_var_atoxgr Test 50: CTCAEv5 White blood cell decreased", { actual_wbcd <- derive_var_atoxgr_dir( input_wbcd, new_var = ATOXGRL, @@ -2064,8 +2064,8 @@ expected_calci <- tibble::tribble( input_calci <- expected_calci %>% select(-ATOXGRH) -# ---- derive_var_atoxgr, test 51: CTCAEv4 Hypercalcemia ---- -test_that("derive_var_atoxgr, test 51: CTCAEv4 Hypercalcemia", { +## Test 51: CTCAEv4 Hypercalcemia ---- +test_that("derive_var_atoxgr Test 51: CTCAEv4 Hypercalcemia", { actual_calci <- derive_var_atoxgr_dir( input_calci, new_var = ATOXGRH, @@ -2082,8 +2082,8 @@ test_that("derive_var_atoxgr, test 51: CTCAEv4 Hypercalcemia", { ) }) -# ---- derive_var_atoxgr, test 52: CTCAEv5 Hypercalcemia ---- -test_that("derive_var_atoxgr, test 52: CTCAEv5 Hypercalcemia", { +## Test 52: CTCAEv5 Hypercalcemia ---- +test_that("derive_var_atoxgr Test 52: CTCAEv5 Hypercalcemia", { actual_calci <- derive_var_atoxgr_dir( input_calci, new_var = ATOXGRH, @@ -2139,8 +2139,8 @@ input_calioni <- expected_calioni %>% select(-ATOXGRH) -# ---- derive_var_atoxgr, test 53: CTCAEv4 Hypercalcemia (Ionized) ---- -test_that("derive_var_atoxgr, test 53: CTCAEv4 Hypercalcemia (Ionized)", { +## Test 53: CTCAEv4 Hypercalcemia (Ionized) ---- +test_that("derive_var_atoxgr Test 53: CTCAEv4 Hypercalcemia (Ionized)", { actual_calioni <- derive_var_atoxgr_dir( input_calioni, new_var = ATOXGRH, @@ -2157,8 +2157,8 @@ test_that("derive_var_atoxgr, test 53: CTCAEv4 Hypercalcemia (Ionized)", { ) }) -# ---- derive_var_atoxgr, test 54: CTCAEv5 Hypercalcemia (Ionized) ---- -test_that("derive_var_atoxgr, test 54: CTCAEv5 Hypercalcemia (Ionized)", { +## Test 54: CTCAEv5 Hypercalcemia (Ionized) ---- +test_that("derive_var_atoxgr Test 54: CTCAEv5 Hypercalcemia (Ionized)", { actual_calioni <- derive_var_atoxgr_dir( input_calioni, new_var = ATOXGRH, @@ -2182,8 +2182,8 @@ test_that("derive_var_atoxgr, test 54: CTCAEv5 Hypercalcemia (Ionized)", { ### Grade 2: >8.9 - 13.9 mmol/L ### Grade 1: >ULN - 8.9 mmol/L -# ---- derive_var_atoxgr, test 55: CTCAEv4 Hyperglycemia (Fasting) ---- -test_that("derive_var_atoxgr, test 55: CTCAEv4 Hyperglycemia (Fasting)", { +## Test 55: CTCAEv4 Hyperglycemia (Fasting) ---- +test_that("derive_var_atoxgr Test 55: CTCAEv4 Hyperglycemia (Fasting)", { expected_glycfi <- tibble::tribble( ~ATOXDSCH, ~AVAL, ~ANRLO, ~ANRHI, ~AVALU, ~ATOXGRH, ~TESTNUM, "Not a term", 27.9, 0, 5.3, "mmol/L", NA, 1, @@ -2236,8 +2236,8 @@ test_that("derive_var_atoxgr, test 55: CTCAEv4 Hyperglycemia (Fasting)", { ### Grade 4: >27.8 mmol/L ### Grade 3: >13.9 - 27.8 mmol/L -# ---- derive_var_atoxgr, test 56: CTCAEv4 Hyperglycemia ---- -test_that("derive_var_atoxgr, test 56: CTCAEv4 Hyperglycemia", { +## Test 56: CTCAEv4 Hyperglycemia ---- +test_that("derive_var_atoxgr Test 56: CTCAEv4 Hyperglycemia", { expected_glyci <- tibble::tribble( ~ATOXDSCH, ~AVAL, ~ANRLO, ~ANRHI, ~AVALU, ~ATOXGRH, ~TESTNUM, "Not a term", 27.9, 0, 5.3, "mmol/L", NA, 1, @@ -2309,8 +2309,8 @@ expected_kalei <- tibble::tribble( input_kalei <- expected_kalei %>% select(-ATOXGRH) -# ---- derive_var_atoxgr, test 57: CTCAEv4 Hyperkalemia ---- -test_that("derive_var_atoxgr, test 57: CTCAEv4 Hyperkalemia", { +## Test 57: CTCAEv4 Hyperkalemia ---- +test_that("derive_var_atoxgr Test 57: CTCAEv4 Hyperkalemia", { actual_kalei <- derive_var_atoxgr_dir( input_kalei, new_var = ATOXGRH, @@ -2327,8 +2327,8 @@ test_that("derive_var_atoxgr, test 57: CTCAEv4 Hyperkalemia", { ) }) -# ---- derive_var_atoxgr, test 58: CTCAEv5 Hyperkalemia ---- -test_that("derive_var_atoxgr, test 58: CTCAEv5 Hyperkalemia", { +## Test 58: CTCAEv5 Hyperkalemia ---- +test_that("derive_var_atoxgr Test 58: CTCAEv5 Hyperkalemia", { actual_kalei <- derive_var_atoxgr_dir( input_kalei, new_var = ATOXGRH, @@ -2379,8 +2379,8 @@ input_magni <- expected_magni %>% select(-ATOXGRH) -# ---- derive_var_atoxgr, test 59: CTCAEv4 Hypermagnesemia ---- -test_that("derive_var_atoxgr, test 59: CTCAEv4 Hypermagnesemia", { +## Test 59: CTCAEv4 Hypermagnesemia ---- +test_that("derive_var_atoxgr Test 59: CTCAEv4 Hypermagnesemia", { actual_magni <- derive_var_atoxgr_dir( input_magni, new_var = ATOXGRH, @@ -2397,8 +2397,8 @@ test_that("derive_var_atoxgr, test 59: CTCAEv4 Hypermagnesemia", { ) }) -# ---- derive_var_atoxgr, test 60: CTCAEv5 Hypermagnesemia ---- -test_that("derive_var_atoxgr, test 60: CTCAEv5 Hypermagnesemia", { +## Test 60: CTCAEv5 Hypermagnesemia ---- +test_that("derive_var_atoxgr Test 60: CTCAEv5 Hypermagnesemia", { actual_magni <- derive_var_atoxgr_dir( input_magni, new_var = ATOXGRH, @@ -2453,8 +2453,8 @@ expected_natri <- tibble::tribble( input_natri <- expected_natri %>% select(-ATOXGRH) -# ---- derive_var_atoxgr, test 61: CTCAEv4 Hypernatremia ---- -test_that("derive_var_atoxgr, test 61: CTCAEv4 Hypernatremia", { +## Test 61: CTCAEv4 Hypernatremia ---- +test_that("derive_var_atoxgr Test 61: CTCAEv4 Hypernatremia", { actual_natri <- derive_var_atoxgr_dir( input_natri, new_var = ATOXGRH, @@ -2471,8 +2471,8 @@ test_that("derive_var_atoxgr, test 61: CTCAEv4 Hypernatremia", { ) }) -# ---- derive_var_atoxgr, test 62: CTCAEv5 Hypernatremia ---- -test_that("derive_var_atoxgr, test 62: CTCAEv5 Hypernatremia", { +## Test 62: CTCAEv5 Hypernatremia ---- +test_that("derive_var_atoxgr Test 62: CTCAEv5 Hypernatremia", { actual_natri <- derive_var_atoxgr_dir( input_natri, new_var = ATOXGRH, @@ -2516,8 +2516,8 @@ expected_trigi <- tibble::tribble( input_trigi <- expected_trigi %>% select(-ATOXGRH) -# ---- derive_var_atoxgr, test 63: CTCAEv4 Hypertriglyceridemia ---- -test_that("derive_var_atoxgr, test 63: CTCAEv4 Hypertriglyceridemia", { +## Test 63: CTCAEv4 Hypertriglyceridemia ---- +test_that("derive_var_atoxgr Test 63: CTCAEv4 Hypertriglyceridemia", { actual_trigi <- derive_var_atoxgr_dir( input_trigi, new_var = ATOXGRH, @@ -2534,8 +2534,8 @@ test_that("derive_var_atoxgr, test 63: CTCAEv4 Hypertriglyceridemia", { ) }) -# ---- derive_var_atoxgr, test 64: CTCAEv5 Hypertriglyceridemia ---- -test_that("derive_var_atoxgr, test 64: CTCAEv5 Hypertriglyceridemia", { +## Test 64: CTCAEv5 Hypertriglyceridemia ---- +test_that("derive_var_atoxgr Test 64: CTCAEv5 Hypertriglyceridemia", { actual_trigi <- derive_var_atoxgr_dir( input_trigi, new_var = ATOXGRH, @@ -2584,8 +2584,8 @@ input_urici <- expected_urici %>% ### NCICTCAEv5 only has grade 3 ### Grade 3: >ULN -# ---- derive_var_atoxgr, test 65: CTCAEv5 Hyperuricemia ---- -test_that("derive_var_atoxgr, test 65: CTCAEv5 Hyperuricemia", { +## Test 65: CTCAEv5 Hyperuricemia ---- +test_that("derive_var_atoxgr Test 65: CTCAEv5 Hyperuricemia", { expected_urici <- expected_urici %>% filter(is.na(ATOXGRH) | ATOXGRH != "4") input_urici <- expected_urici %>% @@ -2607,9 +2607,9 @@ test_that("derive_var_atoxgr, test 65: CTCAEv5 Hyperuricemia", { ) }) -# ---- derive_var_atoxgr, test 66: CTCAEv4 Hyperuricemia ---- # If unit missing then grade CANNOT be calculated as needed for grade 4 -test_that("derive_var_atoxgr, test 66: CTCAEv4 Hyperuricemia", { +## Test 66: CTCAEv4 Hyperuricemia ---- +test_that("derive_var_atoxgr Test 66: CTCAEv4 Hyperuricemia", { expected_urici <- expected_urici %>% mutate(ATOXGRH = if_else(is.na(AVALU), NA_character_, ATOXGRH)) @@ -2666,8 +2666,8 @@ expected_albd <- tibble::tribble( input_albd <- expected_albd %>% select(-ATOXGRL) -# ---- derive_var_atoxgr, test 67: CTCAEv4 Hypoalbuminemia ---- -test_that("derive_var_atoxgr, test 67: CTCAEv4 Hypoalbuminemia", { +## Test 67: CTCAEv4 Hypoalbuminemia ---- +test_that("derive_var_atoxgr Test 67: CTCAEv4 Hypoalbuminemia", { actual_albd <- derive_var_atoxgr_dir( input_albd, new_var = ATOXGRL, @@ -2684,8 +2684,8 @@ test_that("derive_var_atoxgr, test 67: CTCAEv4 Hypoalbuminemia", { ) }) -# ---- derive_var_atoxgr, test 68: CTCAEv5 Hypoalbuminemia ---- -test_that("derive_var_atoxgr, test 68: CTCAEv5 Hypoalbuminemia", { +## Test 68: CTCAEv5 Hypoalbuminemia ---- +test_that("derive_var_atoxgr Test 68: CTCAEv5 Hypoalbuminemia", { actual_albd <- derive_var_atoxgr_dir( input_albd, new_var = ATOXGRL, @@ -2740,8 +2740,8 @@ expected_calcd <- tibble::tribble( input_calcd <- expected_calcd %>% select(-ATOXGRL) -# ---- derive_var_atoxgr, test 69: CTCAEv4 Hypocalcemia ---- -test_that("derive_var_atoxgr, test 69: CTCAEv4 Hypocalcemia", { +## Test 69: CTCAEv4 Hypocalcemia ---- +test_that("derive_var_atoxgr Test 69: CTCAEv4 Hypocalcemia", { actual_calcd <- derive_var_atoxgr_dir( input_calcd, new_var = ATOXGRL, @@ -2758,8 +2758,8 @@ test_that("derive_var_atoxgr, test 69: CTCAEv4 Hypocalcemia", { ) }) -# ---- derive_var_atoxgr, test 70: CTCAEv5 Hypocalcemia ---- -test_that("derive_var_atoxgr, test 70: CTCAEv5 Hypocalcemia", { +## Test 70: CTCAEv5 Hypocalcemia ---- +test_that("derive_var_atoxgr Test 70: CTCAEv5 Hypocalcemia", { actual_calcd <- derive_var_atoxgr_dir( input_calcd, new_var = ATOXGRL, @@ -2814,8 +2814,8 @@ expected_caliond <- tibble::tribble( input_caliond <- expected_caliond %>% select(-ATOXGRL) -# ---- derive_var_atoxgr, test 71: CTCAEv4 Hypocalcemia (Ionized) ---- -test_that("derive_var_atoxgr, test 71: CTCAEv4 Hypocalcemia (Ionized)", { +## Test 71: CTCAEv4 Hypocalcemia (Ionized) ---- +test_that("derive_var_atoxgr Test 71: CTCAEv4 Hypocalcemia (Ionized)", { actual_caliond <- derive_var_atoxgr_dir( input_caliond, new_var = ATOXGRL, @@ -2832,8 +2832,8 @@ test_that("derive_var_atoxgr, test 71: CTCAEv4 Hypocalcemia (Ionized)", { ) }) -# ---- derive_var_atoxgr, test 72: CTCAEv5 Hypocalcemia (Ionized) ---- -test_that("derive_var_atoxgr, test 72: CTCAEv5 Hypocalcemia (Ionized)", { +## Test 72: CTCAEv5 Hypocalcemia (Ionized) ---- +test_that("derive_var_atoxgr Test 72: CTCAEv5 Hypocalcemia (Ionized)", { actual_caliond <- derive_var_atoxgr_dir( input_caliond, new_var = ATOXGRL, @@ -2888,8 +2888,8 @@ expected_glycd <- tibble::tribble( input_glycd <- expected_glycd %>% select(-ATOXGRL) -# ---- derive_var_atoxgr, test 73: CTCAEv4 Hypoglycemia ---- -test_that("derive_var_atoxgr, test 73: CTCAEv4 Hypoglycemia", { +## Test 73: CTCAEv4 Hypoglycemia ---- +test_that("derive_var_atoxgr Test 73: CTCAEv4 Hypoglycemia", { actual_glycd <- derive_var_atoxgr_dir( input_glycd, new_var = ATOXGRL, @@ -2906,8 +2906,8 @@ test_that("derive_var_atoxgr, test 73: CTCAEv4 Hypoglycemia", { ) }) -# ---- derive_var_atoxgr, test 74: CTCAEv5 Hypoglycemia ---- -test_that("derive_var_atoxgr, test 74: CTCAEv5 Hypoglycemia", { +## Test 74: CTCAEv5 Hypoglycemia ---- +test_that("derive_var_atoxgr Test 74: CTCAEv5 Hypoglycemia", { actual_glycd <- derive_var_atoxgr_dir( input_glycd, new_var = ATOXGRL, @@ -2957,8 +2957,8 @@ expected_kaled <- tibble::tribble( input_kaled <- expected_kaled %>% select(-ATOXGRL) -# ---- derive_var_atoxgr, test 75: CTCAEv4 Hypokalemia ---- -test_that("derive_var_atoxgr, test 75: CTCAEv4 Hypokalemia", { +## Test 75: CTCAEv4 Hypokalemia ---- +test_that("derive_var_atoxgr Test 75: CTCAEv4 Hypokalemia", { actual_kaled <- derive_var_atoxgr_dir( input_kaled, new_var = ATOXGRL, @@ -2975,8 +2975,8 @@ test_that("derive_var_atoxgr, test 75: CTCAEv4 Hypokalemia", { ) }) -# ---- derive_var_atoxgr, test 76: CTCAEv5 Hypokalemia ---- -test_that("derive_var_atoxgr, test 76: CTCAEv5 Hypokalemia", { +## Test 76: CTCAEv5 Hypokalemia ---- +test_that("derive_var_atoxgr Test 76: CTCAEv5 Hypokalemia", { actual_kaled <- derive_var_atoxgr_dir( input_kaled, new_var = ATOXGRL, @@ -3031,8 +3031,8 @@ expected_magnd <- tibble::tribble( input_magnd <- expected_magnd %>% select(-ATOXGRL) -# ---- derive_var_atoxgr, test 77: CTCAEv4 Hypomagnesemia ---- -test_that("derive_var_atoxgr, test 77: CTCAEv4 Hypomagnesemia", { +## Test 77: CTCAEv4 Hypomagnesemia ---- +test_that("derive_var_atoxgr Test 77: CTCAEv4 Hypomagnesemia", { actual_magnd <- derive_var_atoxgr_dir( input_magnd, new_var = ATOXGRL, @@ -3049,8 +3049,8 @@ test_that("derive_var_atoxgr, test 77: CTCAEv4 Hypomagnesemia", { ) }) -# ---- derive_var_atoxgr, test 78: CTCAEv5 Hypomagnesemia ---- -test_that("derive_var_atoxgr, test 78: CTCAEv5 Hypomagnesemia", { +## Test 78: CTCAEv5 Hypomagnesemia ---- +test_that("derive_var_atoxgr Test 78: CTCAEv5 Hypomagnesemia", { actual_magnd <- derive_var_atoxgr_dir( input_magnd, new_var = ATOXGRL, @@ -3100,8 +3100,8 @@ expected_natrd <- tibble::tribble( input_natrd <- expected_natrd %>% select(-ATOXGRL) -# ---- derive_var_atoxgr, test 79: CTCAEv4 Hyponatremia ---- -test_that("derive_var_atoxgr, test 79: CTCAEv4 Hyponatremia", { +## Test 79: CTCAEv4 Hyponatremia ---- +test_that("derive_var_atoxgr Test 79: CTCAEv4 Hyponatremia", { actual_natrd <- derive_var_atoxgr_dir( input_natrd, new_var = ATOXGRL, @@ -3118,8 +3118,8 @@ test_that("derive_var_atoxgr, test 79: CTCAEv4 Hyponatremia", { ) }) -# ---- derive_var_atoxgr, test 80: CTCAEv5 Hyponatremia ---- -test_that("derive_var_atoxgr, test 80: CTCAEv5 Hyponatremia", { +## Test 80: CTCAEv5 Hyponatremia ---- +test_that("derive_var_atoxgr Test 80: CTCAEv5 Hyponatremia", { actual_natrd <- derive_var_atoxgr_dir( input_natrd, new_var = ATOXGRL, @@ -3143,8 +3143,8 @@ test_that("derive_var_atoxgr, test 80: CTCAEv5 Hyponatremia", { ### Grade 2: <0.8 - 0.6 mmol/L ### Grade 1: % + mutate(AVALU = NA_character_) + + input_acido_daids <- expected_acido_daids %>% + select(-ATOXGRL) + + actual_acido_daids <- derive_var_atoxgr_dir( + input_acido_daids, + new_var = ATOXGRL, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCL, + criteria_direction = "L", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_acido_daids, + compare = actual_acido_daids, + keys = c("ATOXDSCL", "TESTNUM") + ) +}) + +### Albumin, Low +### Grade 3: < 20 +### Grade 2: >= 20 to < 30 +### Grade 1: 30 to < LLN + +## Test 83: DAIDS Albumin, Low ---- +test_that("derive_var_atoxgr Test 83: DAIDS Albumin, Low", { + expected_albl_daids <- tibble::tribble( + ~ATOXDSCL, ~AVAL, ~ANRLO, ~AVALU, ~ATOXGRL, ~TESTNUM, + "Not a term", 35, 40, "g/L", NA, 1, + NA_character_, 35, 40, "g/L", NA, 2, + # ANRLO not missing + "Albumin, Low", 19, 40, "g/L", "3", 3, + "Albumin, Low", 20, 40, "g/L", "2", 4, + "Albumin, Low", 29, 40, "g/L", "2", 5, + "Albumin, Low", 30, 40, "g/L", "1", 6, + "Albumin, Low", 39, 40, "g/L", "1", 7, + "Albumin, Low", 40, 40, "g/L", "0", 8, + # ANRLO missing - can grade 2 and 3 + "Albumin, Low", 19, NA, "g/L", "3", 9, + "Albumin, Low", 20, NA, "g/L", "2", 10, + "Albumin, Low", 29, NA, "g/L", "2", 11, + # ANRLO missing - can NOT grade 0 or 1 + "Albumin, Low", 30, NA, "g/L", NA, 12, + "Albumin, Low", 39, NA, "g/L", NA, 13, + "Albumin, Low", 40, NA, "g/L", NA, 14, + # AVALU missing cannot grade + "Albumin, Low", 40, 40, NA, NA, 15, + # AVAL missing cannot grade + "Albumin, Low", NA, 40, "g/L", NA, 16, + ) + + input_albl_daids <- expected_albl_daids %>% + select(-ATOXGRL) + + actual_albl_daids <- derive_var_atoxgr_dir( + input_albl_daids, + new_var = ATOXGRL, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCL, + criteria_direction = "L", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_albl_daids, + compare = actual_albl_daids, + keys = c("ATOXDSCL", "TESTNUM") + ) +}) + + +### Alkaline Phosphatase, High +### Grade 4: >= 10.0 x ULN +### Grade 3: 5.0 to < 10.0 x ULN +### Grade 2: 2.5 to < 5.0 x ULN +### Grade 1: 1.25 to < 2.5 x ULN + +## Test 84: DAIDS Alkaline Phosphatase, High ---- +test_that("derive_var_atoxgr Test 84: DAIDS Alkaline Phosphatase, High", { + expected_alkphi_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~ANRHI, ~ATOXGRH, ~TESTNUM, + "Not a term", 30, 40, NA, 1, + NA_character_, 30, 40, NA, 2, + # ANRHI not missing + "Alkaline Phosphatase, High", 401, 40, "4", 3, + "Alkaline Phosphatase, High", 400, 40, "4", 4, + "Alkaline Phosphatase, High", 399, 40, "3", 5, + "Alkaline Phosphatase, High", 200, 40, "3", 6, + "Alkaline Phosphatase, High", 199, 40, "2", 7, + "Alkaline Phosphatase, High", 100, 40, "2", 8, + "Alkaline Phosphatase, High", 99, 40, "1", 9, + "Alkaline Phosphatase, High", 51, 40, "1", 10, + "Alkaline Phosphatase, High", 50, 40, "1", 11, + "Alkaline Phosphatase, High", 49, 40, "0", 12, + # ANRHI missing cannot grade + "Alkaline Phosphatase, High", 49, NA, NA, 13, + # AVAL missing cannot grade + "Alkaline Phosphatase, High", NA, 40, NA, 14, + ) %>% + mutate(AVALU = NA_character_) + + input_alkphi_daids <- expected_alkphi_daids %>% + select(-ATOXGRH) + + actual_alkphi_daids <- derive_var_atoxgr_dir( + input_alkphi_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_alkphi_daids, + compare = actual_alkphi_daids, + keys = c("ATOXDSCH", "TESTNUM") + ) +}) + +### Alkalosis +### Grade 4: pH > 7.5 with lifethreatening consequences +### Grade 3: pH > 7.5 without lifethreatening consequences +### Grade 2: pH > ULN to ≤ 7.5 + +## Test 85: DAIDS Alkalosis ---- +test_that("derive_var_atoxgr Test 85: DAIDS Alkalosis", { + expected_alkalo_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~ANRLO, ~ANRHI, ~ATOXGRH, ~TESTNUM, + "Not a term", 7.3, 7.35, 7.4, NA, 1, + NA_character_, 7.3, 7.35, 7.4, NA, 2, + # ANRHI not missing + "Alkalosis", 7.51, 7.35, 7.4, "4", 3, + "Alkalosis", 7.5, 7.35, 7.4, "2", 4, + "Alkalosis", 7.41, 7.35, 7.4, "2", 5, + "Alkalosis", 7.4, 7.35, 7.4, "0", 6, + "Alkalosis", 7.39, 7.35, 7.4, "0", 7, + # ANRHI missing - can grade 4 + "Alkalosis", 7.51, 7.35, NA, "4", 8, + # ANRHI missing - can NOT grade 0 or 2 + "Alkalosis", 7.5, 7.35, NA, NA, 9, + "Alkalosis", 7.41, 7.35, NA, NA, 10, + "Alkalosis", 7.4, 7.35, NA, NA, 11, + "Alkalosis", 7.39, 7.35, NA, NA, 12, + # AVAL missing cannot grade + "Alkalosis", NA, 1.1, NA, NA, 13, + ) %>% + mutate(AVALU = NA_character_) + + input_alkalo_daids <- expected_alkalo_daids %>% + select(-ATOXGRH) + + actual_alkalo_daids <- derive_var_atoxgr_dir( + input_alkalo_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_alkalo_daids, + compare = actual_alkalo_daids, + keys = c("ATOXDSCH", "TESTNUM") + ) +}) + + +### ALT, High +### Grade 4: >= 10.0 x ULN +### Grade 3: 5.0 to < 10.0 x ULN +### Grade 2: 2.5 to < 5.0 x ULN +### Grade 1: 1.25 to < 2.5 x ULN + +## Test 86: DAIDS ALT, High ---- +test_that("derive_var_atoxgr Test 86: DAIDS ALT, High", { + expected_alti_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~ANRHI, ~ATOXGRH, ~TESTNUM, + "Not a term", 30, 60, NA, 1, + NA_character_, 30, 60, NA, 2, + # ANRHI not missing + "ALT, High", 601, 60, "4", 3, + "ALT, High", 600, 60, "4", 4, + "ALT, High", 599, 60, "3", 5, + "ALT, High", 300, 60, "3", 6, + "ALT, High", 299, 60, "2", 7, + "ALT, High", 150, 60, "2", 8, + "ALT, High", 149, 60, "1", 9, + "ALT, High", 76, 60, "1", 10, + "ALT, High", 75, 60, "1", 11, + "ALT, High", 74, 60, "0", 12, + # ANRHI missing cannot grade + "ALT, High", 49, NA, NA, 13, + # AVAL missing cannot grade + "ALT, High", NA, 60, NA, 14, + ) %>% + mutate(AVALU = NA_character_) + + input_alti_daids <- expected_alti_daids %>% + select(-ATOXGRH) + + actual_alti_daids <- derive_var_atoxgr_dir( + input_alti_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_alti_daids, + compare = actual_alti_daids, + keys = c("ATOXDSCH", "TESTNUM") + ) +}) + + +### Amylase, High +### Grade 4: >= 5.0 x ULN +### Grade 3: 3.0 to < 5.0 x ULN +### Grade 2: 1.5 to < 3.0 x ULN +### Grade 1: 1.1 to < 1.5 x ULN + +## Test 87: DAIDS Amylase, High ---- +test_that("derive_var_atoxgr Test 87: DAIDS Amylase, High", { + expected_amyli_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~ANRHI, ~ATOXGRH, ~TESTNUM, + "Not a term", 30, 60, NA, 1, + NA_character_, 30, 60, NA, 2, + # ANRHI not missing + "Amylase, High", 301, 60, "4", 3, + "Amylase, High", 300, 60, "4", 4, + "Amylase, High", 299, 60, "3", 5, + "Amylase, High", 180, 60, "3", 6, + "Amylase, High", 179, 60, "2", 7, + "Amylase, High", 90, 60, "2", 8, + "Amylase, High", 89, 60, "1", 9, + "Amylase, High", 66, 60, "1", 10, + "Amylase, High", 65, 60, "0", 11, + # ANRHI missing cannot grade + "Amylase, High", 65, NA, NA, 12, + # AVAL missing cannot grade + "Amylase, High", NA, 60, NA, 13, + ) %>% + mutate(AVALU = NA_character_) + + input_amyli_daids <- expected_amyli_daids %>% + select(-ATOXGRH) + + actual_amyli_daids <- derive_var_atoxgr_dir( + input_amyli_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_amyli_daids, + compare = actual_amyli_daids, + keys = c("ATOXDSCH", "TESTNUM") + ) +}) + + + +### AST, High +### Grade 4: >= 10.0 x ULN +### Grade 3: 5.0 to < 10.0 x ULN +### Grade 2: 2.5 to < 5.0 x ULN +### Grade 1: 1.25 to < 2.5 x ULN + +## Test 88: DAIDS AST, High ---- +test_that("derive_var_atoxgr Test 88: DAIDS AST, High", { + expected_asti_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~ANRHI, ~ATOXGRH, ~TESTNUM, + "Not a term", 30, 60, NA, 1, + NA_character_, 30, 60, NA, 2, + # ANRHI not missing + "AST, High", 601, 60, "4", 3, + "AST, High", 600, 60, "4", 4, + "AST, High", 599, 60, "3", 5, + "AST, High", 300, 60, "3", 6, + "AST, High", 299, 60, "2", 7, + "AST, High", 150, 60, "2", 8, + "AST, High", 149, 60, "1", 9, + "AST, High", 76, 60, "1", 10, + "AST, High", 75, 60, "1", 11, + "AST, High", 74, 60, "0", 12, + # ANRHI missing cannot grade + "AST, High", 49, NA, NA, 13, + # AVAL missing cannot grade + "AST, High", NA, 60, NA, 14, + ) %>% + mutate(AVALU = NA_character_) + + input_asti_daids <- expected_asti_daids %>% + select(-ATOXGRH) + + actual_asti_daids <- derive_var_atoxgr_dir( + input_asti_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_asti_daids, + compare = actual_asti_daids, + keys = c("ATOXDSCH", "TESTNUM") + ) +}) + + +### Bicarbonate, Low +### Grade 4: < 8.0 mmol/L +### Grade 3: 8.0 -< 11.0 mmol/L +### Grade 2: 11.0 -< 16.0 mmol/L +### Grade 1: 16.0 mmol/L -< LLN + +## Test 89: DAIDS Bicarbonate, Low ---- +test_that("derive_var_atoxgr Test 89: DAIDS Bicarbonate, Low", { + expected_bicarbd_daids <- tibble::tribble( + ~ATOXDSCL, ~AVAL, ~ANRLO, ~AVALU, ~ATOXGRL, ~TESTNUM, + "Not a term", 22, 20, "mmol/L", NA, 1, + NA_character_, 22, 20, "mmol/L", NA, 2, + # ANRLO not missing + "Bicarbonate, Low", 7.9, 20, "mmol/L", "4", 3, + "Bicarbonate, Low", 8, 20, "mmol/L", "3", 4, + "Bicarbonate, Low", 10.9, 20, "mmol/L", "3", 5, + "Bicarbonate, Low", 11, 20, "mmol/L", "2", 6, + "Bicarbonate, Low", 15.9, 20, "mmol/L", "2", 7, + "Bicarbonate, Low", 16, 20, "mmol/L", "1", 8, + "Bicarbonate, Low", 19, 20, "mmol/L", "1", 9, + "Bicarbonate, Low", 20, 20, "mmol/L", "0", 10, + # ANRLO missing - can grade 2-4 + "Bicarbonate, Low", 7.9, NA, "mmol/L", "4", 11, + "Bicarbonate, Low", 8, NA, "mmol/L", "3", 12, + "Bicarbonate, Low", 10.9, NA, "mmol/L", "3", 13, + "Bicarbonate, Low", 11, NA, "mmol/L", "2", 14, + "Bicarbonate, Low", 15.9, NA, "mmol/L", "2", 15, + # ANRLO missing - can NOT grade 0 or 1 + "Bicarbonate, Low", 16, NA, "mmol/L", NA, 16, + "Bicarbonate, Low", 19, NA, "mmol/L", NA, 17, + "Bicarbonate, Low", 20, NA, "mmol/L", NA, 18, + # Unit missing cannot grade + "Bicarbonate, Low", 20, 20, NA, NA, 19, + # AVAL missing cannot grade + "Bicarbonate, Low", NA, 20, "mmol/L", NA, 20, + ) + input_bicarbd_daids <- expected_bicarbd_daids %>% + select(-ATOXGRL) + + actual_bicarbd_daids <- derive_var_atoxgr_dir( + input_bicarbd_daids, + new_var = ATOXGRL, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCL, + criteria_direction = "L", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_bicarbd_daids, + compare = actual_bicarbd_daids, + keys = c("ATOXDSCL", "TESTNUM") + ) +}) + + +### Direct Bilirubin, High + +### 17.1 used as conversion from "mg/dL" to "umol/L" + +### > 28 days of age + +### Grade 4: > ULN + +expected_dbiligt28d_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~ANRHI, ~AVALU, ~ATOXGRH, ~TESTNUM, + "Not a term", 7, 8, "umol/L", NA, 1, + NA_character_, 7, 8, "umol/L", NA, 2, + # ANRHI not missing + "Direct Bilirubin, High", 8.1, 8, "umol/L", "4", 3, + "Direct Bilirubin, High", 8, 8, "umol/L", "0", 4, + "Direct Bilirubin, High", 7.9, 8, "umol/L", "0", 5, + # ANRHI missing cannot still grade 0 or 4 + "Direct Bilirubin, High", 8.1, NA, "umol/L", NA, 6, + "Direct Bilirubin, High", 8, NA, "umol/L", NA, 7, + "Direct Bilirubin, High", 7.9, NA, "umol/L", NA, 8, + # AVAL missing cannot grade + "Direct Bilirubin, High", NA, 8, "umol/L", NA, 9, +) %>% + mutate( + BRTHDT = lubridate::ymd("2023-01-01"), + LBDT = lubridate::ymd("2023-01-30") + ) + +### <= 28 days of age + +### Grade 4: > 2 mg/dL (> 34.2 umol/L) +### Grade 3: > 1.5 to <= 2 mg/dL (> 25.65 to <= 34.2 umol/L) +### Grade 2: > 1 to <= 1.5 mg/dL (> 17.1 to <= 25.65 umol/L) +### Grade 1: ULN to <= 1 mg/dL (ULN to <= 17.1 umol/L) + + +expected_dbilile28d_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~ANRHI, ~AVALU, ~ATOXGRH, ~TESTNUM, + "Not a term", 7, 8, "umol/L", NA, 10, + NA_character_, 7, 8, "umol/L", NA, 11, + # ANRHI not missing + "Direct Bilirubin, High", 34.3, 8, "umol/L", "4", 12, + "Direct Bilirubin, High", 34.2, 8, "umol/L", "3", 13, + "Direct Bilirubin, High", 25.66, 8, "umol/L", "3", 14, + "Direct Bilirubin, High", 25.65, 8, "umol/L", "2", 15, + "Direct Bilirubin, High", 17.19, 8, "umol/L", "2", 16, + "Direct Bilirubin, High", 17.1, 8, "umol/L", "1", 17, + "Direct Bilirubin, High", 8, 8, "umol/L", "1", 18, + "Direct Bilirubin, High", 7.9, 8, "umol/L", "0", 19, + # ANRHI missing can still grade 2 - 4 + "Direct Bilirubin, High", 34.3, NA, "umol/L", "4", 20, + "Direct Bilirubin, High", 34.2, NA, "umol/L", "3", 21, + "Direct Bilirubin, High", 25.66, NA, "umol/L", "3", 22, + "Direct Bilirubin, High", 25.65, NA, "umol/L", "2", 23, + "Direct Bilirubin, High", 17.19, NA, "umol/L", "2", 24, + # ANRHI missing cannot still grade 0 - 1 + "Direct Bilirubin, High", 17.1, NA, "umol/L", NA, 25, + "Direct Bilirubin, High", 8, NA, "umol/L", NA, 26, + "Direct Bilirubin, High", 7.9, NA, "umol/L", NA, 27, + # AVAL missing cannot grade + "Direct Bilirubin, High", NA, 8, "umol/L", NA, 28, +) %>% + mutate( + BRTHDT = lubridate::ymd("2023-01-01"), + LBDT = lubridate::ymd("2023-01-29") + ) + +### add subjects with missing LBDT or BRTHDT + +expected_dbilinoage_daids <- expected_dbilile28d_daids %>% + filter(TESTNUM %in% c(18, 19)) %>% + mutate( + LBDT = if_else(TESTNUM == 18, NA, LBDT), + BRTHDT = if_else(TESTNUM == 19, NA, BRTHDT), + ATOXGRH = NA_character_, + TESTNUM = if_else(TESTNUM == 18, 29, 30) + ) + +### put all data together +expected_dbili_daids <- expected_dbilinoage_daids %>% + bind_rows( + expected_dbilile28d_daids, + expected_dbiligt28d_daids + ) + + +## Test 90: DAIDS Direct Bilirubin, High ---- +test_that("derive_var_atoxgr Test 90: DAIDS Direct Bilirubin, High", { + input_dbili_daids <- expected_dbili_daids %>% + select(-ATOXGRH) + + actual_dbili_daids <- derive_var_atoxgr_dir( + input_dbili_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_dbili_daids, + compare = actual_dbili_daids, + keys = c("ATOXDSCH", "TESTNUM") + ) +}) + +### Total Bilirubin, High + +### > 28 days of age + +### Grade 4: >= 5.0 x ULN +### Grade 3: 2.6 to < 5.0 x ULN +### Grade 2: 1.6 to < 2.6 x ULN +### Grade 1: 1.1 to < 1.6 x ULN + +expected_tbiligt28d_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~ANRHI, ~AVALU, ~ATOXGRH, ~TESTNUM, + "Not a term", 9, 10, "umol/L", NA, 1, + NA_character_, 9, 10, "umol/L", NA, 2, + # ANRHI not missing + "Total Bilirubin, High", 50, 10, "umol/L", "4", 3, + "Total Bilirubin, High", 49, 10, "umol/L", "3", 4, + "Total Bilirubin, High", 26, 10, "umol/L", "3", 5, + "Total Bilirubin, High", 25.9, 10, "umol/L", "2", 6, + "Total Bilirubin, High", 16, 10, "umol/L", "2", 7, + "Total Bilirubin, High", 15.9, 10, "umol/L", "1", 8, + "Total Bilirubin, High", 11, 10, "umol/L", "1", 9, + "Total Bilirubin, High", 10.9, 10, "umol/L", "0", 10, + # Unit missing can grade - grade based on comparison of AVAL with ANRHI + "Total Bilirubin, High", 10.9, 10, NA, "0", 11, + # ANRHI missing - cannot grade + "Total Bilirubin, High", 10.9, NA, "umol/L", NA, 12, + # AVAL missing cannot grade + "Total Bilirubin, High", NA, 10, "umol/L", NA, 13, +) %>% + mutate( + BRTHDT = lubridate::ymd("2023-01-01"), + LBDT = lubridate::ymd("2023-01-30") + ) + +### make Age <= 28 all results NA for ATOXGRH +expected_tbilile28d_daids <- expected_tbiligt28d_daids %>% + mutate( + LBDT = lubridate::ymd("2023-01-29"), + ATOXGRH = NA_character_, + TESTNUM = TESTNUM + 13 + ) + +### make Age missing results NA for ATOXGRH +expected_tbilinoage_daids <- expected_tbiligt28d_daids %>% + filter(TESTNUM %in% c(10, 11)) %>% + mutate( + LBDT = if_else(TESTNUM == 10, NA, LBDT), + BRTHDT = if_else(TESTNUM == 11, NA, BRTHDT), + ATOXGRH = NA_character_, + TESTNUM = if_else(TESTNUM == 10, 27, 28) + ) + +expected_tbili_daids <- expected_tbilinoage_daids %>% + bind_rows( + expected_tbiligt28d_daids, + expected_tbilile28d_daids + ) + + +## Test 91: DAIDS Total Bilirubin, High ---- +test_that("derive_var_atoxgr Test 91: DAIDS Total Bilirubin, High", { + input_tbili_daids <- expected_tbili_daids %>% + select(-ATOXGRH) + + actual_tbili_daids <- derive_var_atoxgr_dir( + input_tbili_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_tbili_daids, + compare = actual_tbili_daids, + keys = c("ATOXDSCH", "TESTNUM") + ) +}) + + +### Calcium, High + +### >= 7 days of age +### Grade 4: >= 3.38 mmol/L +### Grade 3: 3.13 -< 3.38 mmol/L +### Grade 2: 2.88 -< 3.13 mmol/L +### Grade 1: 2.65 -< 2.88 mmol/L + +expected_calcige7d_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~AVALU, ~ATOXGRH, ~TESTNUM, + "Not a term", 3.5, "mmol/L", NA, 1, + NA_character_, 3.5, "mmol/L", NA, 2, + # ANRHI not missing + "Calcium, High", 3.38, "mmol/L", "4", 3, + "Calcium, High", 3.37, "mmol/L", "3", 4, + "Calcium, High", 3.13, "mmol/L", "3", 5, + "Calcium, High", 3.12, "mmol/L", "2", 6, + "Calcium, High", 2.88, "mmol/L", "2", 7, + "Calcium, High", 2.87, "mmol/L", "1", 8, + "Calcium, High", 2.65, "mmol/L", "1", 9, + "Calcium, High", 2.64, "mmol/L", "0", 10, + # Unit missing cannot grade + "Calcium, High", 2.5, NA, NA, 11, + # AVAL missing cannot grade + "Calcium, High", NA, "mmol/L", NA, 12, +) %>% + mutate( + BRTHDT = lubridate::ymd("2023-01-01"), + LBDT = lubridate::ymd("2023-01-08") + ) + +### < 7 days of age +### Grade 4: >= 3.38 mmol/L +### Grade 3: 3.23 -< 3.38 mmol/L +### Grade 2: 3.1 -< 3.23 mmol/L +### Grade 1: 2.88 -< 3.1 mmol/L + +expected_calcilt7d_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~AVALU, ~ATOXGRH, ~TESTNUM, + "Not a term", 3.5, "mmol/L", NA, 13, + NA_character_, 3.5, "mmol/L", NA, 14, + # ANRHI not missing + "Calcium, High", 3.38, "mmol/L", "4", 15, + "Calcium, High", 3.37, "mmol/L", "3", 16, + "Calcium, High", 3.23, "mmol/L", "3", 17, + "Calcium, High", 3.22, "mmol/L", "2", 18, + "Calcium, High", 3.1, "mmol/L", "2", 19, + "Calcium, High", 3.09, "mmol/L", "1", 20, + "Calcium, High", 2.88, "mmol/L", "1", 21, + "Calcium, High", 2.87, "mmol/L", "0", 22, + # Unit missing cannot grade + "Calcium, High", 3.5, NA, NA, 23, + # AVAL missing cannot grade + "Calcium, High", NA, "mmol/L", NA, 24, +) %>% + mutate( + BRTHDT = lubridate::ymd("2023-01-01"), + LBDT = lubridate::ymd("2023-01-07") + ) + +expected_calcinoage_daids <- expected_calcige7d_daids %>% + filter(TESTNUM %in% c(9, 10)) %>% + mutate( + LBDT = if_else(TESTNUM == 9, NA, LBDT), + BRTHDT = if_else(TESTNUM == 10, NA, BRTHDT), + ATOXGRH = NA_character_, + TESTNUM = if_else(TESTNUM == 9, 25, 26) + ) + +expected_calci_daids <- expected_calcinoage_daids %>% + bind_rows( + expected_calcige7d_daids, + expected_calcilt7d_daids + ) + + +## Test 92: DAIDS Calcium, High ---- +test_that("derive_var_atoxgr Test 92: DAIDS Calcium, High", { + input_calci_daids <- expected_calci_daids %>% + select(-ATOXGRH) + + actual_calci_daids <- derive_var_atoxgr_dir( + input_calci_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_calci_daids, + compare = actual_calci_daids, + keys = c("TESTNUM") + ) +}) + + +### Calcium (Ionized), High +### Grade 4: >= 1.8 mmol/L +### Grade 3: 1.6 -< 1.8 mmol/L +### Grade 2: 1.5 -< 1.6 mmol/L +### Grade 1: >ULN -< 1.5 mmol/L + +## Test 93: DAIDS Calcium (Ionized), High ---- +test_that("derive_var_atoxgr Test 93: DAIDS Calcium (Ionized), High", { + expected_calioni_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~ANRLO, ~ANRHI, ~AVALU, ~ATOXGRH, ~TESTNUM, + "Not a term", 1.8, 1.1, 1.4, "mmol/L", NA, 1, + NA_character_, 1.79, 1.1, 1.4, "mmol/L", NA, 2, + # ANRHI not missing + "Calcium (Ionized), High", 1.8, 1.1, 1.4, "mmol/L", "4", 3, + "Calcium (Ionized), High", 1.79, 1.1, 1.4, "mmol/L", "3", 4, + "Calcium (Ionized), High", 1.6, 1.1, 1.4, "mmol/L", "3", 5, + "Calcium (Ionized), High", 1.59, 1.1, 1.4, "mmol/L", "2", 6, + "Calcium (Ionized), High", 1.5, 1.1, 1.4, "mmol/L", "2", 7, + "Calcium (Ionized), High", 1.49, 1.1, 1.4, "mmol/L", "1", 8, + "Calcium (Ionized), High", 1.41, 1.1, 1.4, "mmol/L", "1", 9, + "Calcium (Ionized), High", 1.4, 1.1, 1.4, "mmol/L", "0", 10, + # ANRHI missing - can grade 2-4 + "Calcium (Ionized), High", 1.8, 1.1, NA, "mmol/L", "4", 11, + "Calcium (Ionized), High", 1.79, 1.1, NA, "mmol/L", "3", 12, + "Calcium (Ionized), High", 1.6, 1.1, NA, "mmol/L", "3", 13, + "Calcium (Ionized), High", 1.59, 1.1, NA, "mmol/L", "2", 14, + "Calcium (Ionized), High", 1.5, 1.1, NA, "mmol/L", "2", 15, + # ANRHI missing - can NOT grade 0 or 1 + "Calcium (Ionized), High", 1.49, 1.1, NA, "mmol/L", NA, 16, + "Calcium (Ionized), High", 1.41, 1.1, NA, "mmol/L", NA, 17, + "Calcium (Ionized), High", 1.4, 1.1, NA, "mmol/L", NA, 18, + # Unit missing cannot grade + "Calcium (Ionized), High", 1.3, 1.1, 1.4, NA, NA, 19, + # AVAL missing cannot grade + "Calcium (Ionized), High", NA, 1.1, 1.4, "mmol/L", NA, 20, + ) + input_calioni_daids <- expected_calioni_daids %>% + select(-ATOXGRH) + + actual_calioni_daids <- derive_var_atoxgr_dir( + input_calioni_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_calioni_daids, + compare = actual_calioni_daids, + keys = c("ATOXDSCH", "TESTNUM") + ) +}) + + +### Calcium, Low + +### >= 7 days of age +### Grade 4: < 1.53 mmol/L +### Grade 3: 1.53 -< 1.75 mmol/L +### Grade 2: 1.75 -< 1.95 mmol/L +### Grade 1: 1.95 -< 2.10 mmol/L + +expected_calcdge7d_daids <- tibble::tribble( + ~ATOXDSCL, ~AVAL, ~AVALU, ~ATOXGRL, ~TESTNUM, + "Not a term", 2.2, "mmol/L", NA, 1, + NA_character_, 2.2, "mmol/L", NA, 2, + # ANRLO not missing + "Calcium, Low", 1.52, "mmol/L", "4", 3, + "Calcium, Low", 1.53, "mmol/L", "3", 4, + "Calcium, Low", 1.74, "mmol/L", "3", 5, + "Calcium, Low", 1.75, "mmol/L", "2", 6, + "Calcium, Low", 1.94, "mmol/L", "2", 7, + "Calcium, Low", 1.95, "mmol/L", "1", 8, + "Calcium, Low", 2.09, "mmol/L", "1", 9, + "Calcium, Low", 2.1, "mmol/L", "0", 10, + # Unit missing cannot grade + "Calcium, Low", 2.5, NA, NA, 11, + # AVAL missing cannot grade + "Calcium, Low", NA, "mmol/L", NA, 12, +) %>% + mutate( + BRTHDT = lubridate::ymd("2023-01-01"), + LBDT = lubridate::ymd("2023-01-08") + ) + +### < 7 days of age +### Grade 4: < 1.38 mmol/L +### Grade 3: 1.38 -< 1.5 mmol/L +### Grade 2: 1.5 -< 1.63 mmol/L +### Grade 1: 1.63 -< 1.88 mmol/L + +expected_calcdlt7d_daids <- tibble::tribble( + ~ATOXDSCL, ~AVAL, ~AVALU, ~ATOXGRL, ~TESTNUM, + "Not a term", 2.2, "mmol/L", NA, 13, + NA_character_, 2.2, "mmol/L", NA, 14, + # ANRLO not missing + "Calcium, Low", 1.37, "mmol/L", "4", 15, + "Calcium, Low", 1.38, "mmol/L", "3", 16, + "Calcium, Low", 1.49, "mmol/L", "3", 17, + "Calcium, Low", 1.5, "mmol/L", "2", 18, + "Calcium, Low", 1.62, "mmol/L", "2", 19, + "Calcium, Low", 1.63, "mmol/L", "1", 20, + "Calcium, Low", 1.87, "mmol/L", "1", 21, + "Calcium, Low", 1.88, "mmol/L", "0", 22, + # Unit missing cannot grade + "Calcium, Low", 2.2, NA, NA, 23, + # AVAL missing cannot grade + "Calcium, Low", NA, "mmol/L", NA, 24, +) %>% + mutate( + BRTHDT = lubridate::ymd("2023-01-01"), + LBDT = lubridate::ymd("2023-01-07") + ) + +expected_calcdnoage_daids <- expected_calcdge7d_daids %>% + filter(TESTNUM %in% c(9, 10)) %>% + mutate( + LBDT = if_else(TESTNUM == 9, NA, LBDT), + BRTHDT = if_else(TESTNUM == 10, NA, BRTHDT), + ATOXGRL = NA_character_, + TESTNUM = if_else(TESTNUM == 9, 25, 26) + ) + +expected_calcd_daids <- expected_calcdnoage_daids %>% + bind_rows( + expected_calcdge7d_daids, + expected_calcdlt7d_daids + ) + + +## Test 94: DAIDS Calcium, Low ---- +test_that("derive_var_atoxgr Test 94: DAIDS Calcium, Low", { + input_calcd_daids <- expected_calcd_daids %>% + select(-ATOXGRL) + + actual_calcd_daids <- derive_var_atoxgr_dir( + input_calcd_daids, + new_var = ATOXGRL, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCL, + criteria_direction = "L", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_calcd_daids, + compare = actual_calcd_daids, + keys = c("TESTNUM") + ) +}) + + +### Calcium (Ionized), Low +### Grade 4: <0.8 mmol/L +### Grade 3: 0.8 -< 0.9 mmol/L +### Grade 2: 0.9 -< 1.0 mmol/L +### Grade 1: 1.0 mmol/L -< LLN + +## Test 95: DAIDS Calcium (Ionized), Low ---- +test_that("derive_var_atoxgr Test 95: DAIDS Calcium (Ionized), Low", { + expected_caliond_daids <- tibble::tribble( + ~ATOXDSCL, ~AVAL, ~ANRLO, ~ANRHI, ~AVALU, ~ATOXGRL, ~TESTNUM, + "Not a term", 0.79, 1.1, 100, "mmol/L", NA, 1, + NA_character_, 0.79, 1.1, 100, "mmol/L", NA, 2, + # ANRLO not missing + "Calcium (Ionized), Low", 0.79, 1.1, 100, "mmol/L", "4", 3, + "Calcium (Ionized), Low", 0.8, 1.1, 100, "mmol/L", "3", 4, + "Calcium (Ionized), Low", 0.89, 1.1, 100, "mmol/L", "3", 5, + "Calcium (Ionized), Low", 0.9, 1.1, 100, "mmol/L", "2", 6, + "Calcium (Ionized), Low", 0.99, 1.1, 100, "mmol/L", "2", 7, + "Calcium (Ionized), Low", 1, 1.1, 100, "mmol/L", "1", 8, + "Calcium (Ionized), Low", 1.09, 1.1, 100, "mmol/L", "1", 9, + "Calcium (Ionized), Low", 1.1, 1.1, 100, "mmol/L", "0", 10, + # ANRLO missing - can grade 2-4 + "Calcium (Ionized), Low", 0.79, NA, 100, "mmol/L", "4", 11, + "Calcium (Ionized), Low", 0.8, NA, 100, "mmol/L", "3", 12, + "Calcium (Ionized), Low", 0.89, NA, 100, "mmol/L", "3", 13, + "Calcium (Ionized), Low", 0.9, NA, 100, "mmol/L", "2", 14, + "Calcium (Ionized), Low", 0.99, NA, 100, "mmol/L", "2", 15, + # ANRLO missing - can NOT grade 0 or 1 + "Calcium (Ionized), Low", 1, NA, 100, "mmol/L", NA, 16, + "Calcium (Ionized), Low", 1.09, NA, 100, "mmol/L", NA, 17, + "Calcium (Ionized), Low", 1.1, NA, 100, "mmol/L", NA, 18, + # Unit missing cannot grade + "Calcium (Ionized), Low", 1.1, 1.1, 100, NA, NA, 19, + # AVAL missing cannot grade + "Calcium (Ionized), Low", NA, 1.1, 100, "mmol/L", NA, 20, + ) + input_caliond_daids <- expected_caliond_daids %>% + select(-ATOXGRL) + + actual_caliond_daids <- derive_var_atoxgr_dir( + input_caliond_daids, + new_var = ATOXGRL, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCL, + criteria_direction = "L", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_caliond_daids, + compare = actual_caliond_daids, + keys = c("ATOXDSCL", "TESTNUM") + ) +}) + + +### Creatine Kinase, High +### Grade 4: >= 20.0 x ULN +### Grade 3: 10.0 -< 20.0 x ULN +### Grade 2: 6 -< 10.0 x ULN +### Grade 1: 3 -< 6 x ULN + +## Test 96: DAIDS Creatine Kinase, High ---- +test_that("derive_var_atoxgr Test 96: DAIDS Creatine Kinase, High", { + expected_cki_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~ANRHI, ~AVALU, ~ATOXGRH, ~TESTNUM, + "Not a term", 10, 5, NA_character_, NA, 1, + NA_character_, 10, 5, NA_character_, NA, 2, + "Creatine Kinase, High", 100, 5, NA_character_, "4", 3, + "Creatine Kinase, High", 99, 5, NA_character_, "3", 4, + "Creatine Kinase, High", 50, 5, NA_character_, "3", 5, + "Creatine Kinase, High", 49, 5, NA_character_, "2", 6, + "Creatine Kinase, High", 30, 5, NA_character_, "2", 7, + "Creatine Kinase, High", 29, 5, NA_character_, "1", 8, + "Creatine Kinase, High", 15, 5, NA_character_, "1", 9, + "Creatine Kinase, High", 14, 5, NA_character_, "0", 10, + # ANRHI missing - cannot grade + "Creatine Kinase, High", 4, NA, NA_character_, NA, 11, + # AVAL missing cannot grade + "Creatine Kinase, High", NA, NA, NA_character_, NA, 12, + ) + + input_cki_daids <- expected_cki_daids %>% + select(-ATOXGRH) + + actual_cki_daids <- derive_var_atoxgr_dir( + input_cki_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_cki_daids, + compare = actual_cki_daids, + keys = c("ATOXDSCH", "TESTNUM") + ) +}) + + +### Creatinine, High +### Grade 4: >= 3.5 x ULN or >= 2 X BASE +### Grade 3: >1.8 -< 3.5 x ULN or 1.5 -< 2 x BASE +### Grade 2: >1.3 - 1.8 x ULN or 1.3 - < 1.5 x BASE +### Grade 1: 1.1 - 1.3 x ULN + +## Test 97: DAIDS Creatinine, High ---- +test_that("derive_var_atoxgr Test 97: DAIDS Creatinine, High", { + expected_creati_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~ANRHI, ~BASE, ~ATOXGRH, ~TESTNUM, + "Not a term", 10, 10, 34, NA, 1, + NA_character_, 10, 10, 34, NA, 2, + "Creatinine, High", 35, 10, 34, "4", 3, + "Creatinine, High", 10, 10, 5, "4", 4, + "Creatinine, High", 34, 10, 34, "3", 5, + "Creatinine, High", 19, 10, 20, "3", 6, + "Creatinine, High", 9, 10, 5, "3", 7, + "Creatinine, High", 7.5, 10, 5, "3", 8, + "Creatinine, High", 18, 10, 34, "2", 9, + "Creatinine, High", 14, 10, 20, "2", 10, + "Creatinine, High", 7.4, 10, 5, "2", 11, + "Creatinine, High", 6.5, 10, 5, "2", 12, + "Creatinine, High", 13, 10, 34, "1", 13, + "Creatinine, High", 11, 10, 20, "1", 14, + "Creatinine, High", 10, 10, 20, "0", 15, + # ANRHI missing - cannot grade + "Creatinine, High", 10, NA, 20, NA, 16, + # AVAL missing cannot grade + "Creatinine, High", NA, 10, 20, NA, 18, + ) %>% + mutate(AVALU = NA_character_) + + input_creati_daids <- expected_creati_daids %>% + select(-ATOXGRH) + + actual_creati_daids <- derive_var_atoxgr_dir( + input_creati_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_creati_daids, + compare = actual_creati_daids, + keys = c("ATOXDSCH", "TESTNUM") + ) +}) + + +### Glucose Fasting, High + +### Grade 4: >= 27.75 mmol/L +### Grade 3: 13.89 -< 27.75 mmol/L +### Grade 2: 6.95 -< 13.89 mmol/L +### Grade 1: 6.11 -< 6.95 mmol/L + +## Test 98: DAIDS Glucose Fasting, High ---- +test_that("derive_var_atoxgr Test 98: DAIDS Glucose Fasting, High", { + expected_glucfi_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~AVALU, ~ATOXGRH, ~TESTNUM, + "Not a term", 9.5, "mg/L", NA, 1, + NA_character_, 9.5, "mmol/L", NA, 2, + "Glucose Fasting, High", 27.75, "mmol/L", "4", 3, + "Glucose Fasting, High", 27.74, "mmol/L", "3", 4, + "Glucose Fasting, High", 13.89, "mmol/L", "3", 5, + "Glucose Fasting, High", 13.88, "mmol/L", "2", 6, + "Glucose Fasting, High", 6.95, "mmol/L", "2", 7, + "Glucose Fasting, High", 6.94, "mmol/L", "1", 8, + "Glucose Fasting, High", 6.11, "mmol/L", "1", 9, + "Glucose Fasting, High", 6.1, "mmol/L", "0", 10, + # AVALU missing cannot grade + "Glucose Fasting, High", 7, NA, NA, 11, + # AVAL missing cannot grade + "Glucose Fasting, High", NA, "mmol/L", NA, 12, + ) + + input_glucfi_daids <- expected_glucfi_daids %>% + select(-ATOXGRH) + + actual_glucfi_daids <- derive_var_atoxgr_dir( + input_glucfi_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_glucfi_daids, + compare = actual_glucfi_daids, + keys = c("ATOXDSCH", "TESTNUM") + ) +}) + +### Glucose Nonfasting, High + +### Grade 4: >= 27.75 mmol/L +### Grade 3: 13.89 -< 27.75 mmol/L +### Grade 2: 8.89 -< 13.89 mmol/L +### Grade 1: 6.44 -< 8.89 mmol/L + +## Test 99: DAIDS Glucose Nonfasting, High ---- +test_that("derive_var_atoxgr Test 99: DAIDS Glucose Nonfasting, High", { + expected_glucnfi_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~AVALU, ~ATOXGRH, ~TESTNUM, + "Not a term", 9.5, "mg/L", NA, 1, + NA_character_, 9.5, "mmol/L", NA, 2, + "Glucose Nonfasting, High", 27.75, "mmol/L", "4", 3, + "Glucose Nonfasting, High", 27.74, "mmol/L", "3", 4, + "Glucose Nonfasting, High", 13.89, "mmol/L", "3", 5, + "Glucose Nonfasting, High", 13.88, "mmol/L", "2", 6, + "Glucose Nonfasting, High", 8.89, "mmol/L", "2", 7, + "Glucose Nonfasting, High", 8.88, "mmol/L", "1", 8, + "Glucose Nonfasting, High", 6.44, "mmol/L", "1", 9, + "Glucose Nonfasting, High", 6.43, "mmol/L", "0", 10, + # AVALU missing cannot grade + "Glucose Nonfasting, High", 7, NA, NA, 11, + # AVAL missing cannot grade + "Glucose Nonfasting, High", NA, "mmol/L", NA, 12, + ) + + input_glucnfi_daids <- expected_glucnfi_daids %>% + select(-ATOXGRH) + + actual_glucnfi_daids <- derive_var_atoxgr_dir( + input_glucnfi_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_glucnfi_daids, + compare = actual_glucnfi_daids, + keys = c("ATOXDSCH", "TESTNUM") + ) +}) + +### Glucose, Low + +### >= 1 month of age + +### Grade 4: < 1.67 mmol/L +### Grade 3: 1.67 -< 2.22 mmol/L +### Grade 2: 2.22 -< 3.05 mmol/L +### Grade 1: 3.05 -< 3.55 mmol/L + +expected_glucdge1m_daids <- tibble::tribble( + ~ATOXDSCL, ~AVAL, ~AVALU, ~ATOXGRL, ~TESTNUM, + "Not a term", 9.5, "mg/L", NA, 1, + NA_character_, 4.1, "mmol/L", NA, 2, + "Glucose, Low", 1.66, "mmol/L", "4", 3, + "Glucose, Low", 1.67, "mmol/L", "3", 4, + "Glucose, Low", 2.21, "mmol/L", "3", 5, + "Glucose, Low", 2.22, "mmol/L", "2", 6, + "Glucose, Low", 3.04, "mmol/L", "2", 7, + "Glucose, Low", 3.05, "mmol/L", "1", 8, + "Glucose, Low", 3.54, "mmol/L", "1", 9, + "Glucose, Low", 3.55, "mmol/L", "0", 10, + # AVALU missing cannot grade + "Glucose, Low", 4, NA, NA, 11, + # AVAL missing cannot grade + "Glucose, Low", NA, "mmol/L", NA, 12, +) %>% + mutate( + BRTHDT = lubridate::ymd("2022-11-30"), + LBDT = lubridate::ymd("2022-12-30"), + ) + +### < 1 month of age + +### Grade 4: < 1.67 mmol/L +### Grade 3: 1.67 -< 2.22 mmol/L +### Grade 2: 2.22 -< 2.78 mmol/L +### Grade 1: 2.78 -< 3.00 mmol/L + +expected_glucdlt1m_daids <- tibble::tribble( + ~ATOXDSCL, ~AVAL, ~AVALU, ~ATOXGRL, ~TESTNUM, + "Not a term", 9.5, "mg/L", NA, 13, + NA_character_, 4.1, "mmol/L", NA, 14, + "Glucose, Low", 1.66, "mmol/L", "4", 15, + "Glucose, Low", 1.67, "mmol/L", "3", 16, + "Glucose, Low", 2.21, "mmol/L", "3", 17, + "Glucose, Low", 2.22, "mmol/L", "2", 18, + "Glucose, Low", 2.77, "mmol/L", "2", 19, + "Glucose, Low", 2.78, "mmol/L", "1", 20, + "Glucose, Low", 2.99, "mmol/L", "1", 21, + "Glucose, Low", 3, "mmol/L", "0", 22, + # AVALU missing cannot grade + "Glucose, Low", 4, NA, NA, 23, + # AVAL missing cannot grade + "Glucose, Low", NA, "mmol/L", NA, 24, +) %>% + mutate( + BRTHDT = lubridate::ymd("2022-11-30"), + LBDT = lubridate::ymd("2022-12-29"), + ) + +expected_glucdnoage_daids <- expected_glucdge1m_daids %>% + filter(TESTNUM %in% c(9, 10)) %>% + mutate( + ATOXGRL = NA_character_, + LBDT = if_else(TESTNUM == 9, NA, LBDT), + BRTHDT = if_else(TESTNUM == 10, NA, BRTHDT), + TESTNUM = if_else(TESTNUM == 9, 25, 26) + ) + +expected_glucd_daids <- expected_glucdnoage_daids %>% + bind_rows( + expected_glucdge1m_daids, + expected_glucdlt1m_daids + ) + + +## Test 100: DAIDS Glucose, Low ---- +test_that("derive_var_atoxgr Test 100: DAIDS Glucose, Low", { + input_glucd_daids <- expected_glucd_daids %>% + select(-ATOXGRL) + + actual_glucd_daids <- derive_var_atoxgr_dir( + input_glucd_daids, + new_var = ATOXGRL, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCL, + criteria_direction = "L", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_glucd_daids, + compare = actual_glucd_daids, + keys = c("ATOXDSCL", "TESTNUM") + ) +}) + + +### Lactate, High + +### Grade 2: >= 2.0 x ULN +### Grade 1: ULN -< 2.0 x ULN + +## Test 101: DAIDS Lactate, High ---- +test_that("derive_var_atoxgr Test 101: DAIDS Lactate, High", { + expected_lacti_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~ANRHI, ~ATOXGRH, ~TESTNUM, + "Not a term", 105, 100, NA, 1, + NA_character_, 105, 100, NA, 2, + "Lactate, High", 200, 100, "2", 3, + "Lactate, High", 199, 100, "1", 4, + "Lactate, High", 100, 100, "1", 5, + "Lactate, High", 99, 100, "0", 6, + # ANRHI missing cannot grade + "Lactate, High", 200, NA, NA, 7, + # AVAL missing cannot grade + "Lactate, High", NA, 100, NA, 8, + ) %>% + mutate(AVALU = NA_character_) + + input_lacti_daids <- expected_lacti_daids %>% + select(-ATOXGRH) + + actual_lacti_daids <- derive_var_atoxgr_dir( + input_lacti_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_lacti_daids, + compare = actual_lacti_daids, + keys = c("ATOXDSCH", "TESTNUM") + ) +}) + + +### Lipase, High + +### Grade 4: >= 5.0 x ULN +### Grade 3: 3.0 -< 5.0 x ULN +### Grade 2: 1.5 -< 3.0 x ULN +### Grade 1: 1.1 -< 1.5 x ULN + +## Test 102: DAIDS Lipase, High ---- +test_that("derive_var_atoxgr Test 102: DAIDS Lipase, High", { + expected_lipi_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~ANRHI, ~ATOXGRH, ~TESTNUM, + "Not a term", 80, 100, NA, 1, + NA_character_, 60, 100, NA, 2, + "Lipase, High", 500, 100, "4", 3, + "Lipase, High", 499, 100, "3", 4, + "Lipase, High", 300, 100, "3", 5, + "Lipase, High", 299, 100, "2", 6, + "Lipase, High", 150, 100, "2", 7, + "Lipase, High", 149, 100, "1", 8, + "Lipase, High", 110, 100, "1", 9, + "Lipase, High", 109, 100, "0", 10, + # ANRHI missing cannot grade + "Lipase, High", 200, NA, NA, 11, + # AVAL missing cannot grade + "Lipase, High", NA, 100, NA, 12, + ) %>% + mutate(AVALU = NA_character_) + + input_lipi_daids <- expected_lipi_daids %>% + select(-ATOXGRH) + + actual_lipi_daids <- derive_var_atoxgr_dir( + input_lipi_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_lipi_daids, + compare = actual_lipi_daids, + keys = c("ATOXDSCH", "TESTNUM") + ) +}) + + +### Cholesterol, Fasting, High + +### >= 18 years of age +### Grade 3: >= 7.77 mmol/L +### Grade 2: 6.19 -< 7.77 mmol/L +### Grade 1: 5.18 -< 6.19 mmol/L + +expected_cholfige18y_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~AVALU, ~ATOXGRH, ~TESTNUM, + "Not a term", 3.5, "mmol/L", NA, 1, + NA_character_, 3.5, "mmol/L", NA, 2, + "Cholesterol, Fasting, High", 7.77, "mmol/L", "3", 3, + "Cholesterol, Fasting, High", 7.76, "mmol/L", "2", 4, + "Cholesterol, Fasting, High", 6.19, "mmol/L", "2", 5, + "Cholesterol, Fasting, High", 6.18, "mmol/L", "1", 6, + "Cholesterol, Fasting, High", 5.18, "mmol/L", "1", 7, + "Cholesterol, Fasting, High", 5.17, "mmol/L", "0", 8, + # Unit missing cannot grade + "Cholesterol, Fasting, High", 3.5, NA, NA, 9, + # AVAL missing cannot grade + "Cholesterol, Fasting, High", NA, "mmol/L", NA, 10, +) %>% + mutate( + BRTHDT = lubridate::ymd("2005-01-08"), + LBDT = lubridate::ymd("2023-01-08") + ) + +### < 18 years of age +### Grade 3: >= 7.77 mmol/L +### Grade 2: 5.15 -< 7.77 mmol/L +### Grade 1: 4.4 -< 5.15 mmol/L + +expected_cholfilt18y_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~AVALU, ~ATOXGRH, ~TESTNUM, + "Not a term", 3.5, "mmol/L", NA, 13, + NA_character_, 3.5, "mmol/L", NA, 14, + "Cholesterol, Fasting, High", 7.77, "mmol/L", "3", 15, + "Cholesterol, Fasting, High", 7.76, "mmol/L", "2", 16, + "Cholesterol, Fasting, High", 5.15, "mmol/L", "2", 17, + "Cholesterol, Fasting, High", 5.14, "mmol/L", "1", 18, + "Cholesterol, Fasting, High", 4.4, "mmol/L", "1", 19, + "Cholesterol, Fasting, High", 4.39, "mmol/L", "0", 20, + # Unit missing cannot grade + "Cholesterol, Fasting, High", 3.5, NA, NA, 21, + # AVAL missing cannot grade + "Cholesterol, Fasting, High", NA, "mmol/L", NA, 22, +) %>% + mutate( + BRTHDT = lubridate::ymd("2005-01-08"), + LBDT = lubridate::ymd("2023-01-07") + ) + +expected_cholfinoage_daids <- expected_cholfige18y_daids %>% + filter(TESTNUM %in% c(9, 10)) %>% + mutate( + LBDT = if_else(TESTNUM == 9, NA, LBDT), + BRTHDT = if_else(TESTNUM == 10, NA, BRTHDT), + ATOXGRH = NA_character_, + TESTNUM = if_else(TESTNUM == 9, 25, 26) + ) + +expected_cholfi_daids <- expected_cholfinoage_daids %>% + bind_rows( + expected_cholfige18y_daids, + expected_cholfilt18y_daids + ) + + +## Test 103: DAIDS Cholesterol, Fasting, High ---- +test_that("derive_var_atoxgr Test 103: DAIDS Cholesterol, Fasting, High", { + input_cholfi_daids <- expected_cholfi_daids %>% + select(-ATOXGRH) + + actual_cholfi_daids <- derive_var_atoxgr_dir( + input_cholfi_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_cholfi_daids, + compare = actual_cholfi_daids, + keys = c("TESTNUM") + ) +}) + + + +### LDL, Fasting, High + +### >= 18 years of age +### Grade 3: >= 4.90 mmol/L +### Grade 2: 4.12 -< 4.90 mmol/L +### Grade 1: 3.17 -< 4.12 mmol/L + +expected_ldlfige18y_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~AVALU, ~ATOXGRH, ~TESTNUM, + "Not a term", 3.1, "mmol/L", NA, 1, + NA_character_, 3.1, "mmol/L", NA, 2, + "LDL, Fasting, High", 4.9, "mmol/L", "3", 3, + "LDL, Fasting, High", 4.89, "mmol/L", "2", 4, + "LDL, Fasting, High", 4.12, "mmol/L", "2", 5, + "LDL, Fasting, High", 4.11, "mmol/L", "1", 6, + "LDL, Fasting, High", 3.37, "mmol/L", "1", 7, + "LDL, Fasting, High", 3.36, "mmol/L", "0", 8, + # Unit missing cannot grade + "LDL, Fasting, High", 3.1, NA, NA, 9, + # AVAL missing cannot grade + "LDL, Fasting, High", NA, "mmol/L", NA, 10, +) %>% + mutate( + BRTHDT = lubridate::ymd("2005-01-08"), + LBDT = lubridate::ymd("2023-01-08") + ) + +### > 2 to < 18 years of age +### Grade 3: >= 4.90 mmol/L +### Grade 2: 3.34 -< 4.90 mmol/L +### Grade 1: 2.85 -< 3.34 mmol/L + +expected_ldlfilt18y_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~AVALU, ~ATOXGRH, ~TESTNUM, + "Not a term", 2.8, "mmol/L", NA, 11, + NA_character_, 2.8, "mmol/L", NA, 12, + "LDL, Fasting, High", 4.9, "mmol/L", "3", 13, + "LDL, Fasting, High", 4.89, "mmol/L", "2", 14, + "LDL, Fasting, High", 3.34, "mmol/L", "2", 15, + "LDL, Fasting, High", 3.33, "mmol/L", "1", 16, + "LDL, Fasting, High", 2.85, "mmol/L", "1", 17, + "LDL, Fasting, High", 2.84, "mmol/L", "0", 18, + # Unit missing cannot grade + "LDL, Fasting, High", 3.5, NA, NA, 19, + # AVAL missing cannot grade + "LDL, Fasting, High", NA, "mmol/L", NA, 20, +) %>% + mutate( + BRTHDT = lubridate::ymd("2020-01-07"), + LBDT = lubridate::ymd("2023-01-07") + ) + +expected_ldlfinoage_daids <- expected_ldlfige18y_daids %>% + filter(TESTNUM %in% c(7, 8)) %>% + mutate( + LBDT = if_else(TESTNUM == 7, NA, LBDT), + BRTHDT = if_else(TESTNUM == 8, NA, BRTHDT), + ATOXGRH = NA_character_, + TESTNUM = if_else(TESTNUM == 7, 25, 26) + ) + +expected_ldlfile2y_daids <- expected_ldlfige18y_daids %>% + filter(TESTNUM %in% c(7, 8)) %>% + mutate( + BRTHDT = if_else(TESTNUM == 7, lubridate::ymd("2021-01-07"), lubridate::ymd("2022-01-07")), + ATOXGRH = NA_character_, + TESTNUM = if_else(TESTNUM == 7, 27, 28) + ) + +expected_ldlfi_daids <- expected_ldlfile2y_daids %>% + bind_rows( + expected_ldlfinoage_daids, + expected_ldlfige18y_daids, + expected_ldlfilt18y_daids + ) + + +## Test 104: DAIDS LDL, Fasting, High ---- +test_that("derive_var_atoxgr Test 104: DAIDS LDL, Fasting, High", { + input_ldlfi_daids <- expected_ldlfi_daids %>% + select(-ATOXGRH) + + actual_ldlfi_daids <- derive_var_atoxgr_dir( + input_ldlfi_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_ldlfi_daids, + compare = actual_ldlfi_daids, + keys = c("TESTNUM") + ) +}) + + +### Triglycerides, Fasting, High + +### Grade 4: > 11.4 mmol/L +### Grade 3: >5.7 - 11.4 mmol/L +### Grade 2: >3.42 - 5.7 mmol/L +### Grade 1: 1.71 - 3.42 mmol/L + +## Test 105: DAIDS Triglycerides, Fasting, High ---- +test_that("derive_var_atoxgr Test 105: DAIDS Triglycerides, Fasting, High", { + expected_trigfi_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~AVALU, ~ATOXGRH, ~TESTNUM, + "Not a term", 1.5, "mmol/L", NA, 1, + NA_character_, 1.5, "mmol/L", NA, 2, + "Triglycerides, Fasting, High", 11.5, "mmol/L", "4", 3, + "Triglycerides, Fasting, High", 11.4, "mmol/L", "3", 4, + "Triglycerides, Fasting, High", 5.8, "mmol/L", "3", 5, + "Triglycerides, Fasting, High", 5.7, "mmol/L", "2", 6, + "Triglycerides, Fasting, High", 3.43, "mmol/L", "2", 7, + "Triglycerides, Fasting, High", 3.42, "mmol/L", "1", 8, + "Triglycerides, Fasting, High", 1.71, "mmol/L", "1", 9, + "Triglycerides, Fasting, High", 1.7, "mmol/L", "0", 10, + # Unit missing cannot grade + "Triglycerides, Fasting, High", 1.5, NA, NA, 11, + # AVAL missing cannot grade + "Triglycerides, Fasting, High", NA, "mmol/L", NA, 12, + ) + + input_trigfi_daids <- expected_trigfi_daids %>% + select(-ATOXGRH) + + + actual_trigfi_daids <- derive_var_atoxgr_dir( + input_trigfi_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_trigfi_daids, + compare = actual_trigfi_daids, + keys = c("ATOXDSCH", "TESTNUM") + ) +}) + + + +### Magnesium, Low + +### Grade 4: <0.3 mmol/L +### Grade 3: 0.3 -< 0.45 mmol/L +### Grade 2: 0.45 -< 0.6 mmol/L +### Grade 1: 0.6 -< 0.7 mmol/L + +## Test 106: DAIDS Magnesium, Low ---- +test_that("derive_var_atoxgr Test 106: DAIDS Magnesium, Low", { + expected_magd_daids <- tibble::tribble( + ~ATOXDSCL, ~AVAL, ~AVALU, ~ATOXGRL, ~TESTNUM, + "Not a term", 0.5, "mmol/L", NA, 1, + NA_character_, 0.5, "mmol/L", NA, 2, + "Magnesium, Low", 0.29, "mmol/L", "4", 3, + "Magnesium, Low", 0.3, "mmol/L", "3", 4, + "Magnesium, Low", 0.44, "mmol/L", "3", 5, + "Magnesium, Low", 0.45, "mmol/L", "2", 6, + "Magnesium, Low", 0.59, "mmol/L", "2", 7, + "Magnesium, Low", 0.6, "mmol/L", "1", 8, + "Magnesium, Low", 0.69, "mmol/L", "1", 9, + "Magnesium, Low", 0.7, "mmol/L", "0", 10, + # Unit missing cannot grade + "Magnesium, Low", 0.5, NA, NA, 11, + # AVAL missing cannot grade + "Magnesium, Low", NA, "mmol/L", NA, 12, + ) + + input_magd_daids <- expected_magd_daids %>% + select(-ATOXGRL) + + actual_magd_daids <- derive_var_atoxgr_dir( + input_magd_daids, + new_var = ATOXGRL, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCL, + criteria_direction = "L", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_magd_daids, + compare = actual_magd_daids, + keys = c("ATOXDSCL", "TESTNUM") + ) +}) + + +### Phosphate, Low + +### > 14 years of age + +### Grade 4: < 0.32 mmol/L +### Grade 3: 0.32 to < 0.45 mmol/L +### Grade 2: 0.45 to < 0.65 mmol/L +### Grade 1: 0.65 mmol/L to < LLN mmol/L + +expected_phosd_daids_gt14y <- tibble::tribble( + ~AVAL, ~ANRLO, ~AVALU, ~ATOXGRL, ~TESTNUM, + 0.9, 0.8, "MM3", NA, 1, + 0.31, 0.8, "mmol/L", "4", 2, + 0.32, 0.8, "mmol/L", "3", 3, + 0.44, 0.8, "mmol/L", "3", 4, + 0.45, 0.8, "mmol/L", "2", 5, + 0.64, 0.8, "mmol/L", "2", 6, + 0.65, 0.8, "mmol/L", "1", 7, + 0.79, 0.8, "mmol/L", "1", 8, + 0.8, 0.8, "mmol/L", "0", 9, + # missing ANRLO - can grade 2 - 4 + 0.31, 0.8, "mmol/L", "4", 10, + 0.32, 0.8, "mmol/L", "3", 11, + 0.44, 0.8, "mmol/L", "3", 12, + 0.45, 0.8, "mmol/L", "2", 13, + 0.64, 0.8, "mmol/L", "2", 14, + # missing ANRLO - can grade 0 - 1 + 0.65, 0.8, "mmol/L", "1", 15, + 0.79, 0.8, "mmol/L", "1", 16, + 0.8, 0.8, "mmol/L", "0", 17, + # missing AVAL + NA, 0.8, "mmol/L", NA, 18, + # missing UNIT + 1, 0.8, NA, NA, 19, +) %>% + mutate( + ATOXDSCL = "Phosphate, Low", + BRTHDT = lubridate::ymd("2008-07-01"), + LBDT = lubridate::ymd("2023-07-01") + ) + +### 1 to 14 years of age + +### Grade 4: < 0.48 mmol/L +### Grade 3: 0.48 to < 0.81 mmol/L +### Grade 2: 0.81 to < 0.97 mmol/L +### Grade 1: 0.97 to <1.13 mmol/L + +expected_phosd_daids_le14y <- tibble::tribble( + ~AVAL, ~AVALU, ~ATOXGRL, ~TESTNUM, + 1.2, "MM3", NA, 20, + 0.47, "mmol/L", "4", 21, + 0.48, "mmol/L", "3", 22, + 0.8, "mmol/L", "3", 23, + 0.81, "mmol/L", "2", 24, + 0.96, "mmol/L", "2", 25, + 0.97, "mmol/L", "1", 26, + 1.12, "mmol/L", "1", 27, + 1.13, "mmol/L", "0", 28, + NA, "mmol/L", NA, 29, + 1, NA, NA, 30, +) %>% + mutate( + ATOXDSCL = "Phosphate, Low", + BRTHDT = lubridate::ymd("2022-07-01"), + LBDT = lubridate::ymd("2023-07-01") + ) + +### < 1 year of age + +### Grade 4: < 0.48 mmol/L +### Grade 3: 0.48 to < 0.81 mmol/L +### Grade 2: 0.81 to < 1.13 mmol/L +### Grade 1: 1.13 to < 1.45 mmol/L + +expected_phosd_daids_lt1y <- tibble::tribble( + ~AVAL, ~AVALU, ~ATOXGRL, ~TESTNUM, + 1.5, "MM3", NA, 31, + 0.47, "mmol/L", "4", 32, + 0.48, "mmol/L", "3", 33, + 0.8, "mmol/L", "3", 34, + 0.81, "mmol/L", "2", 35, + 1.12, "mmol/L", "2", 36, + 1.13, "mmol/L", "1", 37, + 1.44, "mmol/L", "1", 38, + 1.45, "mmol/L", "0", 39, + NA, "mmol/L", NA, 40, + 1.5, NA, NA, 41, +) %>% + mutate( + ATOXDSCL = "Phosphate, Low", + BRTHDT = lubridate::ymd("2023-07-01"), + LBDT = lubridate::ymd("2023-07-02") + ) + + +# Set lab date or birth date to missing +expected_phosd_daids_noage <- expected_phosd_daids_gt14y %>% + filter(TESTNUM %in% c(8, 9)) %>% + mutate( + LBDT = if_else(TESTNUM == 8, NA, LBDT), + BRTHDT = if_else(TESTNUM == 9, NA, BRTHDT), + ATOXGRL = NA, + TESTNUM = if_else(TESTNUM == 8, 42, 43) + ) + +expected_phosd_daids <- expected_phosd_daids_gt14y %>% + bind_rows( + expected_phosd_daids_le14y, + expected_phosd_daids_lt1y, + expected_phosd_daids_noage + ) + + +## Test 107: DAIDS Phosphate, Low ---- +test_that("derive_var_atoxgr Test 107: DAIDS Phosphate, Low", { + input_phosd_daids <- expected_phosd_daids %>% + select(-ATOXGRL) + + actual_phosd_daids <- derive_var_atoxgr_dir( + input_phosd_daids, + new_var = ATOXGRL, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCL, + criteria_direction = "L", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_phosd_daids, + compare = actual_phosd_daids, + keys = c("TESTNUM") + ) +}) + + + +### Potassium, High + +### Grade 4: >= 7 mmol/L +### Grade 3: 6.5 -< 7 mmol/L +### Grade 2: 6 -< 6.5 mmol/L +### Grade 1: 5.6 -< 6 mmol/L + +## Test 108: DAIDS Potassium, High ---- +test_that("derive_var_atoxgr Test 108: DAIDS Potassium, High", { + expected_poti_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~AVALU, ~ATOXGRH, ~TESTNUM, + "Not a term", 5, "mmol/L", NA, 1, + NA_character_, 5, "mmol/L", NA, 2, + "Potassium, High", 7, "mmol/L", "4", 3, + "Potassium, High", 6.9, "mmol/L", "3", 4, + "Potassium, High", 6.5, "mmol/L", "3", 5, + "Potassium, High", 6.4, "mmol/L", "2", 6, + "Potassium, High", 6, "mmol/L", "2", 7, + "Potassium, High", 5.9, "mmol/L", "1", 8, + "Potassium, High", 5.6, "mmol/L", "1", 9, + "Potassium, High", 5.5, "mmol/L", "0", 10, + # Unit missing cannot grade + "Potassium, High", 5, NA, NA, 11, + # AVAL missing cannot grade + "Potassium, High", NA, "mmol/L", NA, 12, + ) + + input_poti_daids <- expected_poti_daids %>% + select(-ATOXGRH) + + + actual_poti_daids <- derive_var_atoxgr_dir( + input_poti_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_poti_daids, + compare = actual_poti_daids, + keys = c("ATOXDSCH", "TESTNUM") + ) +}) + + +### Potassium, Low + +### Grade 4: <2 mmol/L +### Grade 3: 2 -< 2.5 mmol/L +### Grade 2: 2.5 -< 3 mmol/L +### Grade 1: 3 -< 3.4 mmol/L + +## Test 109: DAIDS Potassium, Low ---- +test_that("derive_var_atoxgr Test 109: DAIDS Potassium, Low", { + expected_potd_daids <- tibble::tribble( + ~ATOXDSCL, ~AVAL, ~AVALU, ~ATOXGRL, ~TESTNUM, + "Not a term", 3, "mmol/L", NA, 1, + NA_character_, 3, "mmol/L", NA, 2, + "Potassium, Low", 1.9, "mmol/L", "4", 3, + "Potassium, Low", 2, "mmol/L", "3", 4, + "Potassium, Low", 2.4, "mmol/L", "3", 5, + "Potassium, Low", 2.5, "mmol/L", "2", 6, + "Potassium, Low", 2.9, "mmol/L", "2", 7, + "Potassium, Low", 3, "mmol/L", "1", 8, + "Potassium, Low", 3.3, "mmol/L", "1", 9, + "Potassium, Low", 3.4, "mmol/L", "0", 10, + # Unit missing cannot grade + "Potassium, Low", 3, NA, NA, 11, + # AVAL missing cannot grade + "Potassium, Low", NA, "mmol/L", NA, 12, + ) + + input_potd_daids <- expected_potd_daids %>% + select(-ATOXGRL) + + + actual_potd_daids <- derive_var_atoxgr_dir( + input_potd_daids, + new_var = ATOXGRL, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCL, + criteria_direction = "L", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_potd_daids, + compare = actual_potd_daids, + keys = c("ATOXDSCL", "TESTNUM") + ) +}) + + + +### Sodium, High + +### Grade 4: >= 160 mmol/L +### Grade 3: 154 -< 160 mmol/L +### Grade 2: 150 -< 154 mmol/L +### Grade 1: 146 -< 150 mmol/L + +## Test 110: DAIDS Sodium, High ---- +test_that("derive_var_atoxgr Test 110: DAIDS Sodium, High", { + expected_sodi_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~AVALU, ~ATOXGRH, ~TESTNUM, + "Not a term", 146, "mmol/L", NA, 1, + NA_character_, 146, "mmol/L", NA, 2, + "Sodium, High", 160, "mmol/L", "4", 3, + "Sodium, High", 159, "mmol/L", "3", 4, + "Sodium, High", 154, "mmol/L", "3", 5, + "Sodium, High", 153, "mmol/L", "2", 6, + "Sodium, High", 150, "mmol/L", "2", 7, + "Sodium, High", 149, "mmol/L", "1", 8, + "Sodium, High", 146, "mmol/L", "1", 9, + "Sodium, High", 145, "mmol/L", "0", 10, + # Unit missing cannot grade + "Sodium, High", 140, NA, NA, 11, + # AVAL missing cannot grade + "Sodium, High", NA, "mmol/L", NA, 12, + ) + + input_sodi_daids <- expected_sodi_daids %>% + select(-ATOXGRH) + + + actual_sodi_daids <- derive_var_atoxgr_dir( + input_sodi_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_sodi_daids, + compare = actual_sodi_daids, + keys = c("ATOXDSCH", "TESTNUM") + ) +}) + + +### Sodium, Low + +### Grade 4: <= 120 mmol/L +### Grade 3: >120 -< 125 mmol/L +### Grade 2: 125 -< 130 mmol/L +### Grade 1: 130 -< 135 mmol/L + +## Test 111: DAIDS Sodium, Low ---- +test_that("derive_var_atoxgr Test 111: DAIDS Sodium, Low", { + expected_sodd_daids <- tibble::tribble( + ~ATOXDSCL, ~AVAL, ~AVALU, ~ATOXGRL, ~TESTNUM, + "Not a term", 119, "mmol/L", NA, 1, + NA_character_, 119, "mmol/L", NA, 2, + "Sodium, Low", 120, "mmol/L", "4", 3, + "Sodium, Low", 121, "mmol/L", "3", 4, + "Sodium, Low", 124, "mmol/L", "3", 5, + "Sodium, Low", 125, "mmol/L", "2", 6, + "Sodium, Low", 129, "mmol/L", "2", 7, + "Sodium, Low", 130, "mmol/L", "1", 8, + "Sodium, Low", 134, "mmol/L", "1", 9, + "Sodium, Low", 135, "mmol/L", "0", 10, + # Unit missing cannot grade + "Sodium, Low", 140, NA, NA, 11, + # AVAL missing cannot grade + "Sodium, Low", NA, "mmol/L", NA, 12, + ) + + input_sodd_daids <- expected_sodd_daids %>% + select(-ATOXGRL) + + + actual_sodd_daids <- derive_var_atoxgr_dir( + input_sodd_daids, + new_var = ATOXGRL, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCL, + criteria_direction = "L", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_sodd_daids, + compare = actual_sodd_daids, + keys = c("ATOXDSCL", "TESTNUM") + ) +}) + + +### Uric Acid, High + +### Grade 4: >= 890 umol/L (0.89 mmol/L) +### Grade 3: 710 -< 890 umol/L (0.71 - <0.89 mmol/L) +### Grade 2: 590 -< 710 umol/L (0.59 - <0.71 mmol/L) +### Grade 1: 450 -< 590 umol/L (0.45 - <0.59 mmol/L) + +## Test 112: DAIDS Uric Acid, High ---- +test_that("derive_var_atoxgr Test 112: DAIDS Uric Acid, High", { + expected_urici_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~AVALU, ~ATOXGRH, ~TESTNUM, + "Not a term", 591, "umol/L", NA, 1, + NA_character_, 591, "umol/L", NA, 2, + "Uric Acid, High", 890, "umol/L", "4", 3, + "Uric Acid, High", 889, "umol/L", "3", 4, + "Uric Acid, High", 710, "umol/L", "3", 5, + "Uric Acid, High", 709, "umol/L", "2", 6, + "Uric Acid, High", 590, "umol/L", "2", 7, + "Uric Acid, High", 589, "umol/L", "1", 8, + "Uric Acid, High", 450, "umol/L", "1", 9, + "Uric Acid, High", 449, "umol/L", "0", 10, + # Unit missing cannot grade + "Uric Acid, High", 200, NA, NA, 11, + # AVAL missing cannot grade + "Uric Acid, High", NA, "umol/L", NA, 12, + ) + + input_urici_daids <- expected_urici_daids %>% + select(-ATOXGRH) + + actual_urici_daids <- derive_var_atoxgr_dir( + input_urici_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_urici_daids, + compare = actual_urici_daids, + keys = c("ATOXDSCH", "TESTNUM") + ) +}) + + +### Absolute CD4+ Count, Low + +### > 5 years of age + +### Grade 4: < 0.1 10^9/L +### Grade 3: 0.1 to < 0.2 10^9/L +### Grade 2: 0.2 to < 0.3 10^9/L +### Grade 1: 0.3 to < 0.4 10^9/L + +## Test 113: DAIDS Absolute Lymphocyte Count, Low ---- +test_that("derive_var_atoxgr Test 113: DAIDS Absolute Lymphocyte Count, Low", { + expected_cd4d_daids_gt5y <- tibble::tribble( + ~AVAL, ~AVALU, ~ATOXGRL, ~TESTNUM, + 0.1, "MM3", NA, 1, + 0.09, "10^9/L", "4", 2, + 0.1, "10^9/L", "3", 3, + 0.19, "10^9/L", "3", 4, + 0.2, "10^9/L", "2", 5, + 0.29, "10^9/L", "2", 6, + 0.3, "10^9/L", "1", 7, + 0.39, "10^9/L", "1", 8, + 0.4, "10^9/L", "0", 9, + NA, "10^9/L", NA, 10, + 1, NA, NA, 11, + ) %>% + mutate( + ATOXDSCL = "Absolute CD4+ Count, Low", + BRTHDT = lubridate::ymd("2023-07-01"), + LBDT = lubridate::ymd("2029-07-01") + ) + + # no criteria for age <= 5 years set grade to missing + expected_cd4d_daids_le5y <- expected_cd4d_daids_gt5y %>% + mutate( + LBDT = lubridate::ymd("2028-07-01"), + ATOXGRL = NA_character_, + TESTNUM = TESTNUM + 11 + ) + + # add missing LBDT and BRTHDT + expected_cd4d_daids_noage <- expected_cd4d_daids_gt5y %>% + filter(TESTNUM %in% c(5, 6)) %>% + mutate( + LBDT = if_else(TESTNUM == 5, NA, LBDT), + BRTHDT = if_else(TESTNUM == 6, NA, BRTHDT), + ATOXGRL = NA_character_, + TESTNUM = if_else(TESTNUM == 5, 23, 24) + ) + + expected_cd4d_daids <- expected_cd4d_daids_gt5y %>% + bind_rows( + expected_cd4d_daids_le5y, + expected_cd4d_daids_noage + ) + + input_cd4d_daids <- expected_cd4d_daids %>% + select(-ATOXGRL) + + actual_cd4d_daids <- derive_var_atoxgr_dir( + input_cd4d_daids, + new_var = ATOXGRL, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCL, + criteria_direction = "L", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_cd4d_daids, + compare = actual_cd4d_daids, + keys = c("TESTNUM") + ) +}) + + +### Absolute Lymphocyte Count, Low + +### > 5 years of age + +### Grade 4: < 0.35 10^9/L +### Grade 3: 0.35 to < 0.5 10^9/L +### Grade 2: 0.5 to < 0.6 10^9/L +### Grade 1: 0.6 to < 0.65 10^9/L + +## Test 114: DAIDS Absolute Lymphocyte Count, Low ---- +test_that("derive_var_atoxgr Test 114: DAIDS Absolute Lymphocyte Count, Low", { + expected_lymphd_daids_gt5y <- tibble::tribble( + ~AVAL, ~AVALU, ~ATOXGRL, ~TESTNUM, + 0.35, "MM3", NA, 1, + 0.34, "10^9/L", "4", 2, + 0.35, "10^9/L", "3", 3, + 0.49, "10^9/L", "3", 4, + 0.5, "10^9/L", "2", 5, + 0.59, "10^9/L", "2", 6, + 0.6, "10^9/L", "1", 7, + 0.64, "10^9/L", "1", 8, + 0.65, "10^9/L", "0", 9, + NA, "10^9/L", NA, 10, + 1, NA, NA, 11, + ) %>% + mutate( + ATOXDSCL = "Absolute Lymphocyte Count, Low", + BRTHDT = lubridate::ymd("2023-07-01"), + LBDT = lubridate::ymd("2029-07-01") + ) + + # no criteria for age <= 5 years set grade to missing + expected_lymphd_daids_le5y <- expected_lymphd_daids_gt5y %>% + mutate( + LBDT = lubridate::ymd("2028-07-01"), + ATOXGRL = NA_character_, + TESTNUM = TESTNUM + 11 + ) + + # add missing LBDT and BRTHDT + expected_lymphd_daids_noage <- expected_lymphd_daids_gt5y %>% + filter(TESTNUM %in% c(5, 6)) %>% + mutate( + LBDT = if_else(TESTNUM == 5, NA, LBDT), + BRTHDT = if_else(TESTNUM == 6, NA, BRTHDT), + ATOXGRL = NA_character_, + TESTNUM = if_else(TESTNUM == 5, 23, 24) + ) + + expected_lymphd_daids <- expected_lymphd_daids_gt5y %>% + bind_rows( + expected_lymphd_daids_le5y, + expected_lymphd_daids_noage + ) + + input_lymphd_daids <- expected_lymphd_daids %>% + select(-ATOXGRL) + + actual_lymphd_daids <- derive_var_atoxgr_dir( + input_lymphd_daids, + new_var = ATOXGRL, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCL, + criteria_direction = "L", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_lymphd_daids, + compare = actual_lymphd_daids, + keys = c("TESTNUM") + ) +}) + + +### Absolute Neutrophil Count (ANC), Low + +### > 7 days of age + +### Grade 4: < 0.4 10^9/L +### Grade 3: 0.4 to < 0.6 10^9/L +### Grade 2: 0.6 to < 0.8 10^9/L +### Grade 1: 0.8 to 1 10^9/L + +expected_ancd_daids_gt7d <- tibble::tribble( + ~AVAL, ~AVALU, ~ATOXGRL, ~TESTNUM, + 0.3, "MM3", NA, 1, + 0.399, "10^9/L", "4", 2, + 0.4, "10^9/L", "3", 3, + 0.599, "10^9/L", "3", 4, + 0.6, "10^9/L", "2", 5, + 0.799, "10^9/L", "2", 6, + 0.8, "10^9/L", "1", 7, + 1, "10^9/L", "1", 8, + 1.01, "10^9/L", "0", 9, + NA, "10^9/L", NA, 10, + 1, NA, NA, 11, +) %>% + mutate( + ATOXDSCL = "Absolute Neutrophil Count (ANC), Low", + BRTHDT = lubridate::ymd("2023-07-01"), + LBDT = lubridate::ymd("2023-07-09") + ) + +### 2 to 7 days of age + +### Grade 4: < 0.75 10^9/L +### Grade 3: 0.75 to < 1.0 10^9/L +### Grade 2: 1.0 to < 1.25 10^9/L +### Grade 1: 1.25 to 1.5 10^9/L + +expected_ancd_daids_ge2d <- tibble::tribble( + ~AVAL, ~AVALU, ~ATOXGRL, ~TESTNUM, + 0.7, "MM3", NA, 12, + 0.749, "10^9/L", "4", 13, + 0.75, "10^9/L", "3", 14, + 0.999, "10^9/L", "3", 15, + 1, "10^9/L", "2", 16, + 1.249, "10^9/L", "2", 17, + 1.25, "10^9/L", "1", 18, + 1.5, "10^9/L", "1", 19, + 1.51, "10^9/L", "0", 20, + NA, "10^9/L", NA, 21, + 1, NA, NA, 22, +) %>% + mutate( + ATOXDSCL = "Absolute Neutrophil Count (ANC), Low", + BRTHDT = lubridate::ymd("2023-07-01"), + LBDT = lubridate::ymd("2023-07-03") + ) + +### <= 1 day of age + +### Grade 4: < 1.50 10^9/L +### Grade 3: 1.50 to < 3.0 10^9/L +### Grade 2: 3.0 to < 4.0 10^9/L +### Grade 1: 4.0 to 5.0 10^9/L + +expected_ancd_daids_le1d <- tibble::tribble( + ~AVAL, ~AVALU, ~ATOXGRL, ~TESTNUM, + 1.5, "MM3", NA, 23, + 1.499, "10^9/L", "4", 24, + 1.5, "10^9/L", "3", 25, + 2.999, "10^9/L", "3", 26, + 3, "10^9/L", "2", 27, + 3.999, "10^9/L", "2", 28, + 4, "10^9/L", "1", 29, + 5, "10^9/L", "1", 30, + 5.01, "10^9/L", "0", 31, + NA, "10^9/L", NA, 32, + 5, NA, NA, 33, +) %>% + mutate( + ATOXDSCL = "Absolute Neutrophil Count (ANC), Low", + BRTHDT = lubridate::ymd("2023-07-01"), + LBDT = lubridate::ymd("2023-07-02") + ) + +expected_ancd_daids <- expected_ancd_daids_gt7d %>% + bind_rows( + expected_ancd_daids_ge2d, + expected_ancd_daids_le1d + ) + +# Set lab date/birth date to missing +expected_ancd_daids_noage <- expected_ancd_daids %>% + filter(TESTNUM %in% c(20, 31)) %>% + mutate( + LBDT = if_else(TESTNUM == 20, NA, LBDT), + BRTHDT = if_else(TESTNUM == 31, NA, BRTHDT), + ATOXGRL = NA, + TESTNUM = case_when( + TESTNUM == 20 ~ 34, + TESTNUM == 31 ~ 35 + ) + ) + +expected_ancd_daids <- expected_ancd_daids %>% + bind_rows(expected_ancd_daids_noage) + + +input_ancd_daids <- expected_ancd_daids %>% + select(-ATOXGRL) + + +## Test 115: DAIDS ANC Low ---- +test_that("derive_var_atoxgr Test 115: DAIDS ANC Low", { + actual_ancd_daids <- derive_var_atoxgr_dir( + input_ancd_daids, + new_var = ATOXGRL, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCL, + criteria_direction = "L", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_ancd_daids, + compare = actual_ancd_daids, + keys = c("TESTNUM") + ) +}) + + +### Fibrinogen Decreased +### Grade 4: <0.5 g/L OR < 0.25 x LLN +### Grade 3: 0.5 to <0.75 g/L OR 0.25 to < 0.50 x LLN +### Grade 2: 0.75 to <1 g/L OR ≥ 0.50 to < 0.75 x LLN +### Grade 1: 1 to < 2 g/L OR 0.75 to < 1.00 x LLN + +## Test 116: DAIDS Fibrinogen Decreased ---- +test_that("derive_var_atoxgr Test 116: DAIDS Fibrinogen Decreased", { + expected_fibd_daids <- tibble::tribble( + ~ATOXDSCL, ~AVAL, ~ANRLO, ~AVALU, ~ATOXGRL, ~TESTNUM, + "Not a term", 2, 1, "g/L", NA, 1, + NA_character_, 2, 1, "g/L", NA, 2, + "Fibrinogen Decreased", 2, 1, "g/dL", NA, 3, + # test first half of criteria + "Fibrinogen Decreased", 0.49, 1, "g/L", "4", 4, + "Fibrinogen Decreased", 0.5, 1, "g/L", "3", 5, + "Fibrinogen Decreased", 0.74, 1, "g/L", "3", 6, + "Fibrinogen Decreased", 0.75, 1, "g/L", "2", 7, + "Fibrinogen Decreased", 0.99, 1, "g/L", "2", 8, + "Fibrinogen Decreased", 1, 1, "g/L", "1", 9, + "Fibrinogen Decreased", 1.99, 1, "g/L", "1", 10, + "Fibrinogen Decreased", 2, 1, "g/L", "0", 11, + # test second half of criteria + "Fibrinogen Decreased", 0.74, 3, "g/L", "4", 12, + "Fibrinogen Decreased", 0.75, 3, "g/L", "3", 13, + "Fibrinogen Decreased", 1.49, 3, "g/L", "3", 14, + "Fibrinogen Decreased", 1.5, 3, "g/L", "2", 15, + "Fibrinogen Decreased", 2.24, 3, "g/L", "2", 16, + "Fibrinogen Decreased", 2.25, 3, "g/L", "1", 17, + "Fibrinogen Decreased", 2.99, 3, "g/L", "1", 18, + "Fibrinogen Decreased", 3, 3, "g/L", "0", 19, + # TEST for missing values + "Fibrinogen Decreased", 0.49, NA, "g/L", "4", 20, + "Fibrinogen Decreased", 0.5, NA, "g/L", NA, 21, + "Fibrinogen Decreased", 2, 1, NA, NA, 22, + "Fibrinogen Decreased", NA, 1, "g/L", NA, 23, + ) + + input_fibd_daids <- expected_fibd_daids %>% + select(-ATOXGRL) + + actual_fibd_daids <- derive_var_atoxgr_dir( + input_fibd_daids, + new_var = ATOXGRL, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCL, + criteria_direction = "L", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_fibd_daids, + compare = actual_fibd_daids, + keys = c("TESTNUM") + ) +}) + + + +### Hemoglobin, Low + +### >= 13 years of age (male only) + +### Grade 4: < 70 g/L +### Grade 3: 70 to < 90 g/L +### Grade 2: 90 to < 100 g/L +### Grade 1: 100 to 109 g/L + +expected_hgbd_daids_ge13ym <- tibble::tribble( + ~ATOXDSCL, ~AVAL, ~AVALU, ~ATOXGRL, ~SEX, ~TESTNUM, + "Hemoglobin, Low", 69, "MM3", NA, "M", 1, + "Hemoglobin, Low", 69, "g/L", "4", "M", 2, + "Hemoglobin, Low", 70, "g/L", "3", "M", 3, + "Hemoglobin, Low", 89, "g/L", "3", "M", 4, + "Hemoglobin, Low", 90, "g/L", "2", "M", 5, + "Hemoglobin, Low", 99, "g/L", "2", "M", 6, + "Hemoglobin, Low", 100, "g/L", "1", "M", 7, + "Hemoglobin, Low", 109, "g/L", "1", "M", 8, + "Hemoglobin, Low", 110, "g/L", "0", "M", 9, + "Hemoglobin, Low", NA, "g/L", NA, "M", 10, + "Hemoglobin, Low", 110, NA, NA, "M", 11, + "Hemoglobin, Low", 110, "g/L", NA, NA, 12, +) %>% + mutate( + BRTHDT = lubridate::ymd("2010-07-01"), + LBDT = lubridate::ymd("2023-07-01") + ) + +### >= 13 years of age (female only) + +### Grade 4: < 65 g/L +### Grade 3: 65 to < 85 g/L +### Grade 2: 85 to < 95 g/L +### Grade 1: 95 to 104 g/L + +expected_hgbd_daids_ge13yf <- tibble::tribble( + ~ATOXDSCL, ~AVAL, ~AVALU, ~ATOXGRL, ~SEX, ~TESTNUM, + "Hemoglobin, Low", 64, "MM3", NA, "F", 13, + "Hemoglobin, Low", 64, "g/L", "4", "F", 14, + "Hemoglobin, Low", 65, "g/L", "3", "F", 15, + "Hemoglobin, Low", 84, "g/L", "3", "F", 16, + "Hemoglobin, Low", 85, "g/L", "2", "F", 17, + "Hemoglobin, Low", 94, "g/L", "2", "F", 18, + "Hemoglobin, Low", 95, "g/L", "1", "F", 19, + "Hemoglobin, Low", 104, "g/L", "1", "F", 20, + "Hemoglobin, Low", 105, "g/L", "0", "F", 21, + "Hemoglobin, Low", NA, "g/L", NA, "F", 22, + "Hemoglobin, Low", 110, NA, NA, "F", 23, + "Hemoglobin, Low", 110, "g/L", NA, NA, 24, +) %>% + mutate( + BRTHDT = lubridate::ymd("2010-07-01"), + LBDT = lubridate::ymd("2023-07-01") + ) + + +### 57 days to < 13 years of age (male and female) + +### Grade 4: < 65 g/L +### Grade 3: 65 to < 85 g/L +### Grade 2: 85 to < 95 g/L +### Grade 1: 95 to 104 g/L + +expected_hgbd_daids_lt13y <- tibble::tribble( + ~ATOXDSCL, ~AVAL, ~AVALU, ~ATOXGRL, ~TESTNUM, + "Hemoglobin, Low", 64, "MM3", NA, 25, + "Hemoglobin, Low", 64, "g/L", "4", 26, + "Hemoglobin, Low", 65, "g/L", "3", 27, + "Hemoglobin, Low", 84, "g/L", "3", 28, + "Hemoglobin, Low", 85, "g/L", "2", 29, + "Hemoglobin, Low", 94, "g/L", "2", 30, + "Hemoglobin, Low", 95, "g/L", "1", 31, + "Hemoglobin, Low", 104, "g/L", "1", 32, + "Hemoglobin, Low", 105, "g/L", "0", 33, + "Hemoglobin, Low", NA, "g/L", NA, 34, + "Hemoglobin, Low", 110, NA, NA, 35, +) %>% + mutate( + BRTHDT = lubridate::ymd("2010-07-01"), + LBDT = lubridate::ymd("2023-06-30") + ) + +### 36 to ≤ 56 days of age (male and female) + +### Grade 4: < 60 g/L +### Grade 3: 60 to < 70 g/L +### Grade 2: 70 to < 85 g/L +### Grade 1: 85 to 96 g/L + +expected_hgbd_daids_le56d <- tibble::tribble( + ~ATOXDSCL, ~AVAL, ~AVALU, ~ATOXGRL, ~TESTNUM, + "Hemoglobin, Low", 59, "MM3", NA, 36, + "Hemoglobin, Low", 59, "g/L", "4", 37, + "Hemoglobin, Low", 60, "g/L", "3", 38, + "Hemoglobin, Low", 69, "g/L", "3", 39, + "Hemoglobin, Low", 70, "g/L", "2", 40, + "Hemoglobin, Low", 84, "g/L", "2", 41, + "Hemoglobin, Low", 85, "g/L", "1", 42, + "Hemoglobin, Low", 96, "g/L", "1", 43, + "Hemoglobin, Low", 97, "g/L", "0", 44, + "Hemoglobin, Low", NA, "g/L", NA, 45, + "Hemoglobin, Low", 110, NA, NA, 46, +) %>% + mutate( + BRTHDT = lubridate::ymd("2023-07-01"), + LBDT = lubridate::ymd("2023-08-26") + ) + + +### 22 to ≤ 35 days of age (male and female) + +### Grade 4: < 67 g/L +### Grade 3: 67 to < 80 g/L +### Grade 2: 80 to < 95 g/L +### Grade 1: 95 to 110 g/L + +expected_hgbd_daids_le35d <- tibble::tribble( + ~ATOXDSCL, ~AVAL, ~AVALU, ~ATOXGRL, ~TESTNUM, + "Hemoglobin, Low", 66, "MM3", NA, 47, + "Hemoglobin, Low", 66, "g/L", "4", 48, + "Hemoglobin, Low", 67, "g/L", "3", 49, + "Hemoglobin, Low", 79, "g/L", "3", 50, + "Hemoglobin, Low", 80, "g/L", "2", 51, + "Hemoglobin, Low", 94, "g/L", "2", 52, + "Hemoglobin, Low", 95, "g/L", "1", 53, + "Hemoglobin, Low", 110, "g/L", "1", 54, + "Hemoglobin, Low", 111, "g/L", "0", 55, + "Hemoglobin, Low", NA, "g/L", NA, 56, + "Hemoglobin, Low", 110, NA, NA, 57, +) %>% + mutate( + BRTHDT = lubridate::ymd("2023-07-01"), + LBDT = lubridate::ymd("2023-08-05") + ) + + +### 8 to ≤ 21 days of age (male and female) + +### Grade 4: < 80 g/L +### Grade 3: 80 to < 90 g/L +### Grade 2: 90 to < 110 g/L +### Grade 1: 110 to 130 g/L + +expected_hgbd_daids_le21d <- tibble::tribble( + ~ATOXDSCL, ~AVAL, ~AVALU, ~ATOXGRL, ~TESTNUM, + "Hemoglobin, Low", 79, "MM3", NA, 58, + "Hemoglobin, Low", 79, "g/L", "4", 59, + "Hemoglobin, Low", 80, "g/L", "3", 60, + "Hemoglobin, Low", 89, "g/L", "3", 61, + "Hemoglobin, Low", 90, "g/L", "2", 62, + "Hemoglobin, Low", 109, "g/L", "2", 63, + "Hemoglobin, Low", 110, "g/L", "1", 64, + "Hemoglobin, Low", 130, "g/L", "1", 65, + "Hemoglobin, Low", 131, "g/L", "0", 66, + "Hemoglobin, Low", NA, "g/L", NA, 67, + "Hemoglobin, Low", 110, NA, NA, 68, +) %>% + mutate( + BRTHDT = lubridate::ymd("2023-07-01"), + LBDT = lubridate::ymd("2023-07-22") + ) + +### ≤ 7 days of age (male and female) + +### Grade 4: < 90 g/L +### Grade 3: 90 to < 100 g/L +### Grade 2: 100 to < 130 g/L +### Grade 1: 130 to 140 g/L + +expected_hgbd_daids_le7d <- tibble::tribble( + ~ATOXDSCL, ~AVAL, ~AVALU, ~ATOXGRL, ~TESTNUM, + "Hemoglobin, Low", 89, "MM3", NA, 69, + "Hemoglobin, Low", 89, "g/L", "4", 70, + "Hemoglobin, Low", 90, "g/L", "3", 71, + "Hemoglobin, Low", 99, "g/L", "3", 72, + "Hemoglobin, Low", 100, "g/L", "2", 73, + "Hemoglobin, Low", 129, "g/L", "2", 74, + "Hemoglobin, Low", 130, "g/L", "1", 75, + "Hemoglobin, Low", 140, "g/L", "1", 76, + "Hemoglobin, Low", 141, "g/L", "0", 77, + "Hemoglobin, Low", NA, "g/L", NA, 78, + "Hemoglobin, Low", 110, NA, NA, 79, +) %>% + mutate( + BRTHDT = lubridate::ymd("2023-07-01"), + LBDT = lubridate::ymd("2023-07-08") + ) + +expected_hgbd_daids <- expected_hgbd_daids_ge13ym %>% + bind_rows( + expected_hgbd_daids_ge13yf, + expected_hgbd_daids_lt13y, + expected_hgbd_daids_le56d, + expected_hgbd_daids_le35d, + expected_hgbd_daids_le21d, + expected_hgbd_daids_le7d + ) + +# Set lab date to missing fo each type, ie SEX is M, F or missing +expected_hgbd_daids_noage <- expected_hgbd_daids %>% + filter(TESTNUM %in% c(5, 17, 29)) %>% + mutate( + LBDT = NA, + ATOXGRL = NA, + TESTNUM = case_when( + TESTNUM == 5 ~ 80, + TESTNUM == 17 ~ 81, + TESTNUM == 29 ~ 82 + ) + ) + +expected_hgbd_daids <- expected_hgbd_daids %>% + bind_rows(expected_hgbd_daids_noage) + + +input_hgbd_daids <- expected_hgbd_daids %>% + select(-ATOXGRL) + +## Test 117: DAIDS HGB Low ---- +test_that("derive_var_atoxgr Test 117: DAIDS HGB Low", { + actual_hgbd_daids <- derive_var_atoxgr_dir( + input_hgbd_daids, + new_var = ATOXGRL, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCL, + criteria_direction = "L", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_hgbd_daids, + compare = actual_hgbd_daids, + keys = c("ATOXDSCL", "TESTNUM") + ) +}) + + +### INR, high + +### Grade 4: >=3 x ULN +### Grade 3: 2 to <3 x ULN +### Grade 2: 1.5 to < 2 x ULN +### Grade 1: 1.1 to < 1.5 x ULN + +## Test 118: DAIDS INR High ---- +test_that("derive_var_atoxgr Test 118: DAIDS INR High", { + expected_inri_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~ANRHI, ~AVALU, ~ATOXGRH, + "Not a term", 80, 80, NA_character_, NA, + NA_character_, 60, 80, NA_character_, NA, + "INR, High", 240, 80, NA_character_, "4", + "INR, High", 239, 80, NA_character_, "3", + "INR, High", 160, 80, NA_character_, "3", + "INR, High", 159, 80, NA_character_, "2", + "INR, High", 120, 80, NA_character_, "2", + "INR, High", 119, 80, NA_character_, "1", + "INR, High", 88, 80, NA_character_, "1", + "INR, High", 87, 80, NA_character_, "0", + # ANRHI missing - cannot grade + "INR, High", 100, NA, NA_character_, NA, + # AVAL missing cannot grade + "INR, High", NA, 80, NA_character_, NA, + ) + + input_inri_daids <- expected_inri_daids %>% + select(-ATOXGRH) + + actual_inri_daids <- derive_var_atoxgr_dir( + input_inri_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_inri_daids, + compare = actual_inri_daids, + keys = c("ATOXDSCH", "AVAL", "ANRHI", "AVALU") + ) +}) + + +### Methemoglobin + +### Grade 4: >=20.0% +### Grade 3: 15 to < 20% +### Grade 2: 10 to < 15% +### Grade 1: 5 to <10% + +## Test 119: DAIDS Methemoglobin ---- +test_that("derive_var_atoxgr Test 119: DAIDS Methemoglobin", { + expected_methi_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~AVALU, ~ATOXGRH, + "Not a term", 20, "%", NA, + NA_character_, 20, "%", NA, + "Methemoglobin", 20, "%", "4", + "Methemoglobin", 19, "%", "3", + "Methemoglobin", 15, "%", "3", + "Methemoglobin", 14, "%", "2", + "Methemoglobin", 10, "%", "2", + "Methemoglobin", 9, "%", "1", + "Methemoglobin", 5, "%", "1", + "Methemoglobin", 4, "%", "0", + # Unit wrong - cannot grade + "Methemoglobin", 100, NA, NA, + # AVAL missing cannot grade + "Methemoglobin", NA, "%", NA, + ) + + input_methi_daids <- expected_methi_daids %>% + select(-ATOXGRH) + + actual_methi_daids <- derive_var_atoxgr_dir( + input_methi_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_methi_daids, + compare = actual_methi_daids, + keys = c("ATOXDSCH", "AVAL", "AVALU") + ) +}) + +### PTT, high + +### Grade 4: >=3 x ULN +### Grade 3: 2.33 to <3 x ULN +### Grade 2: 1.66 to < 2.33 x ULN +### Grade 1: 1.1 to < 1.66 x ULN + +## Test 120: DAIDS PTT High ---- +test_that("derive_var_atoxgr Test 120: DAIDS PTT High", { + expected_ptti_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~ANRHI, ~AVALU, ~ATOXGRH, + "Not a term", 80, 80, NA_character_, NA, + NA_character_, 60, 80, NA_character_, NA, + "PTT, High", 240, 80, NA_character_, "4", + "PTT, High", 239, 80, NA_character_, "3", + "PTT, High", 186.4, 80, NA_character_, "3", + "PTT, High", 186.3, 80, NA_character_, "2", + "PTT, High", 132.8, 80, NA_character_, "2", + "PTT, High", 132.7, 80, NA_character_, "1", + "PTT, High", 88, 80, NA_character_, "1", + "PTT, High", 87, 80, NA_character_, "0", + # ANRHI missing - cannot grade + "PTT, High", 100, NA, NA_character_, NA, + # AVAL missing cannot grade + "PTT, High", NA, 80, NA_character_, NA, + ) + + input_ptti_daids <- expected_ptti_daids %>% + select(-ATOXGRH) + + actual_ptti_daids <- derive_var_atoxgr_dir( + input_ptti_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_ptti_daids, + compare = actual_ptti_daids, + keys = c("ATOXDSCH", "AVAL", "ANRHI", "AVALU") + ) +}) + + +### Platelets, Decreased +### Grade 4: <25 x 10e9 /L +### Grade 3: 25 to <50 x 10e9 /L +### Grade 2: 50 to <100 - x 10e9 +### Grade 1: 100 - 125 x 10e9 /L + +## Test 121: DAIDS Platelets decreased ---- +test_that("derive_var_atoxgr Test 121: DAIDS Platelets decreased", { + expected_plated_daids <- tibble::tribble( + ~ATOXDSCL, ~AVAL, ~AVALU, ~ATOXGRL, ~TESTNUM, + "Not a term", 126, "10^9/L", NA, 1, + NA_character_, 120, "10^9/L", NA, 2, + "Platelets, Decreased", 115, "MM3", NA, 3, + "Platelets, Decreased", 24.9, "10^9/L", "4", 4, + "Platelets, Decreased", 25, "10^9/L", "3", 5, + "Platelets, Decreased", 49.9, "10^9/L", "3", 6, + "Platelets, Decreased", 50, "10^9/L", "2", 7, + "Platelets, Decreased", 99.9, "10^9/L", "2", 8, + "Platelets, Decreased", 100, "10^9/L", "1", 9, + "Platelets, Decreased", 124.9, "10^9/L", "1", 10, + "Platelets, Decreased", 125, "10^9/L", "0", 11, + ) + + input_plated_daids <- expected_plated_daids %>% + select(-ATOXGRL) + + actual_plated_daids <- derive_var_atoxgr_dir( + input_plated_daids, + new_var = ATOXGRL, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCL, + criteria_direction = "L", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_plated_daids, + compare = actual_plated_daids, + keys = c("TESTNUM") + ) +}) + +### PT, high + +### Grade 4: >=3 x ULN +### Grade 3: 1.5 - <3 x ULN +### Grade 2: 1.25 - <1.5 x ULN +### Grade 1: 1.1 - <1.25 x ULN + +## Test 122: DAIDS PT High ---- +test_that("derive_var_atoxgr Test 122: DAIDS PT High", { + expected_pti_daids <- tibble::tribble( + ~ATOXDSCH, ~AVAL, ~ANRHI, ~AVALU, ~ATOXGRH, + "Not a term", 80, 100, NA_character_, NA, + NA_character_, 60, 100, NA_character_, NA, + "PT, High", 300, 100, NA_character_, "4", + "PT, High", 299, 100, NA_character_, "3", + "PT, High", 150, 100, NA_character_, "3", + "PT, High", 149, 100, NA_character_, "2", + "PT, High", 125, 100, NA_character_, "2", + "PT, High", 124, 100, NA_character_, "1", + "PT, High", 110, 100, NA_character_, "1", + "PT, High", 109, 100, NA_character_, "0", + # ANRHI missing - cannot grade + "PT, High", 100, NA, NA_character_, NA, + # AVAL missing cannot grade + "PT, High", NA, 100, NA_character_, NA, + ) + + input_pti_daids <- expected_pti_daids %>% + select(-ATOXGRH) + + actual_pti_daids <- derive_var_atoxgr_dir( + input_pti_daids, + new_var = ATOXGRH, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCH, + criteria_direction = "H", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_pti_daids, + compare = actual_pti_daids, + keys = c("ATOXDSCH", "AVAL", "ANRHI", "AVALU") + ) +}) + +### White blood cell decreased (> 7 days of age) +### Grade 4: <1 x 10e9/L +### Grade 3: 1 to 1.499 x 10e9/L +### Grade 2: 1.5 to 1.999 x 10e9/L +### Grade 1: 2 to 2.499 x 10e9/L + +expected_wbcd_daids_gt7d <- tibble::tribble( + ~ATOXDSCL, ~AVAL, ~AVALU, ~ATOXGRL, ~TESTNUM, + "Not a term", 1, "10^9/L", NA, 1, + NA_character_, 2, "10^9/L", NA, 2, + "WBC, Decreased", 0.9, "MM3", NA, 3, + "WBC, Decreased", 0.9, "10^9/L", "4", 4, + "WBC, Decreased", 1, "10^9/L", "3", 5, + "WBC, Decreased", 1.49, "10^9/L", "3", 6, + "WBC, Decreased", 1.5, "10^9/L", "2", 7, + "WBC, Decreased", 1.99, "10^9/L", "2", 8, + "WBC, Decreased", 2, "10^9/L", "1", 9, + "WBC, Decreased", 2.49, "10^9/L", "1", 10, + "WBC, Decreased", 2.5, "10^9/L", "0", 11, +) %>% + mutate( + BRTHDT = lubridate::ymd("2023-07-01"), + LBDT = lubridate::ymd("2023-07-09") + ) + +### White blood cell decreased (<= 7 days of age) +### Grade 4: <2.500 x 10e9/L +### Grade 3: 2.5 to 3.999 x 10e9/L +### Grade 2: 4 to 5.499 x 10e9/L +### Grade 1: 5.5 to 6.999 x 10e9/L + +expected_wbcd_daids_le7d <- tibble::tribble( + ~ATOXDSCL, ~AVAL, ~AVALU, ~ATOXGRL, ~TESTNUM, + "WBC, Decreased", 2.49, "MM3", NA, 12, + "WBC, Decreased", 2.49, "10^9/L", "4", 13, + "WBC, Decreased", 2.5, "10^9/L", "3", 14, + "WBC, Decreased", 3.99, "10^9/L", "3", 15, + "WBC, Decreased", 4, "10^9/L", "2", 16, + "WBC, Decreased", 5.49, "10^9/L", "2", 17, + "WBC, Decreased", 5.5, "10^9/L", "1", 18, + "WBC, Decreased", 6.99, "10^9/L", "1", 19, + "WBC, Decreased", 7, "10^9/L", "0", 20, +) %>% + mutate( + BRTHDT = lubridate::ymd("2023-07-01"), + LBDT = lubridate::ymd("2023-07-08") + ) + +expected_wbcd_daids_noage <- expected_wbcd_daids_gt7d %>% + filter(TESTNUM %in% c(10, 11)) %>% + mutate( + BRTHDT = if_else(TESTNUM == 10, NA, BRTHDT), + LBDT = if_else(TESTNUM == 11, NA, LBDT), + ATOXGRL = NA_character_, + TESTNUM = TESTNUM + 11 + ) + +expected_wbcd_daids <- expected_wbcd_daids_gt7d %>% + bind_rows( + expected_wbcd_daids_le7d, + expected_wbcd_daids_noage + ) + +input_wbcd_daids <- expected_wbcd_daids %>% + select(-ATOXGRL) + +## Test 123: DAIDS White blood cell decreased ---- +test_that("derive_var_atoxgr Test 123: DAIDS White blood cell decreased", { + actual_wbcd_daids <- derive_var_atoxgr_dir( + input_wbcd_daids, + new_var = ATOXGRL, + meta_criteria = atoxgr_criteria_daids, + tox_description_var = ATOXDSCL, + criteria_direction = "L", + get_unit_expr = AVALU + ) + + expect_dfs_equal( + base = expected_wbcd_daids, + compare = actual_wbcd_daids, + keys = c("TESTNUM") + ) +}) diff --git a/tests/testthat/test-derive_var_basetype.R b/tests/testthat/test-derive_var_basetype.R index e59fc3db8f..0c27a79137 100644 --- a/tests/testthat/test-derive_var_basetype.R +++ b/tests/testthat/test-derive_var_basetype.R @@ -1,6 +1,6 @@ # derive_var_basetype ---- -## Test 1: deprecation warning if function is called ---- -test_that("derive_var_basetype Test 1: deprecation warning if function is called", { +## Test 1: deprecation error if function is called ---- +test_that("derive_var_basetype Test 1: deprecation error if function is called", { input <- tibble::tribble( ~USUBJID, ~EPOCH, ~PARAMCD, ~ASEQ, ~AVAL, "P01", "RUN-IN", "PARAM01", 1, 10.0, @@ -41,7 +41,7 @@ test_that("derive_var_basetype Test 1: deprecation warning if function is called "P02", "OPEN-LABEL", "PARAM01", 4, 11.4, "OPEN-LABEL", "P02", "OPEN-LABEL", "PARAM01", 5, 10.8, "OPEN-LABEL", ) - expect_warning( + expect_error( derive_var_basetype( dataset = input, basetypes = rlang::exprs( @@ -50,124 +50,6 @@ test_that("derive_var_basetype Test 1: deprecation warning if function is called "OPEN-LABEL" = EPOCH == "OPEN-LABEL" ) ), - class = "lifecycle_warning_deprecated" + class = "lifecycle_error_deprecated" ) }) - -## Test 2: records are duplicated across different `BASETYPE` values ---- -test_that("derive_var_basetype Test 2: records are duplicated across different `BASETYPE` values", { - input <- tibble::tribble( - ~USUBJID, ~EPOCH, ~PARAMCD, ~ASEQ, ~AVAL, - "P01", "RUN-IN", "PARAM01", 1, 10.0, - "P01", "RUN-IN", "PARAM01", 2, 9.8, - "P01", "DOUBLE-BLIND", "PARAM01", 3, 9.2, - "P01", "DOUBLE-BLIND", "PARAM01", 4, 10.1, - "P01", "OPEN-LABEL", "PARAM01", 5, 10.4, - "P01", "OPEN-LABEL", "PARAM01", 6, 9.9, - "P02", "RUN-IN", "PARAM01", 1, 12.1, - "P02", "DOUBLE-BLIND", "PARAM01", 2, 10.2, - "P02", "DOUBLE-BLIND", "PARAM01", 3, 10.8, - "P02", "OPEN-LABEL", "PARAM01", 4, 11.4, - "P02", "OPEN-LABEL", "PARAM01", 5, 10.8 - ) - expect_output <- tibble::tribble( - ~USUBJID, ~EPOCH, ~PARAMCD, ~ASEQ, ~AVAL, ~BASETYPE, - "P01", "RUN-IN", "PARAM01", 1, 10.0, "RUN-IN", - "P01", "RUN-IN", "PARAM01", 2, 9.8, "RUN-IN", - "P01", "DOUBLE-BLIND", "PARAM01", 3, 9.2, "RUN-IN", - "P01", "DOUBLE-BLIND", "PARAM01", 4, 10.1, "RUN-IN", - "P01", "OPEN-LABEL", "PARAM01", 5, 10.4, "RUN-IN", - "P01", "OPEN-LABEL", "PARAM01", 6, 9.9, "RUN-IN", - "P01", "DOUBLE-BLIND", "PARAM01", 3, 9.2, "DOUBLE-BLIND", - "P01", "DOUBLE-BLIND", "PARAM01", 4, 10.1, "DOUBLE-BLIND", - "P01", "OPEN-LABEL", "PARAM01", 5, 10.4, "DOUBLE-BLIND", - "P01", "OPEN-LABEL", "PARAM01", 6, 9.9, "DOUBLE-BLIND", - "P01", "OPEN-LABEL", "PARAM01", 5, 10.4, "OPEN-LABEL", - "P01", "OPEN-LABEL", "PARAM01", 6, 9.9, "OPEN-LABEL", - "P02", "RUN-IN", "PARAM01", 1, 12.1, "RUN-IN", - "P02", "DOUBLE-BLIND", "PARAM01", 2, 10.2, "RUN-IN", - "P02", "DOUBLE-BLIND", "PARAM01", 3, 10.8, "RUN-IN", - "P02", "OPEN-LABEL", "PARAM01", 4, 11.4, "RUN-IN", - "P02", "OPEN-LABEL", "PARAM01", 5, 10.8, "RUN-IN", - "P02", "DOUBLE-BLIND", "PARAM01", 2, 10.2, "DOUBLE-BLIND", - "P02", "DOUBLE-BLIND", "PARAM01", 3, 10.8, "DOUBLE-BLIND", - "P02", "OPEN-LABEL", "PARAM01", 4, 11.4, "DOUBLE-BLIND", - "P02", "OPEN-LABEL", "PARAM01", 5, 10.8, "DOUBLE-BLIND", - "P02", "OPEN-LABEL", "PARAM01", 4, 11.4, "OPEN-LABEL", - "P02", "OPEN-LABEL", "PARAM01", 5, 10.8, "OPEN-LABEL", - ) - actual_output <- suppress_warning( - derive_var_basetype( - dataset = input, - basetypes = rlang::exprs( - "RUN-IN" = EPOCH %in% c("RUN-IN", "STABILIZATION", "DOUBLE-BLIND", "OPEN-LABEL"), - "DOUBLE-BLIND" = EPOCH %in% c("DOUBLE-BLIND", "OPEN-LABEL"), - "OPEN-LABEL" = EPOCH == "OPEN-LABEL" - ) - ), - regexpr = "was deprecated" - ) - - expect_dfs_equal(actual_output, expect_output, keys = c("USUBJID", "BASETYPE", "PARAMCD", "ASEQ")) -}) - -## Test 3: records that do not match any condition are kept ---- -test_that("derive_var_basetype Test 3: records that do not match any condition are kept", { - input <- tibble::tribble( - ~USUBJID, ~EPOCH, ~PARAMCD, ~ASEQ, ~AVAL, - "P01", "SCREENING", "PARAM01", 1, 10.2, - "P01", "RUN-IN", "PARAM01", 2, 10.0, - "P01", "RUN-IN", "PARAM01", 3, 9.8, - "P01", "DOUBLE-BLIND", "PARAM01", 4, 9.2, - "P01", "DOUBLE-BLIND", "PARAM01", 5, 10.1, - "P01", "OPEN-LABEL", "PARAM01", 6, 10.4, - "P01", "OPEN-LABEL", "PARAM01", 7, 9.9, - "P02", "SCREENING", "PARAM01", 1, 12.2, - "P02", "RUN-IN", "PARAM01", 2, 12.1, - "P02", "DOUBLE-BLIND", "PARAM01", 3, 10.2, - "P02", "DOUBLE-BLIND", "PARAM01", 4, 10.8, - "P02", "OPEN-LABEL", "PARAM01", 5, 11.4, - "P02", "OPEN-LABEL", "PARAM01", 6, 10.8 - ) - expect_output <- tibble::tribble( - ~USUBJID, ~EPOCH, ~PARAMCD, ~ASEQ, ~AVAL, ~BASETYPE, - "P01", "SCREENING", "PARAM01", 1, 10.2, NA, - "P01", "RUN-IN", "PARAM01", 2, 10.0, "RUN-IN", - "P01", "RUN-IN", "PARAM01", 3, 9.8, "RUN-IN", - "P01", "DOUBLE-BLIND", "PARAM01", 4, 9.2, "RUN-IN", - "P01", "DOUBLE-BLIND", "PARAM01", 5, 10.1, "RUN-IN", - "P01", "OPEN-LABEL", "PARAM01", 6, 10.4, "RUN-IN", - "P01", "OPEN-LABEL", "PARAM01", 7, 9.9, "RUN-IN", - "P01", "DOUBLE-BLIND", "PARAM01", 4, 9.2, "DOUBLE-BLIND", - "P01", "DOUBLE-BLIND", "PARAM01", 5, 10.1, "DOUBLE-BLIND", - "P01", "OPEN-LABEL", "PARAM01", 6, 10.4, "DOUBLE-BLIND", - "P01", "OPEN-LABEL", "PARAM01", 7, 9.9, "DOUBLE-BLIND", - "P01", "OPEN-LABEL", "PARAM01", 6, 10.4, "OPEN-LABEL", - "P01", "OPEN-LABEL", "PARAM01", 7, 9.9, "OPEN-LABEL", - "P02", "SCREENING", "PARAM01", 1, 12.2, NA, - "P02", "RUN-IN", "PARAM01", 2, 12.1, "RUN-IN", - "P02", "DOUBLE-BLIND", "PARAM01", 3, 10.2, "RUN-IN", - "P02", "DOUBLE-BLIND", "PARAM01", 4, 10.8, "RUN-IN", - "P02", "OPEN-LABEL", "PARAM01", 5, 11.4, "RUN-IN", - "P02", "OPEN-LABEL", "PARAM01", 6, 10.8, "RUN-IN", - "P02", "DOUBLE-BLIND", "PARAM01", 3, 10.2, "DOUBLE-BLIND", - "P02", "DOUBLE-BLIND", "PARAM01", 4, 10.8, "DOUBLE-BLIND", - "P02", "OPEN-LABEL", "PARAM01", 5, 11.4, "DOUBLE-BLIND", - "P02", "OPEN-LABEL", "PARAM01", 6, 10.8, "DOUBLE-BLIND", - "P02", "OPEN-LABEL", "PARAM01", 5, 11.4, "OPEN-LABEL", - "P02", "OPEN-LABEL", "PARAM01", 6, 10.8, "OPEN-LABEL", - ) - actual_output <- suppress_warning( - derive_var_basetype( - dataset = input, - basetypes = rlang::exprs( - "RUN-IN" = EPOCH %in% c("RUN-IN", "STABILIZATION", "DOUBLE-BLIND", "OPEN-LABEL"), - "DOUBLE-BLIND" = EPOCH %in% c("DOUBLE-BLIND", "OPEN-LABEL"), - "OPEN-LABEL" = EPOCH == "OPEN-LABEL" - ) - ), - regexpr = "was deprecated" - ) - - expect_dfs_equal(actual_output, expect_output, keys = c("USUBJID", "BASETYPE", "PARAMCD", "ASEQ")) -}) diff --git a/tests/testthat/test-derive_var_dthcaus.R b/tests/testthat/test-derive_var_dthcaus.R index 59ca13651d..387564b0bf 100644 --- a/tests/testthat/test-derive_var_dthcaus.R +++ b/tests/testthat/test-derive_var_dthcaus.R @@ -135,8 +135,8 @@ test_that("derive_var_dthcaus Test 3: `dthcaus` handles symbols and string liter expect_dfs_equal(expected_output, actual_output, keys = "USUBJID") }) -## Test 4: DTHCAUS and traceability vars are added from AE and DS ---- -test_that("derive_var_dthcaus Test 4: DTHCAUS and traceability vars are added from AE and DS", { +## Test 4: traceability variables are added from AE and DS ---- +test_that("derive_var_dthcaus Test 4: traceability variables are added from AE and DS", { adsl <- tibble::tribble( ~STUDYID, ~USUBJID, "TEST01", "PAT01", @@ -175,7 +175,7 @@ test_that("derive_var_dthcaus Test 4: DTHCAUS and traceability vars are added fr date = AEDTHDT, mode = "first", dthcaus = AEDECOD, - traceability_vars = exprs(DTHDOM = "AE", DTHSEQ = AESEQ) + set_values_to = exprs(DTHDOM = "AE", DTHSEQ = AESEQ) ) src_ds <- dthcaus_source( @@ -184,7 +184,7 @@ test_that("derive_var_dthcaus Test 4: DTHCAUS and traceability vars are added fr date = DSSTDT, mode = "first", dthcaus = DSTERM, - traceability_vars = exprs(DTHDOM = "DS", DTHSEQ = DSSEQ) + set_values_to = exprs(DTHDOM = "DS", DTHSEQ = DSSEQ) ) expected_output <- tibble::tribble( @@ -244,7 +244,7 @@ test_that("derive_var_dthcaus Test 5: DTHCAUS/traceabiity are added from 2 input date = AEDTHDT, mode = "first", dthcaus = AEDECOD, - traceability_vars = exprs(DTHDOM = "AE", DTHSEQ = AESEQ) + set_values_to = exprs(DTHDOM = "AE", DTHSEQ = AESEQ) ) src_ds <- dthcaus_source( @@ -253,7 +253,7 @@ test_that("derive_var_dthcaus Test 5: DTHCAUS/traceabiity are added from 2 input date = DSSTDT, mode = "first", dthcaus = DSTERM, - traceability_vars = exprs(DTHDOM = "DS", DTHSEQ = DSSEQ) + set_values_to = exprs(DTHDOM = "DS", DTHSEQ = DSSEQ) ) expected_output <- tibble::tribble( @@ -413,3 +413,27 @@ test_that("derive_var_dthcaus Test 8: `dataset` is sorted using the `order` para expect_dfs_equal(expected_output, actual_output, keys = "USUBJID") }) + +## Test 9: returns a warning when traceability_vars is used ---- +test_that("dthcaus_source Test 9: returns a warning when traceability_vars is used", { + ae <- tibble::tribble( + ~STUDYID, ~USUBJID, ~AESEQ, ~AEDECOD, ~AEOUT, ~AEDTHDTC, + "TEST01", "PAT01", 12, "SUDDEN DEATH", "FATAL", "2021-04-04" + ) + + expect_warning( + src_ae <- dthcaus_source( + dataset_name = "ae", + filter = AEOUT == "FATAL", + date = AEDTHDT, + mode = "first", + dthcaus = AEDECOD, + traceability_vars = exprs(DTHDOM = "AE", DTHSEQ = AESEQ), + set_values_to = exprs( + DTHDOM = "AE", + DTHSEQ = AESEQ + ) + ), + class = "lifecycle_warning_deprecated" + ) +}) diff --git a/tests/testthat/test-derive_var_extreme_date.R b/tests/testthat/test-derive_var_extreme_date.R index de0317ad8c..98f99618f5 100644 --- a/tests/testthat/test-derive_var_extreme_date.R +++ b/tests/testthat/test-derive_var_extreme_date.R @@ -126,7 +126,7 @@ test_that("derive_var_extreme_dtm Test 4: `LSTALVDTM` and traceability variables ae_start <- date_source( dataset_name = "ae", date = convert_dtc_to_dtm(AESTDTC), - traceability_vars = exprs( + set_values_to = exprs( LALVDOM = "AE", LALVSEQ = AESEQ, LALVVAR = "AESTDTC" @@ -136,7 +136,7 @@ test_that("derive_var_extreme_dtm Test 4: `LSTALVDTM` and traceability variables ae_end <- date_source( dataset_name = "ae", date = AEENDTM, - traceability_vars = exprs( + set_values_to = exprs( LALVDOM = "AE", LALVSEQ = AESEQ, LALVVAR = "AEENDTC" @@ -146,7 +146,7 @@ test_that("derive_var_extreme_dtm Test 4: `LSTALVDTM` and traceability variables adsl_trtdate <- date_source( dataset_name = "adsl", date = TRTEDTM, - traceability_vars = exprs( + set_values_to = exprs( LALVDOM = "ADSL", LALVSEQ = NA_integer_, LALVVAR = "TRTEDTM" @@ -157,7 +157,7 @@ test_that("derive_var_extreme_dtm Test 4: `LSTALVDTM` and traceability variables dataset_name = "adsl", date = DTHDT, filter = nchar(DTHDTC) >= 10, - traceability_vars = exprs( + set_values_to = exprs( LALVDOM = "ADSL", LALVSEQ = NA_integer_, LALVVAR = "DTHDTC" @@ -192,7 +192,7 @@ test_that("derive_var_extreme_dtm Test 5: error is issued if `--DTC` variable is ae_start <- date_source( dataset_name = "ae", date = AESTDTC, - traceability_vars = exprs( + set_values_to = exprs( LALVDOM = "AE", LALVSEQ = AESEQ, LALVVAR = "AESTDTC" @@ -210,3 +210,19 @@ test_that("derive_var_extreme_dtm Test 5: error is issued if `--DTC` variable is regexp = "`AESTDTC` in dataset `ae` is not a date or datetime variable but is a character vector" # nolint ) }) + +## Test 6: Returns a warning when traceability_vars is assigned ---- +test_that("derive_var_extreme_dtm Test 6: Returns a warning when traceability_vars is assigned", { + expect_warning( + ae_start <- date_source( + dataset_name = "ae", + date = convert_dtc_to_dtm(AESTDTC), + traceability_vars = exprs( + LALVDOM = "AE", + LALVSEQ = AESEQ, + LALVVAR = "AESTDTC" + ) + ), + class = "lifecycle_warning_deprecated" + ) +}) diff --git a/tests/testthat/test-derive_var_extreme_flag.R b/tests/testthat/test-derive_var_extreme_flag.R index bc7cf0561c..c918c3d146 100644 --- a/tests/testthat/test-derive_var_extreme_flag.R +++ b/tests/testthat/test-derive_var_extreme_flag.R @@ -1,33 +1,6 @@ -input_worst_flag <- tibble::tribble( - ~STUDYID, ~USUBJID, ~PARAMCD, ~AVISIT, ~ADT, ~AVAL, - "TEST01", "PAT01", "PARAM01", "BASELINE", as.Date("2021-04-27"), 15.0, - "TEST01", "PAT01", "PARAM01", "BASELINE", as.Date("2021-04-25"), 14.0, - "TEST01", "PAT01", "PARAM01", "BASELINE", as.Date("2021-04-23"), 15.0, - "TEST01", "PAT01", "PARAM01", "WEEK 1", as.Date("2021-04-27"), 10.0, - "TEST01", "PAT01", "PARAM01", "WEEK 2", as.Date("2021-04-30"), 12.0, - "TEST01", "PAT02", "PARAM01", "SCREENING", as.Date("2021-04-27"), 15.0, - "TEST01", "PAT02", "PARAM01", "BASELINE", as.Date("2021-04-25"), 14.0, - "TEST01", "PAT02", "PARAM01", "BASELINE", as.Date("2021-04-23"), 15.0, - "TEST01", "PAT02", "PARAM01", "WEEK 1", as.Date("2021-04-27"), 10.0, - "TEST01", "PAT02", "PARAM01", "WEEK 2", as.Date("2021-04-30"), 12.0, - "TEST01", "PAT01", "PARAM02", "SCREENING", as.Date("2021-04-27"), 15.0, - "TEST01", "PAT01", "PARAM02", "SCREENING", as.Date("2021-04-25"), 14.0, - "TEST01", "PAT01", "PARAM02", "SCREENING", as.Date("2021-04-23"), 15.0, - "TEST01", "PAT01", "PARAM02", "BASELINE", as.Date("2021-04-27"), 10.0, - "TEST01", "PAT01", "PARAM02", "WEEK 2", as.Date("2021-04-30"), 12.0, - "TEST01", "PAT02", "PARAM02", "SCREENING", as.Date("2021-04-27"), 15.0, - "TEST01", "PAT02", "PARAM02", "BASELINE", as.Date("2021-04-25"), 14.0, - "TEST01", "PAT02", "PARAM02", "WEEK 1", as.Date("2021-04-23"), 15.0, - "TEST01", "PAT02", "PARAM02", "WEEK 1", as.Date("2021-04-27"), 10.0, - "TEST01", "PAT02", "PARAM02", "BASELINE", as.Date("2021-04-30"), 12.0, - "TEST01", "PAT02", "PARAM03", "SCREENING", as.Date("2021-04-27"), 15.0, - "TEST01", "PAT02", "PARAM03", "BASELINE", as.Date("2021-04-25"), 14.0, - "TEST01", "PAT02", "PARAM03", "WEEK 1", as.Date("2021-04-23"), 15.0, - "TEST01", "PAT02", "PARAM03", "WEEK 1", as.Date("2021-04-27"), 10.0, - "TEST01", "PAT02", "PARAM03", "BASELINE", as.Date("2021-04-30"), 12.0 -) - -test_that("first observation for each group is flagged", { +# derive_var_extreme_flag ---- +## Test 1: first observation for each group is flagged ---- +test_that("derive_var_extreme_flag Test 1: first observation for each group is flagged", { input <- tibble::tribble( ~USUBJID, ~AVISITN, ~AVAL, 1, 1, 12, @@ -54,7 +27,8 @@ test_that("first observation for each group is flagged", { ) }) -test_that("last observation for each group is flagged", { +## Test 2: last observation for each group is flagged ---- +test_that("derive_var_extreme_flag Test 2: last observation for each group is flagged", { input <- tibble::tribble( ~USUBJID, ~AVISITN, ~AVAL, 1, 1, 12, @@ -81,19 +55,153 @@ test_that("last observation for each group is flagged", { ) }) -## Test 7: An error is issued if `derive_var_worst_flag()` is called ---- -test_that("deprecation Test 7: An error is issued if Derive worst flag is called", { - expect_error( - derive_var_worst_flag( - input_worst_flag, - by_vars = exprs(USUBJID, PARAMCD, AVISIT), - order = exprs(desc(ADT)), - new_var = WORSTFL, - param_var = PARAMCD, - analysis_var = AVAL, - worst_high = c("PARAM01", "PARAM03"), - worst_low = "PARAM02" - ), - class = "lifecycle_error_deprecated" + +test_flag_all <- tibble::tribble( + ~STUDYID, ~USUBJID, ~ADTM, ~AVISITN, ~BASETYPE, ~PARAM, + "TEST01", "PAT01", "2020-02-01T12:00", 1, "ontrt", "test1", + "TEST01", "PAT01", "2020-02-01T12:00", 1, "ontrt", "test2", + "TEST01", "PAT01", "2020-02-01T12:01", 1, "ontrt", "test1", + "TEST01", "PAT01", "2020-02-01T13:00", 1, "ontrt", "test1", + "TEST01", "PAT01", "2020-02-01T13:00", 1, "ontrt", "test2" +) + +## Test 3: flag_all = FALSE when mode is first ---- +test_that("derive_var_extreme_flag Test 3: flag_all = FALSE when mode is first", { + expected_output <- test_flag_all %>% + mutate(FIRSTFL = c("Y", NA, NA, NA, NA)) + + actual_output <- derive_var_extreme_flag( + test_flag_all, + by_vars = exprs(STUDYID, USUBJID, BASETYPE, AVISITN), + order = exprs(ADTM), + new_var = FIRSTFL, + mode = "first", + check_type = "none", + flag_all = FALSE + ) + + expect_dfs_equal( + expected_output, + actual_output, + keys = c("STUDYID", "USUBJID", "BASETYPE", "AVISITN", "ADTM", "FIRSTFL", "PARAM") + ) +}) + +## Test 4: flag_all = TRUE when mode is first ---- +test_that("derive_var_extreme_flag Test 4: flag_all = TRUE when mode is first", { + expected_output <- test_flag_all %>% + mutate(FIRSTFL = c("Y", "Y", NA, NA, NA)) + + actual_output <- derive_var_extreme_flag( + test_flag_all, + by_vars = exprs(STUDYID, USUBJID, BASETYPE, AVISITN), + order = exprs(ADTM), + new_var = FIRSTFL, + mode = "first", + flag_all = TRUE + ) + + expect_dfs_equal( + expected_output, + actual_output, + keys = c("STUDYID", "USUBJID", "BASETYPE", "AVISITN", "ADTM", "FIRSTFL", "PARAM") + ) +}) + +## Test 5: flag_all = FALSE when mode is last ---- +test_that("derive_var_extreme_flag Test 5: flag_all = FALSE when mode is last", { + expected_output <- test_flag_all %>% + mutate(LASTFL = c(NA, NA, NA, NA, "Y")) + + actual_output <- derive_var_extreme_flag( + test_flag_all, + by_vars = exprs(STUDYID, USUBJID, BASETYPE, AVISITN), + order = exprs(ADTM), + new_var = LASTFL, + mode = "last", + check_type = "none", + flag_all = FALSE + ) + + expect_dfs_equal( + expected_output, + actual_output, + keys = c("STUDYID", "USUBJID", "BASETYPE", "AVISITN", "ADTM", "LASTFL", "PARAM") + ) +}) + +## Test 6: flag_all = TRUE when mode is last ---- +test_that("derive_var_extreme_flag Test 6: flag_all = TRUE when mode is last", { + expected_output <- test_flag_all %>% + mutate(LASTFL = c(NA, NA, NA, "Y", "Y")) + + actual_output <- derive_var_extreme_flag( + test_flag_all, + by_vars = exprs(STUDYID, USUBJID, BASETYPE, AVISITN), + order = exprs(ADTM), + new_var = LASTFL, + mode = "last", + flag_all = TRUE + ) + + expect_dfs_equal( + expected_output, + actual_output, + keys = c("STUDYID", "USUBJID", "BASETYPE", "AVISITN", "ADTM", "LASTFL", "PARAM") + ) +}) +## Test 7: case for missing order variables ---- +test_that("derive_var_extreme_flag Test 7: case for missing order variables", { + input <- tibble::tribble( + ~USUBJID, ~AVISITN, ~AVAL, + 1, NA, 12, + 1, 3, 9, + 2, 2, 42, + 3, 3, 14, + 3, 3, 10 + ) + + expected_output <- input %>% mutate(firstfl = c(NA, "Y", "Y", "Y", NA)) + + actual_output <- derive_var_extreme_flag( + input, + by_vars = exprs(USUBJID), + order = exprs(AVISITN, desc(AVAL)), + new_var = firstfl, + mode = "first" + ) + + expect_dfs_equal( + base = expected_output, + compare = actual_output, + keys = c("USUBJID", "AVISITN", "AVAL") + ) +}) +## Test 8: additional case for missing order variables ---- +test_that("derive_var_extreme_flag Test 8: additional case for missing order variables", { + input <- tibble::tribble( + ~USUBJID, ~AVISITN, ~AVAL, + 1, 1, 12, + 1, 3, 9, + 2, 2, 42, + 3, 3, 14, + 3, 3, 10, + 3, 3, NA + ) + + expected_output <- input %>% mutate(lastfl = c(NA, "Y", "Y", NA, NA, "Y")) + + actual_output <- derive_var_extreme_flag( + input, + by_vars = exprs(USUBJID), + order = exprs(AVISITN, desc(AVAL)), + new_var = lastfl, + mode = "last" + ) + + expect_dfs_equal( + base = expected_output, + compare = actual_output, + keys = c("USUBJID", "AVISITN", "AVAL") ) }) diff --git a/tests/testthat/test-derive_var_last_dose_amt.R b/tests/testthat/test-derive_var_last_dose_amt.R index 96edd7e5f1..1e4424bf6f 100644 --- a/tests/testthat/test-derive_var_last_dose_amt.R +++ b/tests/testthat/test-derive_var_last_dose_amt.R @@ -28,14 +28,14 @@ input_ex <- tibble::tribble( ) # derive_var_last_dose_amt ---- -## Test 1: works as expected ---- -test_that("derive_var_last_dose_amt Test 1: works as expected", { +## Test 1: works as expected and returns an error message---- +test_that("derive_var_last_dose_amt Test 1: works as expected and returns an error message", { expected_output <- mutate( input_ae, LDOSE = c(10, 10, 10, NA, 0, NA, NA) ) - suppressWarnings( - res <- derive_var_last_dose_amt( + expect_error( + derive_var_last_dose_amt( input_ae, input_ex, filter_ex = (EXDOSE > 0) | (EXDOSE == 0 & EXTRT == "placebo"), @@ -46,33 +46,7 @@ test_that("derive_var_last_dose_amt Test 1: works as expected", { dose_var = EXDOSE, single_dose_condition = (EXSTDTC == EXENDTC), traceability_vars = NULL - ) + ), + class = "lifecycle_error_deprecated" ) - expect_dfs_equal(expected_output, res, keys = c("STUDYID", "USUBJID", "AESEQ", "AESTDTC")) -}) - -## Test 2: returns traceability vars ---- -test_that("derive_var_last_dose_amt Test 2: returns traceability vars", { - expected_output <- mutate( - input_ae, - LDOSEDOM = c("EX", "EX", "EX", NA, "EX", NA, NA), - LDOSESEQ = c(1, 2, 3, NA, 2, NA, NA), - LDOSEVAR = c("EXSTDTC", "EXSTDTC", "EXSTDTC", NA, "EXSTDTC", NA, NA), - LDOSE = c(10, 10, 10, NA, 0, NA, NA) - ) - suppressWarnings( - res <- derive_var_last_dose_amt( - input_ae, - input_ex, - filter_ex = (EXDOSE > 0) | (EXDOSE == 0 & EXTRT == "placebo"), - by_vars = exprs(STUDYID, USUBJID), - dose_date = EXENDT, - analysis_date = AESTDT, - new_var = LDOSE, - dose_var = EXDOSE, - single_dose_condition = (EXSTDTC == EXENDTC), - traceability_vars = exprs(LDOSEDOM = "EX", LDOSESEQ = EXSEQ, LDOSEVAR = "EXSTDTC") - ) - ) - expect_dfs_equal(expected_output, res, keys = c("STUDYID", "USUBJID", "AESEQ", "AESTDTC")) }) diff --git a/tests/testthat/test-derive_var_last_dose_date.R b/tests/testthat/test-derive_var_last_dose_date.R index 380b4267ae..a755a02e79 100644 --- a/tests/testthat/test-derive_var_last_dose_date.R +++ b/tests/testthat/test-derive_var_last_dose_date.R @@ -24,8 +24,8 @@ input_ex <- tibble::tribble( mutate(EXSTDT = as.Date(EXSTDTC), EXENDT = as.Date(EXENDTC)) # derive_var_last_dose_date ---- -## Test 1: works as expected output_datetime = FALSE ---- -test_that("derive_var_last_dose_date Test 1: works as expected output_datetime = FALSE", { +## Test 1: returns an error when the function is called ---- +test_that("derive_var_last_dose_date Test 1: returns an error when the function is called", { expected_output <- tibble::tribble( ~STUDYID, ~USUBJID, ~AESEQ, ~AESTDTC, ~LDOSEDTM, "my_study", "subject1", 1, "2020-01-02", "2020-01-01", @@ -40,8 +40,8 @@ test_that("derive_var_last_dose_date Test 1: works as expected output_datetime = LDOSEDTM = as.Date(LDOSEDTM), AESTDT = ymd(AESTDTC) ) - suppressWarnings( - res <- derive_var_last_dose_date( + expect_error( + derive_var_last_dose_date( input_ae, input_ex, filter_ex = (EXDOSE > 0) | (EXDOSE == 0 & EXTRT == "placebo"), @@ -52,76 +52,7 @@ test_that("derive_var_last_dose_date Test 1: works as expected output_datetime = single_dose_condition = (EXSTDTC == EXENDTC), output_datetime = FALSE, traceability_vars = NULL - ) - ) - expect_dfs_equal(expected_output, res, keys = c("STUDYID", "USUBJID", "AESEQ", "AESTDTC")) -}) - -## Test 2: works as expected with output_datetime = TRUE ---- -test_that("derive_var_last_dose_date Test 2: works as expected with output_datetime = TRUE", { - expected_output <- tibble::tribble( - ~STUDYID, ~USUBJID, ~AESEQ, ~AESTDTC, ~LDOSEDTM, - "my_study", "subject1", 1, "2020-01-02", "2020-01-01 00:00:00", - "my_study", "subject1", 2, "2020-08-31", "2020-08-29 00:00:00", - "my_study", "subject1", 3, "2020-10-10", "2020-09-02 00:00:00", - "my_study", "subject2", 1, "2019-05-15", NA_character_, - "my_study", "subject2", 2, "2020-02-20", "2020-01-20 00:00:00", - "my_study", "subject3", 1, "2020-03-02", NA_character_, - "my_study", "subject4", 1, "2020-11-02", NA_character_ - ) %>% - mutate( - LDOSEDTM = as.POSIXct(as.character(LDOSEDTM), tz = "UTC"), - AESTDT = ymd(AESTDTC) - ) - suppressWarnings( - res <- derive_var_last_dose_date( - input_ae, - input_ex, - filter_ex = (EXDOSE > 0) | (EXDOSE == 0 & EXTRT == "placebo"), - by_vars = exprs(STUDYID, USUBJID), - dose_date = EXENDT, - analysis_date = AESTDT, - new_var = LDOSEDTM, - output_datetime = TRUE, - single_dose_condition = (EXSTDTC == EXENDTC), - traceability_vars = NULL - ) - ) - expect_dfs_equal(expected_output, res, keys = c("STUDYID", "USUBJID", "AESEQ", "AESTDTC")) -}) - -## Test 3: returns traceability vars ---- -test_that("derive_var_last_dose_date Test 3: returns traceability vars", { - expected_output <- tibble::tribble( - ~STUDYID, ~USUBJID, ~AESEQ, ~AESTDTC, ~LDOSEDTM, - "my_study", "subject1", 1, "2020-01-02", "2020-01-01 00:00:00", - "my_study", "subject1", 2, "2020-08-31", "2020-08-29 00:00:00", - "my_study", "subject1", 3, "2020-10-10", "2020-09-02 00:00:00", - "my_study", "subject2", 1, "2019-05-15", NA_character_, - "my_study", "subject2", 2, "2020-02-20", "2020-01-20 00:00:00", - "my_study", "subject3", 1, "2020-03-02", NA_character_, - "my_study", "subject4", 1, "2020-11-02", NA_character_ - ) %>% - mutate( - LDOSEDTM = as.POSIXct(as.character(LDOSEDTM), tz = "UTC"), - LDOSEDOM = c("EX", "EX", "EX", NA, "EX", NA, NA), - LDOSESEQ = c(1, 2, 3, NA, 2, NA, NA), - LDOSEVAR = c("EXENDTC", "EXENDTC", "EXENDTC", NA, "EXENDTC", NA, NA), - AESTDT = ymd(AESTDTC) - ) - suppressWarnings( - res <- derive_var_last_dose_date( - input_ae, - input_ex, - filter_ex = (EXDOSE > 0) | (EXDOSE == 0 & EXTRT == "placebo"), - by_vars = exprs(STUDYID, USUBJID), - dose_date = EXENDT, - analysis_date = AESTDT, - new_var = LDOSEDTM, - single_dose_condition = (EXSTDTC == EXENDTC), - output_datetime = TRUE, - traceability_vars = exprs(LDOSEDOM = "EX", LDOSESEQ = EXSEQ, LDOSEVAR = "EXENDTC") - ) + ), + class = "lifecycle_error_deprecated" ) - expect_dfs_equal(expected_output, res, keys = c("STUDYID", "USUBJID", "AESEQ", "AESTDTC")) }) diff --git a/tests/testthat/test-derive_var_last_dose_grp.R b/tests/testthat/test-derive_var_last_dose_grp.R index 380b4267ae..6e930756e1 100644 --- a/tests/testthat/test-derive_var_last_dose_grp.R +++ b/tests/testthat/test-derive_var_last_dose_grp.R @@ -40,8 +40,8 @@ test_that("derive_var_last_dose_date Test 1: works as expected output_datetime = LDOSEDTM = as.Date(LDOSEDTM), AESTDT = ymd(AESTDTC) ) - suppressWarnings( - res <- derive_var_last_dose_date( + expect_error( + derive_var_last_dose_date( input_ae, input_ex, filter_ex = (EXDOSE > 0) | (EXDOSE == 0 & EXTRT == "placebo"), @@ -52,76 +52,7 @@ test_that("derive_var_last_dose_date Test 1: works as expected output_datetime = single_dose_condition = (EXSTDTC == EXENDTC), output_datetime = FALSE, traceability_vars = NULL - ) - ) - expect_dfs_equal(expected_output, res, keys = c("STUDYID", "USUBJID", "AESEQ", "AESTDTC")) -}) - -## Test 2: works as expected with output_datetime = TRUE ---- -test_that("derive_var_last_dose_date Test 2: works as expected with output_datetime = TRUE", { - expected_output <- tibble::tribble( - ~STUDYID, ~USUBJID, ~AESEQ, ~AESTDTC, ~LDOSEDTM, - "my_study", "subject1", 1, "2020-01-02", "2020-01-01 00:00:00", - "my_study", "subject1", 2, "2020-08-31", "2020-08-29 00:00:00", - "my_study", "subject1", 3, "2020-10-10", "2020-09-02 00:00:00", - "my_study", "subject2", 1, "2019-05-15", NA_character_, - "my_study", "subject2", 2, "2020-02-20", "2020-01-20 00:00:00", - "my_study", "subject3", 1, "2020-03-02", NA_character_, - "my_study", "subject4", 1, "2020-11-02", NA_character_ - ) %>% - mutate( - LDOSEDTM = as.POSIXct(as.character(LDOSEDTM), tz = "UTC"), - AESTDT = ymd(AESTDTC) - ) - suppressWarnings( - res <- derive_var_last_dose_date( - input_ae, - input_ex, - filter_ex = (EXDOSE > 0) | (EXDOSE == 0 & EXTRT == "placebo"), - by_vars = exprs(STUDYID, USUBJID), - dose_date = EXENDT, - analysis_date = AESTDT, - new_var = LDOSEDTM, - output_datetime = TRUE, - single_dose_condition = (EXSTDTC == EXENDTC), - traceability_vars = NULL - ) - ) - expect_dfs_equal(expected_output, res, keys = c("STUDYID", "USUBJID", "AESEQ", "AESTDTC")) -}) - -## Test 3: returns traceability vars ---- -test_that("derive_var_last_dose_date Test 3: returns traceability vars", { - expected_output <- tibble::tribble( - ~STUDYID, ~USUBJID, ~AESEQ, ~AESTDTC, ~LDOSEDTM, - "my_study", "subject1", 1, "2020-01-02", "2020-01-01 00:00:00", - "my_study", "subject1", 2, "2020-08-31", "2020-08-29 00:00:00", - "my_study", "subject1", 3, "2020-10-10", "2020-09-02 00:00:00", - "my_study", "subject2", 1, "2019-05-15", NA_character_, - "my_study", "subject2", 2, "2020-02-20", "2020-01-20 00:00:00", - "my_study", "subject3", 1, "2020-03-02", NA_character_, - "my_study", "subject4", 1, "2020-11-02", NA_character_ - ) %>% - mutate( - LDOSEDTM = as.POSIXct(as.character(LDOSEDTM), tz = "UTC"), - LDOSEDOM = c("EX", "EX", "EX", NA, "EX", NA, NA), - LDOSESEQ = c(1, 2, 3, NA, 2, NA, NA), - LDOSEVAR = c("EXENDTC", "EXENDTC", "EXENDTC", NA, "EXENDTC", NA, NA), - AESTDT = ymd(AESTDTC) - ) - suppressWarnings( - res <- derive_var_last_dose_date( - input_ae, - input_ex, - filter_ex = (EXDOSE > 0) | (EXDOSE == 0 & EXTRT == "placebo"), - by_vars = exprs(STUDYID, USUBJID), - dose_date = EXENDT, - analysis_date = AESTDT, - new_var = LDOSEDTM, - single_dose_condition = (EXSTDTC == EXENDTC), - output_datetime = TRUE, - traceability_vars = exprs(LDOSEDOM = "EX", LDOSESEQ = EXSEQ, LDOSEVAR = "EXENDTC") - ) + ), + class = "lifecycle_error_deprecated" ) - expect_dfs_equal(expected_output, res, keys = c("STUDYID", "USUBJID", "AESEQ", "AESTDTC")) }) diff --git a/tests/testthat/test-derive_var_ontrtfl.R b/tests/testthat/test-derive_var_ontrtfl.R index 324e8915bc..8167e41554 100644 --- a/tests/testthat/test-derive_var_ontrtfl.R +++ b/tests/testthat/test-derive_var_ontrtfl.R @@ -334,7 +334,7 @@ test_that("derive_var_ontrtfl Test 12: end_date is NA and start_date < ref_start ref_start_date = TRTSDT, ref_end_date = TRTEDT, ref_end_window = 60, - span_period = "Y" + span_period = TRUE ) expect_dfs_equal( @@ -363,7 +363,7 @@ test_that("derive_var_ontrtfl Test 13: end_date is NA and start_date < ref_start ref_start_date = TRTSDT, ref_end_date = TRTEDT, ref_end_window = 60, - span_period = "Y" + span_period = TRUE ) expect_dfs_equal( @@ -393,7 +393,7 @@ test_that("derive_var_ontrtfl Test 14: start_date < ref_start_date and end_date end_date = AENDT, ref_start_date = AP01SDT, ref_end_date = AP01EDT, - span_period = "Y" + span_period = TRUE ) expect_dfs_equal( @@ -402,3 +402,73 @@ test_that("derive_var_ontrtfl Test 14: start_date < ref_start_date and end_date keys = c("STUDYID", "USUBJID", "ASTDT") ) }) + + +## Test 15: if trt end date is missing, the obs may still be flagged ---- +test_that("derive_var_ontrtfl Test 15: if trt end date is missing, the obs may still be flagged", { # nolint + adcm <- tibble::tribble( + ~USUBJID, ~ASTDT, ~TRTSDT, ~TRTEDT, ~AENDT, + "P01", ymd("2018-03-15"), ymd("2019-01-01"), NA, ymd("2022-12-01"), + "P02", ymd("2020-04-30"), ymd("2019-01-01"), NA, ymd("2022-03-15"), + "P03", ymd("2020-04-30"), ymd("2019-01-01"), NA, NA, + "P04", ymd("2020-04-30"), NA, NA, NA + ) %>% + as.data.frame() + + # all flags should be "Y" because span_period flag is TRUE + expect_snapshot( + derive_var_ontrtfl( + adcm, + start_date = ASTDT, + end_date = AENDT, + ref_start_date = TRTSDT, + ref_end_date = TRTEDT, + span_period = TRUE + ) + ) + + # first obs started before treatment, and it should NOT be flagged + expect_snapshot( + derive_var_ontrtfl( + adcm, + start_date = ASTDT, + end_date = AENDT, + ref_start_date = TRTSDT, + ref_end_date = TRTEDT + ) + ) +}) + +## Test 16: expected deprecation messaging ---- +test_that("derive_var_ontrtfl Test 16: expected deprecation messaging", { # nolint + adcm <- tibble::tribble( + ~USUBJID, ~ASTDT, ~TRTSDT, ~TRTEDT, ~AENDT, + "P01", ymd("2018-03-15"), ymd("2019-01-01"), NA, ymd("2022-12-01"), + "P02", ymd("2020-04-30"), ymd("2019-01-01"), NA, ymd("2022-03-15"), + "P03", ymd("2020-04-30"), ymd("2019-01-01"), NA, NA, + ) + + # all flags should be "Y" because span_period flag is TRUE + lifecycle::expect_deprecated( + derive_var_ontrtfl( + adcm, + start_date = ASTDT, + end_date = AENDT, + ref_start_date = TRTSDT, + ref_end_date = TRTEDT, + span_period = "Y" + ) + ) + + # first obs started before treatment, and it should NOT be flagged + lifecycle::expect_deprecated( + derive_var_ontrtfl( + adcm, + start_date = ASTDT, + end_date = AENDT, + ref_start_date = TRTSDT, + ref_end_date = TRTEDT, + span_period = NULL + ) + ) +}) diff --git a/tests/testthat/test-derive_var_shift.R b/tests/testthat/test-derive_var_shift.R index e5dcdb733a..bebbabb1f4 100644 --- a/tests/testthat/test-derive_var_shift.R +++ b/tests/testthat/test-derive_var_shift.R @@ -1,4 +1,7 @@ -test_that("Shift based on character variables", { +# derive_var_shift ---- + +## Test 1: Shift based on character variables ---- +test_that("derive_var_shift Test 1: Shift based on character variables", { input <- tibble::tribble( ~USUBJID, ~PARAMCD, ~AVAL, ~ABLFL, ~BNRIND, ~ANRIND, "P01", "ALB", 33, "Y", "LOW", "LOW", @@ -28,7 +31,8 @@ test_that("Shift based on character variables", { }) -test_that("Shift based on character variables with missing values", { +## Test 2: Shift based on character variables with missing values ---- +test_that("derive_var_shift Test 2: Shift based on character variables with missing values", { input <- tibble::tribble( ~USUBJID, ~PARAMCD, ~AVAL, ~ABLFL, ~BNRIND, ~ANRIND, "P01", "ALB", 33, "Y", "LOW", "LOW", @@ -60,7 +64,8 @@ test_that("Shift based on character variables with missing values", { }) -test_that("Shift based on numeric variables with missing values", { +## Test 3: Shift based on numeric variables with missing values ---- +test_that("derive_var_shift Test 3: Shift based on numeric variables with missing values", { input <- tibble::tribble( ~USUBJID, ~PARAMCD, ~AVAL, ~ABLFL, ~BASE, "P01", "ALB", 33.1, "Y", 33.1, @@ -91,7 +96,8 @@ test_that("Shift based on numeric variables with missing values", { ) }) -test_that("Shift with user-specified na_val and sep_val", { +## Test 4: Shift with user-specified missing_value and sep_val ---- +test_that("derive_var_shift Test 4: Shift with user-specified missing_value and sep_val", { input <- tibble::tribble( ~USUBJID, ~PARAMCD, ~AVAL, ~ABLFL, ~BNRIND, ~ANRIND, "P01", "ALB", 33, "Y", "LOW", "LOW", @@ -117,9 +123,34 @@ test_that("Shift with user-specified na_val and sep_val", { new_var = SHIFT1, from_var = BNRIND, to_var = ANRIND, - na_val = "MISSING", + missing_value = "MISSING", sep_val = " - " ), expected_output ) }) + +## Test 5: Test deprecation warning of na_val argument ---- +test_that("derive_var_shift Test 5: Test deprecation warning of na_val argument", { + input <- tibble::tribble( + ~USUBJID, ~PARAMCD, ~AVAL, ~ABLFL, ~BNRIND, ~ANRIND, + "P01", "ALB", 33, "Y", "LOW", "LOW", + "P01", "ALB", 38, NA, "LOW", "NORMAL", + "P01", "ALB", NA, NA, "LOW", NA, + "P02", "ALB", NA, "Y", NA, NA, + "P02", "ALB", 49, NA, NA, "HIGH", + "P02", "SODIUM", 147, "Y", "HIGH", "HIGH" + ) + + expect_warning( + derive_var_shift( + input, + new_var = SHIFT1, + from_var = BNRIND, + to_var = ANRIND, + na_val = "MISSING", + sep_val = " - " + ), + class = "lifecycle_warning_deprecated" + ) +}) diff --git a/tests/testthat/test-derive_vars_aage.R b/tests/testthat/test-derive_vars_aage.R index 0116ae8c83..23248b082c 100644 --- a/tests/testthat/test-derive_vars_aage.R +++ b/tests/testthat/test-derive_vars_aage.R @@ -10,9 +10,21 @@ test_that("derive_vars_aage Test 1: duration and unit variable are added", { expect_dfs_equal(derive_vars_aage(input), expected_output, keys = c("BRTHDT", "RANDDT")) }) +## Test 2: duration and unit variable are added ---- +test_that("derive_vars_aage Test 2: Error is thrown when age_unit is not proper unit", { + input <- tibble::tribble( + ~BRTHDT, ~RANDDT, + ymd("1999-09-09"), ymd("2020-02-20") + ) + expect_error( + derive_vars_aage(input, age_unit = "centuries"), + "`age_unit` must be one of 'years', 'months', 'weeks', 'days', 'hours', 'minutes' or 'seconds' but is 'centuries'" # nolint + ) +}) + # derive_var_age_years ---- -## Test 2: derive_var_age_years works as expected when AGEU exists ---- -test_that("derive_var_age_years Test 2: derive_var_age_years works as expected when AGEU exists", { +## Test 3: derive_var_age_years works as expected when AGEU exists ---- +test_that("derive_var_age_years Test 3: derive_var_age_years works as expected when AGEU exists", { input <- tibble::tibble( AGE = c(12, 24, 36, 48, 60), AGEU = c("months", "months", "months", "months", "months") @@ -26,9 +38,9 @@ test_that("derive_var_age_years Test 2: derive_var_age_years works as expected w expect_dfs_equal(derive_var_age_years(input, AGE, new_var = AAGE), expected_output, keys = "AGE") }) -## Test 3: derive_var_age_years works as expected when AGEU doesn't exist and +## Test 4: derive_var_age_years works as expected when AGEU doesn't exist and ## `age_unit` is used ---- -test_that("derive_var_age_years Test 3: derive_var_age_years works as expected +test_that("derive_var_age_years Test 4: derive_var_age_years works as expected when AGEU doesn't exist and `age_unit` is used", { input <- tibble::tibble(AGE = c(12, 24, 36, 48, 60)) @@ -43,8 +55,8 @@ test_that("derive_var_age_years Test 3: derive_var_age_years works as expected ) }) -## Test 4: Error is thrown when age_unit is not proper unit ---- -test_that("derive_var_age_years Test 4: Error is thrown when age_unit is not proper unit", { +## Test 5: Error is thrown when age_unit is not proper unit ---- +test_that("derive_var_age_years Test 5: Error is thrown when age_unit is not proper unit", { input <- data.frame(AGE = c(12, 24, 36, 48)) expect_error( derive_var_age_years(input, AGE, age_unit = "month", new_var = AAGE), @@ -52,17 +64,17 @@ test_that("derive_var_age_years Test 4: Error is thrown when age_unit is not pro ) }) -## Test 5: Error is issued if age_unit is missing ---- -test_that("derive_var_age_years Test 5: Error is issued if age_unit is missing", { +## Test 6: Error is issued if age_unit is missing ---- +test_that("derive_var_age_years Test 6: Error is issued if age_unit is missing", { input <- data.frame(AGE = c(12, 24, 36, 48)) expect_error( derive_var_age_years(input, AGE, new_var = AAGE) ) }) -## Test 6: Warning is issued if age_unit is not null, but the 'unit' variable +## Test 7: Warning is issued if age_unit is not null, but the 'unit' variable ## corresponding to age_var stores more than one unique value. ---- -test_that("derive_var_age_years Test 6: Warning is issued if age_unit is not +test_that("derive_var_age_years Test 7: Warning is issued if age_unit is not null, but the 'unit' variable corresponding to age_var stores more than one unique value.", { input <- tibble::tribble( @@ -81,8 +93,8 @@ test_that("derive_var_age_years Test 6: Warning is issued if age_unit is not }) -## Test 7: Error is issued if age_unit consists of more than one unique value. ---- -test_that("derive_var_age_years Test 7: Error is issued if age_unit consists of +## Test 8: Error is issued if age_unit consists of more than one unique value. ---- +test_that("derive_var_age_years Test 8: Error is issued if age_unit consists of more than one unique value.", { input <- tibble::tribble( ~AGE, ~AGEU, @@ -99,10 +111,10 @@ test_that("derive_var_age_years Test 7: Error is issued if age_unit consists of ) }) -## Test 8: The 'unit' variable corresponding to age_var will be considered as +## Test 9: The 'unit' variable corresponding to age_var will be considered as ## storing one unique unit, if values differ only by case, i.e. ## 'months', 'Months', 'MONTHS' considered same unit, etc. ---- -test_that("derive_var_age_years Test 8: The 'unit' variable corresponding to +test_that("derive_var_age_years Test 9: The 'unit' variable corresponding to age_var will be considered as storing one unique unit, if values differ only by case, i.e. 'months', 'Months', 'MONTHS' considered same unit, etc.", { @@ -135,10 +147,10 @@ test_that("derive_var_age_years Test 8: The 'unit' variable corresponding to ) }) -## Test 9: Warning is issued if age_unit is not null, but the 'unit' variable -## corresponding to age_var stores one unique unit that is not -## equivalent to age_unit. ---- -test_that("derive_var_age_years Test 9: Warning is issued if age_unit is not +## Test 10: Warning is issued if age_unit is not null, but the 'unit' variable +## corresponding to age_var stores one unique unit that is not +## equivalent to age_unit. ---- +test_that("derive_var_age_years Test 10: Warning is issued if age_unit is not null, but the 'unit' variable corresponding to age_var stores one unique unit that is not equivalent to age_unit.", { input <- tibble::tribble( diff --git a/tests/testthat/test-derive_vars_dy.R b/tests/testthat/test-derive_vars_dy.R index e619550f76..db246d5737 100644 --- a/tests/testthat/test-derive_vars_dy.R +++ b/tests/testthat/test-derive_vars_dy.R @@ -285,3 +285,35 @@ test_that("derive_vars_dy Test 9: Single named --DT input when ref date is --DTM keys = c("STUDYID", "USUBJID") ) }) + +## Test 10: no error if input with variable end with `_temp` ---- +test_that("derive_vars_dy Test 10: no error if input with variable end with `_temp`", { + datain <- tibble::tribble( + ~STUDYID, ~USUBJID, ~TRTSDTM, ~ASTDT, ~test_temp, + "TEST01", "PAT01", "2014-01-17T23:59:59", "2014-01-18", "test" + ) %>% + mutate( + TRTSDTM = lubridate::as_datetime(TRTSDTM), + ASTDT = lubridate::ymd(ASTDT) + ) + + expected_output <- tibble::tribble( + ~STUDYID, ~USUBJID, ~TRTSDTM, ~ASTDT, ~test_temp, ~ASTDY, + "TEST01", "PAT01", "2014-01-17T23:59:59", "2014-01-18", "test", 2 + ) %>% + mutate( + TRTSDTM = lubridate::as_datetime(TRTSDTM), + ASTDT = lubridate::ymd(ASTDT) + ) + + actual_output <- derive_vars_dy(datain, + reference_date = TRTSDTM, + source_vars = exprs(ASTDT) + ) + + expect_dfs_equal( + expected_output, + actual_output, + keys = c("STUDYID", "USUBJID") + ) +}) diff --git a/tests/testthat/test-derive_vars_last_dose.R b/tests/testthat/test-derive_vars_last_dose.R index e602aa20f6..2a99d04734 100644 --- a/tests/testthat/test-derive_vars_last_dose.R +++ b/tests/testthat/test-derive_vars_last_dose.R @@ -25,8 +25,8 @@ input_ex <- tibble::tribble( mutate(EXSTDT = as.Date(EXSTDTC), EXENDT = as.Date(EXENDTC)) # derive_vars_last_dose ---- -## Test 1: function works as expected ---- -test_that("derive_vars_last_dose Test 1: function works as expected", { +## Test 1: function works as expected and returns an error message ---- +test_that("derive_vars_last_dose Test 1: function works as expected and returns an error message", { expected_output <- mutate( input_ae, EXSTDT = as.Date(c("2020-01-01", "2020-08-29", "2020-09-02", NA, "2020-01-20", NA, NA)), @@ -35,188 +35,7 @@ test_that("derive_vars_last_dose Test 1: function works as expected", { EXDOSE = c(10, 10, 10, NA, 0, NA, NA), EXTRT = c("treatment", "treatment", "treatment", NA, "placebo", NA, NA) ) - suppressWarnings( - res <- derive_vars_last_dose( - input_ae, - input_ex, - filter_ex = (EXDOSE > 0) | (EXDOSE == 0 & EXTRT == "placebo"), - by_vars = exprs(STUDYID, USUBJID), - dose_date = EXENDT, - new_vars = exprs(EXDOSE, EXTRT, EXSEQ, EXENDT, EXSTDT), - analysis_date = AESTDT, - single_dose_condition = (EXSTDTC == EXENDTC), - traceability_vars = NULL - ) - ) - expect_dfs_equal(expected_output, res, keys = c("STUDYID", "USUBJID", "AESEQ", "AESTDTC")) -}) - -## Test 2: function checks validity of start and end dose inputs ---- -test_that("derive_vars_last_dose Test 2: function checks validity of start and end dose inputs", { - input_ex_wrong <- bind_rows( - input_ex, - tibble::tribble( - ~STUDYID, ~USUBJID, ~EXSTDTC, ~EXENDTC, ~EXSEQ, ~EXDOSE, ~EXTRT, - "my_study", "subject4", "2020-11-05", "2020-11-06", 1, 10, "treatment" - ) %>% - mutate( - EXENDT = ymd(EXENDTC), - EXSTDT = ymd(EXSTDTC) - ) - ) - - expect_warning( - derive_vars_last_dose( - input_ae, - input_ex_wrong, - filter_ex = (EXDOSE > 0) | (EXDOSE == 0 & EXTRT == "placebo"), - by_vars = exprs(STUDYID, USUBJID), - dose_date = EXENDT, - analysis_date = AESTDT, - single_dose_condition = (EXSTDTC == EXENDTC), - traceability_vars = NULL - ), - class = "lifecycle_warning_deprecated" - ) -}) - -## Test 3: function returns traceability vars ---- -test_that("derive_vars_last_dose Test 3: function returns traceability vars", { - expected_output <- mutate( - input_ae, - EXSTDTC = c("2020-01-01", "2020-08-29", "2020-09-02", NA, "2020-01-20", NA, NA), - EXENDTC = c("2020-01-01", "2020-08-29", "2020-09-02", NA, "2020-01-20", NA, NA), - EXENDT = ymd(EXENDTC), - EXSTDT = ymd(EXSTDTC), - EXSEQ = c(1, 2, 3, NA, 2, NA, NA), - EXDOSE = c(10, 10, 10, NA, 0, NA, NA), - EXTRT = c("treatment", "treatment", "treatment", NA, "placebo", NA, NA), - LDOSEDOM = c("EX", "EX", "EX", NA, "EX", NA, NA), - LDOSESEQ = c(1, 2, 3, NA, 2, NA, NA), - LDOSEVAR = c("EXSTDTC", "EXSTDTC", "EXSTDTC", NA, "EXSTDTC", NA, NA) - ) - suppressWarnings( - res <- derive_vars_last_dose( - input_ae, - input_ex, - filter_ex = (EXDOSE > 0) | (EXDOSE == 0 & EXTRT == "placebo"), - by_vars = exprs(STUDYID, USUBJID), - dose_date = EXENDT, - analysis_date = AESTDT, - single_dose_condition = (EXSTDTC == EXENDTC), - new_vars = exprs(EXSTDTC, EXENDTC, EXENDT, EXSTDT, EXSEQ, EXDOSE, EXTRT), - traceability_vars = exprs(LDOSEDOM = "EX", LDOSESEQ = EXSEQ, LDOSEVAR = "EXSTDTC") - ) - ) - expect_dfs_equal(expected_output, res, keys = c("STUDYID", "USUBJID", "AESEQ", "AESTDTC")) -}) - -## Test 4: function errors when multiple doses are on same date ---- -test_that("derive_vars_last_dose Test 4: function errors when multiple doses are on same date", { - input_ex_dup <- bind_rows( - input_ex, - tibble::tribble( - ~STUDYID, ~USUBJID, ~EXSTDTC, ~EXENDTC, ~EXSEQ, ~EXDOSE, ~EXTRT, - "my_study", "subject2", "2020-01-20", "2020-01-20", 3, 0, "placebo" - ) %>% - mutate( - EXSTDT = ymd(EXSTDTC), - EXENDT = ymd(EXENDTC) - ) - ) - - # single_dose_condition not part of `derive_vars_joined()` - expect_warning( - suppress_warning( - derive_vars_last_dose( - input_ae, - input_ex_dup, - filter_ex = (EXDOSE > 0) | (EXDOSE == 0 & EXTRT == "placebo"), - by_vars = exprs(STUDYID, USUBJID), - dose_date = EXENDT, - analysis_date = AESTDT, - single_dose_condition = (EXSTDTC == EXENDTC), - traceability_vars = NULL - ), - regexpr = paste( - "Dataset contains duplicate records with respect to", - "`STUDYID`, `USUBJID`, `tmp_obs_nr_1` and `EXENDT`" - ) - ), - class = "lifecycle_warning_deprecated" - ) -}) - -## Test 5: multiple doses on same date - dose_id supplied ---- -test_that("derive_vars_last_dose Test 5: multiple doses on same date - dose_id supplied", { - input_ex_dup <- bind_rows( - input_ex, - tibble::tribble( - ~STUDYID, ~USUBJID, ~EXSTDTC, ~EXENDTC, ~EXSEQ, ~EXDOSE, ~EXTRT, - "my_study", "subject2", "2020-01-20", "2020-01-20", 3, 0, "placebo" - ) %>% mutate( - EXSTDT = ymd(EXSTDTC), - EXENDT = ymd(EXENDTC) - ) - ) - - expected_output <- mutate( - input_ae, - EXSTDT = ymd(c("2020-01-01", "2020-08-29", "2020-09-02", NA, "2020-01-20", NA, NA)), - EXENDT = ymd(c("2020-01-01", "2020-08-29", "2020-09-02", NA, "2020-01-20", NA, NA)), - EXSEQ = c(1, 2, 3, NA, 3, NA, NA), - EXDOSE = c(10, 10, 10, NA, 0, NA, NA), - EXTRT = c("treatment", "treatment", "treatment", NA, "placebo", NA, NA) - ) - suppressWarnings( - res <- derive_vars_last_dose( - input_ae, - input_ex_dup, - filter_ex = (EXDOSE > 0) | (EXDOSE == 0 & EXTRT == "placebo"), - by_vars = exprs(STUDYID, USUBJID), - dose_date = EXENDT, - dose_id = exprs(EXSEQ), - new_vars = exprs(EXDOSE, EXTRT, EXSEQ, EXSTDT, EXENDT), - analysis_date = AESTDT, - single_dose_condition = (EXSTDTC == EXENDTC), - traceability_vars = NULL - ) - ) - expect_dfs_equal(expected_output, res, keys = c("STUDYID", "USUBJID", "AESEQ", "AESTDTC")) -}) - -## Test 6: error is issued if same variable is found in both input datasets ---- -test_that("derive_vars_last_dose Test 6: error is issued if same variable is found in both input datasets", { # nolint - input_ae <- tibble::tribble( - ~STUDYID, ~USUBJID, ~AESEQ, ~EXSTDTC, - "my_study", "subject1", 1, "2020-01-02", - "my_study", "subject1", 2, "2020-08-31", - "my_study", "subject1", 3, "2020-10-10", - "my_study", "subject2", 1, "2019-05-15", - "my_study", "subject2", 2, "2020-02-20", - "my_study", "subject3", 1, "2020-03-02", - "my_study", "subject4", 1, "2020-11-02" - ) %>% - mutate( - EXSTDT = ymd(EXSTDTC) - ) - - input_ex <- tibble::tribble( - ~STUDYID, ~USUBJID, ~EXSTDTC, ~EXENDTC, ~EXSEQ, ~EXDOSE, ~EXTRT, - "my_study", "subject1", "2020-01-01", "2020-01-01", 1, 10, "treatment", - "my_study", "subject1", "2020-08-29", "2020-08-29", 2, 10, "treatment", - "my_study", "subject1", "2020-09-02", "2020-09-02", 3, 10, "treatment", - "my_study", "subject1", "2020-10-20", "2020-10-20", 4, 10, "treatment", - "my_study", "subject2", "2019-05-25", "2019-05-25", 1, 0, "placebo", - "my_study", "subject2", "2020-01-20", "2020-01-20", 2, 0, "placebo", - "my_study", "subject3", "2020-03-15", "2020-03-15", 1, 10, "treatment" - ) %>% - mutate( - EXSTDT = as.Date(EXSTDTC), - EXENDT = as.Date(EXENDTC) - ) - - expect_warning( + expect_error( derive_vars_last_dose( input_ae, input_ex, @@ -224,44 +43,10 @@ test_that("derive_vars_last_dose Test 6: error is issued if same variable is fou by_vars = exprs(STUDYID, USUBJID), dose_date = EXENDT, new_vars = exprs(EXDOSE, EXTRT, EXSEQ, EXENDT, EXSTDT), - analysis_date = EXSTDT, + analysis_date = AESTDT, single_dose_condition = (EXSTDTC == EXENDTC), traceability_vars = NULL ), - class = "lifecycle_warning_deprecated" - ) -}) - -## Test 7: no error is raised when setting `dose_date` to a renamed variable ---- -test_that("derive_vars_last_dose Test 7: no error is raised when setting `dose_date` to a renamed variable", { # nolint - adae <- tibble::tribble( - ~USUBJID, ~AESTDTC, ~AENDTC, ~ASTDT, ~AENDT, ~AEDECOD, - "P01", "2022-01-10", "2022-01-12", ymd("2022-01-10"), ymd("2022-01-12"), "Nausea", - "P02", "2022-01-31", "2022-01-31", ymd("2022-01-31"), ymd("2022-01-31"), "Vomitting", - "P02", "2022-02-02", "2022-02-04", ymd("2022-02-02"), ymd("2022-02-04"), "Vomitting" - ) - - adex <- tibble::tribble( - ~USUBJID, ~EXTRT, ~EXDOSFRQ, ~EXSTDTC, ~EXENDTC, ~ASTDT, ~AENDT, ~ASTDTM, ~AENDTM, - "P01", "Drug A", "QD", "2022-01-09", "2022-01-12", ymd("2022-01-09"), ymd("2022-01-12"), - ymd_hms("2022-01-09 09:30:00"), ymd_hms("2022-01-12 09:30:00"), - "P02", "Drug A", "QD", "2022-02-01", "2022-02-04", ymd("2022-02-01"), ymd("2022-02-04"), - ymd_hms("2022-02-01 10:00:00"), ymd_hms("2022-02-04 10:00:00") - ) - - (adex_single <- create_single_dose_dataset(adex)) - - expect_error( - suppressWarnings( - derive_vars_last_dose( - adae, - adex_single, - by_vars = exprs(USUBJID), - dose_date = EXSTDT, - analysis_date = ASTDT, - new_vars = exprs(EXSTDT = ASTDT) - ) - ), - regexp = "Required variable `EXSTDT` is missing" + class = "lifecycle_error_deprecated" ) }) diff --git a/tests/testthat/test-duplicates.R b/tests/testthat/test-duplicates.R index 13db84313d..d8715d08cb 100644 --- a/tests/testthat/test-duplicates.R +++ b/tests/testthat/test-duplicates.R @@ -1,4 +1,6 @@ -test_that("duplicate records are extracted", { +# extract_duplicate_records ---- +## Test 1: duplicate records are extracted ---- +test_that("extract_duplicate_records Test 1: duplicate records are extracted", { input <- tibble::tribble( ~USUBJID, ~COUNTRY, ~AAGE, "P01", "GER", 22, @@ -16,7 +18,9 @@ test_that("duplicate records are extracted", { ) }) -test_that("dataset of duplicate records can be accessed using `get_duplicates_dataset()`", { +# signal_duplicate_records ---- +## Test 2: dataset of duplicate records can be accessed using `get_duplicates_dataset()` ---- +test_that("signal_duplicate_records Test 2: dataset of duplicate records can be accessed using `get_duplicates_dataset()`", { # nolint input <- tibble::tribble( ~USUBJID, ~COUNTRY, ~AAGE, "P01", "GER", 22, @@ -35,4 +39,6 @@ test_that("dataset of duplicate records can be accessed using `get_duplicates_da ) expect_true(all(expected_ouput == get_duplicates_dataset())) + + expect_snapshot(get_duplicates_dataset()) }) diff --git a/tests/testthat/test-user_utils.R b/tests/testthat/test-user_utils.R index 66a8ed037d..5f6d44b060 100644 --- a/tests/testthat/test-user_utils.R +++ b/tests/testthat/test-user_utils.R @@ -36,6 +36,7 @@ test_that("convert_blanks_to_na Test 3: blank strings are turned into `NA` insid }) +# convert_blanks_to_na.list ---- ## Test 4: `convert_blanks_to_na.list` produces a lists ---- test_that("convert_blanks_to_na.list Test 4: `convert_blanks_to_na.list` produces a lists", { x <- c("", "", "") @@ -45,7 +46,8 @@ test_that("convert_blanks_to_na.list Test 4: `convert_blanks_to_na.list` produce expect_equal(expected_output, actual_output) }) -# Test 5: convert_na_to_blanks Test 5---- +# convert_na_to_blanks ---- +## Test 5: `NA` strings are turned into blank ---- test_that("convert_na_to_blanks Test 5: `NA` strings are turned into blank ", { expect_identical( convert_na_to_blanks(c("a", NA, "b")), @@ -53,7 +55,7 @@ test_that("convert_na_to_blanks Test 5: `NA` strings are turned into blank ", { ) }) -## Test 6: attributes are preserved when converting `NA` to blanks ---- +## Test 6: attributes are preserved when converting `NA` to blanks ---- test_that("convert_na_to_blanks Test 6: attributes are preserved when converting `NA` to blanks", { input <- structure(letters, names = rev(letters), label = "Letters") input[c(1, 9, 23)] <- NA_character_ @@ -63,8 +65,9 @@ test_that("convert_na_to_blanks Test 6: attributes are preserved when converting expect_identical(names(output), rev(letters)) }) +# convert_na_to_blanks.data.frame ---- ## Test 7: `NA` are turned into blank strings inside data frames ---- -test_that("convert_na_to_blanks Test 7: `NA` are turned into blank strings inside data frames", { +test_that("convert_na_to_blanks.data.frame Test 7: `NA` are turned into blank strings inside data frames", { # nolint input <- tibble::tibble( a = structure(c("a", "b", NA, "c"), label = "A"), b = structure(c(1, NA, 21, 9), label = "B"), @@ -99,7 +102,7 @@ test_that("negate_vars Test 9: negate_vars returns list of negated variables", { }) ## Test 10: negate_vars returns NULL if input is NULL ---- -test_that("negate_vars Test 6: negate_vars returns NULL if input is NULL", { +test_that("negate_vars Test 10: negate_vars returns NULL if input is NULL", { expect_identical(negate_vars(NULL), NULL) }) @@ -137,7 +140,7 @@ test_that("print.source Test 13: `source` objects are printed as intended", { "dataset_name: \"ae\"", "filter: NULL", "date: AESTDTC", - "censor: 0L", + "censor: 0", "set_values_to:", " EVENTDESC: \"AE\"", " SRCDOM: \"AE\"", @@ -198,7 +201,8 @@ test_that("print.source Test 15: `source` objects containing `data.frame`", { ) }) -## Test 16 print_named_list ---- +# print_named_list ---- +## Test 16: named list ---- test_that("print_named_list Test 16: named list", { expect_identical( capture.output(print_named_list(list(a = 1, b = 2))), @@ -219,3 +223,13 @@ test_that("print_named_list Test 17: unnamed list", { ) ) }) + +## Test 18: named list with unamed list ---- +test_that("print_named_list Test 18: named list with unamed list", { + expect_snapshot( + print_named_list(list( + list_item = list("Hello World!", expr(universe), list(42)), + another_one = ymd("2020-02-02") + )) + ) +}) diff --git a/vignettes/admiral.Rmd b/vignettes/admiral.Rmd index 7680f72ec4..feee92b05c 100644 --- a/vignettes/admiral.Rmd +++ b/vignettes/admiral.Rmd @@ -26,22 +26,22 @@ for example the following script which creates a (very simple) ADSL dataset. ## Load Packages and Example Datasets -First, we will load our packages and example datasets to help with our `ADSL` creation. The `{dplyr}` and `{lubridate}` packages are `{tidyverse}` packages and used heavily throughout this script. The `{admiral}` package also leverages the `{admiral.test}` package for example SDTM datasets which are from the CDISC Pilot Study. +First, we will load our packages and example datasets to help with our `ADSL` creation. The `{dplyr}` and `{lubridate}` packages are `{tidyverse}` packages and used heavily throughout this script. The `{admiral}` package also leverages the `{pharmaversesdtm}` package for example SDTM datasets which are from the CDISC Pilot Study. ```{r, message=FALSE, warning=FALSE} library(dplyr, warn.conflicts = FALSE) library(lubridate) library(admiral) -library(admiral.test) +library(pharmaversesdtm) # Read in SDTM datasets -data("admiral_dm") -data("admiral_ds") -data("admiral_ex") +data("dm") +data("ds") +data("ex") -dm <- convert_blanks_to_na(admiral_dm) -ds <- convert_blanks_to_na(admiral_ds) -ex <- convert_blanks_to_na(admiral_ex) +dm <- convert_blanks_to_na(dm) +ds <- convert_blanks_to_na(ds) +ex <- convert_blanks_to_na(ex) ``` ## Derive Treatment Variables (`TRT0xP`, `TRT0xA`) {#treatmentvargs} diff --git a/vignettes/adsl.Rmd b/vignettes/adsl.Rmd index 8a3dfe50dd..00ff322785 100644 --- a/vignettes/adsl.Rmd +++ b/vignettes/adsl.Rmd @@ -56,26 +56,26 @@ the environment. This will be a company specific process. Some of the data frames needed may be `DM`, `EX`, `DS`, `AE`, and `LB`. For example purpose, the CDISC Pilot SDTM datasets---which are included in -`{admiral.test}`---are used. +`{pharmaversesdtm}`---are used. ```{r, message=FALSE, warning=FALSE} library(admiral) library(dplyr, warn.conflicts = FALSE) -library(admiral.test) +library(pharmaversesdtm) library(lubridate) library(stringr) -data("admiral_dm") -data("admiral_ds") -data("admiral_ex") -data("admiral_ae") -data("admiral_lb") +data("dm") +data("ds") +data("ex") +data("ae") +data("lb") -dm <- convert_blanks_to_na(admiral_dm) -ds <- convert_blanks_to_na(admiral_ds) -ex <- convert_blanks_to_na(admiral_ex) -ae <- convert_blanks_to_na(admiral_ae) -lb <- convert_blanks_to_na(admiral_lb) +dm <- convert_blanks_to_na(dm) +ds <- convert_blanks_to_na(ds) +ex <- convert_blanks_to_na(ex) +ae <- convert_blanks_to_na(ae) +lb <- convert_blanks_to_na(lb) ``` The `DM` domain is used as the basis for `ADSL`: @@ -275,7 +275,7 @@ adsl <- adsl %>% by_vars = exprs(STUDYID, USUBJID), filter_add = DSCAT == "DISPOSITION EVENT", new_vars = exprs(EOSSTT = format_eosstt(DSDECOD)), - missing_value = exprs(EOSSTT = "ONGOING") + missing_values = exprs(EOSSTT = "ONGOING") ) ``` @@ -433,7 +433,7 @@ study requirement. - `date`: the date of death, - `mode`: `first` or `last` to select the first/last date of death if multiple dates are collected, - `dthcaus`: variable or text used to populate `DTHCAUS`. -- `traceability_vars`: whether the traceability variables need to be added (e.g source domain, +- `set_values_to`: whether the traceability variables need to be added (e.g source domain, sequence, variable) An example call to define the sources would be: @@ -504,7 +504,7 @@ src_ae <- dthcaus_source( date = convert_dtc_to_dtm(AESTDTC, highest_imputation = "M"), mode = "first", dthcaus = AEDECOD, - traceability_vars = exprs(DTHDOM = "AE", DTHSEQ = AESEQ) + set_values_to = exprs(DTHDOM = "AE", DTHSEQ = AESEQ) ) src_ds <- dthcaus_source( @@ -513,7 +513,7 @@ src_ds <- dthcaus_source( date = DSSTDT, mode = "first", dthcaus = DSTERM, - traceability_vars = exprs(DTHDOM = "DS", DTHSEQ = DSSEQ) + set_values_to = exprs(DTHDOM = "DS", DTHSEQ = DSSEQ) ) adsl <- adsl %>% select(-DTHCAUS) %>% # remove it before deriving it again @@ -578,7 +578,7 @@ sources (`date_source()`) are correctly defined. - `dataset_name`: the name of the dataset where to search for date information, - `filter`: the filter to apply on the datasets, - `date`: the date of interest, -- `traceability_vars`: whether the traceability variables need to be added (e.g +- `set_values_to`: whether the traceability variables need to be added (e.g source domain, sequence, variable) An example could be (DTC dates are converted to numeric dates imputing missing @@ -625,28 +625,28 @@ dataset_vignette( ``` Similarly to `dthcaus_source()`, the traceability variables can be added by specifying the -`traceability_vars` argument in `date_source()`. +`set_values_to` argument in `date_source()`. ```{r eval=TRUE} ae_start_date <- date_source( dataset_name = "ae", date = convert_dtc_to_dt(AESTDTC, highest_imputation = "M"), - traceability_vars = exprs(LALVDOM = "AE", LALVSEQ = AESEQ, LALVVAR = "AESTDTC") + set_values_to = exprs(LALVDOM = "AE", LALVSEQ = AESEQ, LALVVAR = "AESTDTC") ) ae_end_date <- date_source( dataset_name = "ae", date = convert_dtc_to_dt(AEENDTC, highest_imputation = "M"), - traceability_vars = exprs(LALVDOM = "AE", LALVSEQ = AESEQ, LALVVAR = "AEENDTC") + set_values_to = exprs(LALVDOM = "AE", LALVSEQ = AESEQ, LALVVAR = "AEENDTC") ) lb_date <- date_source( dataset_name = "lb", date = convert_dtc_to_dt(LBDTC, highest_imputation = "M"), - traceability_vars = exprs(LALVDOM = "LB", LALVSEQ = LBSEQ, LALVVAR = "LBDTC") + set_values_to = exprs(LALVDOM = "LB", LALVSEQ = LBSEQ, LALVVAR = "LBDTC") ) trt_end_date <- date_source( dataset_name = "adsl", date = TRTEDTM, - traceability_vars = exprs(LALVDOM = "ADSL", LALVSEQ = NA_integer_, LALVVAR = "TRTEDTM") + set_values_to = exprs(LALVDOM = "ADSL", LALVSEQ = NA_integer_, LALVVAR = "TRTEDTM") ) adsl <- adsl %>% diff --git a/vignettes/bds_exposure.Rmd b/vignettes/bds_exposure.Rmd index 3d55b3925d..0258e1fc8a 100644 --- a/vignettes/bds_exposure.Rmd +++ b/vignettes/bds_exposure.Rmd @@ -52,21 +52,21 @@ To start, all data frames needed for the creation of `ADEX` should be read into the environment. This will be a company specific process. Some of the data frames needed may be `EX` and `ADSL`. -For example purpose, the CDISC Pilot SDTM and ADaM datasets---which are included in `{admiral.test}`---are used. +For example purpose, the CDISC Pilot SDTM and ADaM datasets---which are included in `{pharmaversesdtm}`---are used. ```{r message=FALSE} library(admiral) library(dplyr, warn.conflicts = FALSE) -library(admiral.test) +library(pharmaversesdtm) library(lubridate) library(stringr) library(tibble) data("admiral_adsl") -data("admiral_ex") +data("ex") adsl <- admiral_adsl -ex <- convert_blanks_to_na(admiral_ex) +ex <- convert_blanks_to_na(ex) ``` ```{r echo=FALSE} ex <- filter(ex, USUBJID %in% c("01-701-1015", "01-701-1023", "01-703-1086", "01-703-1096", "01-707-1037", "01-716-1024")) diff --git a/vignettes/bds_finding.Rmd b/vignettes/bds_finding.Rmd index e0aeaba5e2..ed8e715ece 100644 --- a/vignettes/bds_finding.Rmd +++ b/vignettes/bds_finding.Rmd @@ -55,21 +55,21 @@ To start, all data frames needed for the creation of `ADVS` should be read into the environment. This will be a company specific process. Some of the data frames needed may be `VS` and `ADSL`. -For example purpose, the CDISC Pilot SDTM and ADaM datasets---which are included in `{admiral.test}`---are used. +For example purpose, the CDISC Pilot SDTM and ADaM datasets---which are included in `{pharmaversesdtm}`---are used. ```{r message=FALSE} library(admiral) library(dplyr, warn.conflicts = FALSE) -library(admiral.test) +library(pharmaversesdtm) library(lubridate) library(stringr) library(tibble) data("admiral_adsl") -data("admiral_vs") +data("vs") adsl <- admiral_adsl -vs <- convert_blanks_to_na(admiral_vs) +vs <- convert_blanks_to_na(vs) ``` ```{r echo=FALSE} vs <- filter(vs, USUBJID %in% c("01-701-1015", "01-701-1023", "01-703-1086", "01-703-1096", "01-707-1037", "01-716-1024")) @@ -305,8 +305,8 @@ dataset_vignette( ) ``` -Likewise, function call below, to create parameter `Body Surface Area` and -`Body Mass Index` for `ADVS` domain. +Likewise, function call below, to create parameter `Body Surface Area` (BSA) and +`Body Mass Index` (BMI) for `ADVS` domain. Note that if height is collected only once use `constant_by_vars` to specify the subject-level variable to merge on. Otherwise BSA and BMI are only calculated for visits where both are collected. ```{r eval=TRUE} advs <- derive_param_bsa( @@ -315,7 +315,8 @@ advs <- derive_param_bsa( method = "Mosteller", set_values_to = exprs(PARAMCD = "BSA"), get_unit_expr = VSSTRESU, - filter = VSSTAT != "NOT DONE" | is.na(VSSTAT) + filter = VSSTAT != "NOT DONE" | is.na(VSSTAT), + constant_by_vars = exprs(USUBJID) ) advs <- derive_param_bmi( @@ -323,7 +324,8 @@ advs <- derive_param_bmi( by_vars = exprs(STUDYID, USUBJID, !!!adsl_vars, VISIT, VISITNUM, ADT, ADY, VSTPT, VSTPTNUM), set_values_to = exprs(PARAMCD = "BMI"), get_unit_expr = VSSTRESU, - filter = VSSTAT != "NOT DONE" | is.na(VSSTAT) + filter = VSSTAT != "NOT DONE" | is.na(VSSTAT), + constant_by_vars = exprs(USUBJID) ) ``` @@ -525,7 +527,7 @@ advs <- derive_var_ontrtfl( end_date = AENDT, ref_start_date = AP01SDT, ref_end_date = AP01EDT, - span_period = "Y" + span_period = TRUE ) ``` ```{r, eval=TRUE, echo=FALSE} @@ -928,7 +930,7 @@ advs_ex1 <- advs %>% by_vars = exprs(STUDYID, USUBJID, PARAMCD), order = exprs(ADT, AVISITN, ATPTN, AVAL), mode = "last", - filter = (4 < AVISITN & AVISITN <= 12 & ANL01FL == "Y"), + filter_add = (4 < AVISITN & AVISITN <= 12 & ANL01FL == "Y"), set_values_to = exprs( AVISIT = "End of Treatment", AVISITN = 99, @@ -957,7 +959,7 @@ advs_ex1 <- advs %>% by_vars = exprs(STUDYID, USUBJID, PARAMCD), order = exprs(AVAL, ADT, AVISITN, ATPTN), mode = "first", - filter = (4 < AVISITN & AVISITN <= 12 & ANL01FL == "Y" & !is.na(AVAL)), + filter_add = (4 < AVISITN & AVISITN <= 12 & ANL01FL == "Y" & !is.na(AVAL)), set_values_to = exprs( AVISIT = "Minimum on Treatment", AVISITN = 98, @@ -1016,8 +1018,8 @@ advs_ex3 <- derive_param_computed( advs, by_vars = exprs(USUBJID, VISIT, ATPT), parameters = c("SYSBP", "DIABP"), - analysis_value = (AVAL.SYSBP - AVAL.DIABP) / 3 + AVAL.DIABP, set_values_to = exprs( + AVAL = (AVAL.SYSBP - AVAL.DIABP) / 3 + AVAL.DIABP, PARAMCD = "MAP2", PARAM = "Mean Arterial Pressure 2 (mmHg)" ) diff --git a/vignettes/bds_tte.Rmd b/vignettes/bds_tte.Rmd index 72b2452194..5456fa0b2c 100644 --- a/vignettes/bds_tte.Rmd +++ b/vignettes/bds_tte.Rmd @@ -36,7 +36,7 @@ The examples of this vignette require the following packages. ```{r, warning=FALSE, message=FALSE} library(admiral) library(dplyr, warn.conflicts = FALSE) -library(admiral.test) +library(pharmaversesdtm) ``` ```{r, warning=FALSE, message=FALSE, include=FALSE} @@ -58,13 +58,13 @@ To start, all datasets needed for the creation of the time-to-event dataset should be read into the environment. This will be a company specific process. For example purpose, the ADSL dataset---which is included -in `{admiral}`---and the SDTM datasets from `{admiral.test}` are used. +in `{admiral}`---and the SDTM datasets from `{pharmaversesdtm}` are used. ```{r} -data("admiral_ae") +data("ae") data("admiral_adsl") -ae <- convert_blanks_to_na(admiral_ae) +ae <- convert_blanks_to_na(ae) adsl <- admiral_adsl ``` diff --git a/vignettes/generic.Rmd b/vignettes/generic.Rmd index b25515905b..61d6f43d06 100644 --- a/vignettes/generic.Rmd +++ b/vignettes/generic.Rmd @@ -41,23 +41,23 @@ shown within each function page. The examples in this vignette require the following packages. -For example purpose, the SDTM datasets from `{admiral.test}` are used. +For example purpose, the SDTM datasets from `{pharmaversesdtm}` are used. ```{r, warning=FALSE, message=FALSE} library(admiral) -library(admiral.test) +library(pharmaversesdtm) library(dplyr, warn.conflicts = FALSE) library(stringr) library(tibble) -data("admiral_dm") -data("admiral_ds") -data("admiral_ex") -data("admiral_ae") -dm <- convert_blanks_to_na(admiral_dm) -ds <- convert_blanks_to_na(admiral_ds) -ex <- convert_blanks_to_na(admiral_ex) -ae <- convert_blanks_to_na(admiral_ae) +data("dm") +data("ds") +data("ex") +data("ae") +dm <- convert_blanks_to_na(dm) +ds <- convert_blanks_to_na(ds) +ex <- convert_blanks_to_na(ex) +ae <- convert_blanks_to_na(ae) ``` ```{r echo=FALSE} # Filter test patients and make more realistic and interesting for the examples diff --git a/vignettes/higher_order.Rmd b/vignettes/higher_order.Rmd index 348cde971b..db73719473 100644 --- a/vignettes/higher_order.Rmd +++ b/vignettes/higher_order.Rmd @@ -39,19 +39,19 @@ derivation may vary depending on the slice. The examples of this vignette require the following packages. For example purpose, the ADSL dataset---which is included -in `{admiral}`---and the SDTM datasets from `{admiral.test}` are used. +in `{admiral}`---and the SDTM datasets from `{pharmaversesdtm}` are used. ```{r, warning=FALSE, message=FALSE} library(admiral) -library(admiral.test) +library(pharmaversesdtm) library(dplyr, warn.conflicts = FALSE) data("admiral_adsl") -data("admiral_ae") -data("admiral_vs") +data("ae") +data("vs") adsl <- admiral_adsl -ae <- convert_blanks_to_na(admiral_ae) -vs <- convert_blanks_to_na(admiral_vs) +ae <- convert_blanks_to_na(ae) +vs <- convert_blanks_to_na(vs) ``` ```{r echo=FALSE} adsl <- filter(adsl, USUBJID %in% c("01-701-1111", "01-705-1393")) diff --git a/vignettes/imputation.Rmd b/vignettes/imputation.Rmd index c8e1a790ae..8042bc837f 100644 --- a/vignettes/imputation.Rmd +++ b/vignettes/imputation.Rmd @@ -18,6 +18,28 @@ library(admiraldev) # Introduction +This vignette is broken into three major sections. The first section briefly +explores the imputation rules used in `{admiral}`. The second section focuses on +imputation functions that work on vectors with lots of small examples to explore +the imputation rules. These **vector-based** functions form the backbone of +`{admiral}`'s more powerful functions `derive_vars_dt()` and `derive_vars_dtm()` +for building ADaM dataset. The final section moves into more detailed examples +that a user might face while working on ADaMs in need of `---DT` and `---DTM` +variables. + +## Required Packages + +The examples of this vignette require the following packages. + +```{r, warning=FALSE, message=FALSE} +library(admiral) +library(lubridate) +library(tibble) +library(dplyr, warn.conflicts = FALSE) +``` + +# Imputation Rules + Date and time is collected in SDTM as character values using the extended [ISO 8601](https://en.wikipedia.org/wiki/ISO_8601) format. For example, `"2019-10-9T13:42:00"`. It allows that some parts of the date or time are @@ -25,34 +47,43 @@ missing, e.g., `"2019-10"` if the day and the time is unknown. The ADaM timing variables like `ADTM` (Analysis Datetime) or `ADY` (Analysis Relative Day) are numeric variables. They can be derived only if the date or -datetime is complete. Therefore `{admiral}` provides imputation functions which fill -in missing date or time parts according to certain imputation rules. +datetime is complete. Therefore `{admiral}` provides imputation functions which +fill in missing date or time parts according to certain imputation rules. -In {admiral} we use only two functions `derive_vars_dt()` and +In `{admiral}` users will primarily use two functions `derive_vars_dt()` and `derive_vars_dtm()` for date and datetime imputations respectively. In all other functions where dates can be passed as an argument, we expect full dates or datetimes (unless otherwise specified), so if any possibility of partials then these functions should be used as a first step to make the required imputation. -## Required Packages +The functions that need to do date/time imputation follow a rule that we have +called **Highest Imputation**, which has a corresponding argument in all our +functions called `highest_imputation`. The rule is best explained by working +through the examples below, but to put it briefly, this rule allows a user to +control which components of the DTC value are imputed if they are missing. -The examples of this vignette require the following packages. +The default imputation for `_dtm()` functions, e.g. `impute_dtc_dtm()`, +`derive_vars_dtm()`, is "h" (hours). A user can specify that that no imputation +is to be done by setting `highest_imputation = n`. However, for for `_dt()` +functions, e.g. `impute_dtc_dt()`, `derive_vars_dt()` the default imputation is +already set as `highest_imputation = "n"`. -```{r, warning=FALSE, message=FALSE} -library(admiral) -library(lubridate) -library(tibble) -library(dplyr, warn.conflicts = FALSE) -``` +Care must be taken when deciding on level of imputation. If a component is at a +higher level than the highest imputation level is missing, `NA_character_` is +returned. For example, for `highest_imputation = "D"` `"2020"` results in +`NA_character_` because the month is missing. -# Imputation Rules +We encourage readers to explore in more detail the `highest_imputation` options +in both the `_dtm()` and `_dt()` function documentations and in the examples +below. + +## Imputation on a Vector -In {admiral} we don't allow users to pick any single part of the date/time to -impute, we only enable to impute up to a highest level, i.e. you couldn't choose -to say impute months, but not days. +In our first example, we will make use of `impute_dtc_dtm()` on `2019-10` +setting `highest_imputation = "M"`. The argument `date_imputation` and +`time_imputation` are given expressed inputs of the imputation we would like to +see done. -The simplest imputation rule is to set the missing parts to a fixed value. For -example ```{r} impute_dtc_dtm( @@ -63,7 +94,7 @@ impute_dtc_dtm( ) ``` -Sometimes this does not work as it would result in invalid dates, e.g., +Next we impute using `2019-02`, which if done naively can result in invalid dates, e.g., ```{r} impute_dtc_dtm( @@ -73,9 +104,9 @@ impute_dtc_dtm( time_imputation = "00:00:00" ) ``` - -Therefore the keywords `"first"` or `"last"` can be specified to request that -missing parts are replaced by the first or last possible value: +Therefore the keywords `"first"` or `"last"` can be specified in `date_imputation` +to request that missing parts are replaced by the first or last possible value - giving +us a valid date! ```{r} impute_dtc_dtm( @@ -88,7 +119,7 @@ impute_dtc_dtm( For dates, there is the additional option to use keyword `"mid"` to impute missing day to `15` or missing day and month to `06-30`, but note the -different behavior below depending on `preserve` argument for case when month +different behavior below depending on the `preserve` argument for the case when month only is missing: ```{r} @@ -196,10 +227,10 @@ impute_dtc_dtm( ``` It is ensured that the imputed date is not after any of the specified dates. -Only dates which are in the range of possible dates of the dtc value are -considered. The possible dates are defined by the missing parts of the dtc date, +Only dates which are in the range of possible dates of the DTC value are +considered. The possible dates are defined by the missing parts of the DTC date, i.e., for "2019-02" the possible dates range from "2019-02-01" to "2019-02-28". -Thus "2019-01-14" is ignored. This ensures that the non-missing parts of the dtc +Thus "2019-01-14" is ignored. This ensures that the non-missing parts of the DTC date are not changed. If the `min_dates` or `max_dates` argument is specified, it is also possible to diff --git a/vignettes/lab_grading.Rmd b/vignettes/lab_grading.Rmd index 9a1b694e0b..47103021ae 100644 --- a/vignettes/lab_grading.Rmd +++ b/vignettes/lab_grading.Rmd @@ -27,7 +27,7 @@ a set of criteria for particular lab tests that grade the severity or abnormalit a lab value. The grades are from 0 to 4, where grade 0 can be viewed generally as a “NORMAL” value. The higher the grade the more severe or more abnormal the lab value is. There are several sets of lab grading criteria, currently `{admiral}` has implemented -NCI-CTCAEv4 and NCI-CTCAEv5 grading criteria. In future releases `{admiral}` may look +NCI-CTCAEv4, NCI-CTCAEv5 and DAIDS grading criteria. In future releases `{admiral}` may look to implement further grading criteria. The NCI-CTCAE version 4 and 5 grading criteria can be found @@ -39,13 +39,21 @@ The NCI-CTCAEv4 criteria can be found under the heading The NCI-CTCAEv5 criteria can be found under the heading [**Common Terminology Criteria for Adverse Events (CTCAE)v5.0**](https://ctep.cancer.gov/protocoldevelopment/electronic_applications/ctc.htm#ctc_50) +The DAIDS grading criteria can be found +here: https://rsc.niaid.nih.gov/clinical-research-sites/daids-adverse-event-grading-tables . + +The DAIDS criteria can be found under the heading +[**DAIDS Table for Grading the Severity of Adult and Pediatric Adverse Events Corrected Version 2.1**](https://rsc.niaid.nih.gov/sites/default/files/daidsgradingcorrectedv21.pdf) + + # Grading metadata `{admiral}` will store a metadata data set for each set of grading criteria in the data folder of -`{admiral}`. Currently, we have `atoxgr_criteria_ctcv4()` for NCI-CTCAEv4 and `atoxgr_criteria_ctcv5()` -for NCI-CTCAEv5. Each metadata data set has required variables and optional variables, the optional -variables are purely for transparency, and will contain detailed information about the grading criteria. -The required variables are those used by `{admiral}` to create the grade. +`{admiral}`. Currently, we have `atoxgr_criteria_ctcv4()` for NCI-CTCAEv4, `atoxgr_criteria_ctcv5()` +for NCI-CTCAEv5 and `atoxgr_criteria_daids()` for DAIDS. Each metadata data set has required +variables and optional variables, the optional variables are purely for transparency, and will +contain detailed information about the grading criteria. The required variables are those used by +`{admiral}` to create the grade. ## Structure of metadata set @@ -57,13 +65,15 @@ Variable | Scope | Type | Example Value **DIRECTION** | The direction of the abnormality of a particular lab test value| Character | "L" or "H". **SI_UNIT_CHECK** | Unit of lab test, to check against input data if criteria is based on absolute values. | Character | "mmol/L" **VAR_CHECK** | Comma separated list of variables used in criteria, to check input data that variables exist. | Character | "AVAL, ANRLO" -**GRADE_CRITERIA_CODE** | Variable to hold code that creates grade based on defined criteria. | Character |R code that is a valid case statement within a `mutate` function call +**FILTER** | Only required for DAIDS grading. Variable to hold code that filters the lab data based on contents of column SUBGROUP. | Character |R code that is valid within a `filter` function call. +**GRADE_CRITERIA_CODE** | Variable to hold code that creates grade based on defined criteria. | Character |R code that is a valid case statement within a `mutate` function call. The metadata data set has the following structure for the optional variables: Variable | Scope | Type | Example Value ------- | -------- | ------ | -------- **SOC** | System Organ Class the lab test belongs to.| Character | "Investigations" +**SUBGROUP** | Only required for DAIDS grading. Description of subgroup of lab data.| Character | "> 15 years of age". **GRADE_1** | Grade 1 criteria for lab test, normally straight from source document.| Character | ">ULN - 3.0 x ULN". **GRADE_2** | Grade 2 criteria for lab test, normally straight from source document.| Character | ">3.0 - 5.0 x ULN". **GRADE_3** | Grade 3 criteria for lab test, normally straight from source document.| Character | ">5.0 - 20.0 x ULN". @@ -71,6 +81,13 @@ Variable | Scope | Type | Example Value **DEFINITION** | Definition of abnormality, normally from source document.| Character | "A finding based on laboratory test results that indicate an increase in the level of alanine aminotransferase (ALT or SGPT) in the blood specimen.". **COMMENT** | Description of any decisions made by `{admiral}` to implement grading criteria, where grading criteria alone was ambiguous. | Character | "Take worst case and assume on anticoagulation". +# Handling floating points when comparing numeric values + +When comparing numeric values, for example `AVAL > 1.1*ANRHI`, unexpected results can occur +due to floating point issues. To solve this issue {admiral} used the `signif()` function on +both side of the equation, the number of significant digits used to compare is passed into the +function `derive_var_atoxgr_dir()` via the argument `signif_dig`. Please see documentation of the +function for more details. # Creating the lab grade @@ -79,15 +96,15 @@ Variable | Scope | Type | Example Value ```{r message=FALSE} library(admiral) -library(admiral.test) +library(pharmaversesdtm) library(dplyr, warn.conflicts = FALSE) library(stringr) library(tibble) -data("admiral_lb") +data("lb") adsl <- admiral_adsl -lb <- convert_blanks_to_na(admiral_lb) +lb <- convert_blanks_to_na(lb) ``` ```{r echo=FALSE} lb <- filter(lb, USUBJID %in% c("01-701-1115", "01-705-1186", "01-705-1349", "01-708-1286", "01-707-1037", "01-716-1024")) @@ -121,6 +138,20 @@ atoxgr_criteria_ctcv5 %>% ) ```
+ +
+Finally, the list of terms defined in the `{admiral}` metadata to implement DAIDS is below: +
+ +```{r, eval=TRUE, echo=FALSE} +atoxgr_criteria_daids %>% + filter(!is.na(TERM)) %>% + distinct(TERM) %>% + dataset_vignette( + display_vars = exprs(TERM) + ) +``` +
Using CDISC data these lab tests can be mapped to the correct terms, firstly create `PARAMCD`, `PARAM`, `AVAL`, `ANRLO` and `ANRHI`, also some lab grading criteria require `BASE` and `PCHG`, so these would also need to be created before running `derive_var_atoxgr_dir()` @@ -243,7 +274,8 @@ It is now straightforward to create the grade, for low lab values the grade will be held in `ATOXGRL` and for high lab values the grade will be held in `ATOXGRH`. Note: for NCICTCAEv5 grading, you would update `meta_criteria` parameter to -`atoxgr_criteria_ctcv5`. +`atoxgr_criteria_ctcv5` and for DAIDS grading you would update `meta_criteria` +parameter to `atoxgr_criteria_daids` ```{r, eval=TRUE} adlb <- adlb %>% @@ -266,7 +298,8 @@ adlb <- adlb %>% Note: `{admiral}` does not grade 'Anemia' or 'Hemoglobin Increased' because the metadata is based on the SI unit of 'g/L', however the CDISC data has SI unit of 'mmol/L'. Please see `SI_UNIT_CHECK` variable in `{admiral}` metadata `atoxgr_criteria_ctcv4()` or -`atoxgr_criteria_ctcv5()`, the metadata is in the data folder of `{admiral}`. +`atoxgr_criteria_ctcv5()` or `atoxgr_criteria_daids()`, the metadata is in the data folder +of `{admiral}`.
```{r, eval=TRUE, echo=FALSE} @@ -604,9 +637,187 @@ atoxgr_criteria_ctcv5 %>% ```
+# DAIDS implementation {#implement_daids} + +## Terms graded + +Grading is implemented for those lab tests where a lab value is included in the grading definition, +`{admiral}` does NOT try to read any other data to determine the grade, and only the ADLB VAD is used. +The following DAIDS SOC values were identified for grading, these are “Chemistries" and +“Hematology”. + +From these SOC values the following terms criteria is implemented in `{admiral}` + +From SOC = "Chemistries" there are 31 DAIDS Terms: + + + Acidosis + + Albumin, Low + + Alkaline Phosphatase, High + + Alkalosis + + ALT, High + + Amylase, High + + AST, High + + Bicarbonate, Low + + Direct Bilirubin, High + + Total Bilirubin, High + + Calcium, High + + Calcium (Ionized), High + + Calcium, Low + + Calcium (Ionized), Low + + Creatine Kinase, High + + Creatinine, High + + Glucose Fasting, High + + Glucose Nonfasting, High + + Glucose, Low + + Lactate, High + + Lipase, High + + Cholesterol, Fasting, High + + LDL, Fasting, High + + Triglycerides, Fasting, High + + Magnesium, Low + + Phosphate, Low + + Potassium, High + + Potassium, Low + + Sodium, High + + Sodium, Low + + Uric Acid, High + +Note: {admiral} does not grade for TERM = "Total Bilirubin, High" when AGE <= 28 days, +these criteria are in Appendix of [**DAIDS Table for Grading the Severity of Adult and Pediatric Adverse Events Corrected Version 2.1**](https://rsc.niaid.nih.gov/sites/default/files/daidsgradingcorrectedv21.pdf). + +From the SOC = "Hematology" there are 11 DAIDS Terms: + + + Absolute CD4+ Count, Low + + Absolute Lymphocyte Count, Low + + Absolute Neutrophil Count (ANC), Low + + Fibrinogen Decreased + + Hemoglobin, Low + + INR, High + + Methemoglobin + + PTT, High + + Platelets, Decreased + + PT, High + + WBC, Decreased + +## Terms with age or sex dependent grading criteria + +Some terms defined in DAIDS have age or sex dependent grading criteria, {admiral} +handles this in variable `FILTER` in the metadata. We use {admiral} function +`compute_duration` to calculate age, see TERM = "Cholesterol, Fasting, High": +
+ +```{r, eval=TRUE, echo=FALSE} +atoxgr_criteria_daids %>% + filter(str_detect(TERM, "Cholesterol")) %>% + dataset_vignette( + display_vars = exprs(TERM, FILTER) + ) +``` +
+ +Note: All possible values must be covered for each TERM defined, for TERM = +"Absolute Lymphocyte Count, Low" and "Absolute CD4+ Count, Low" there is only grading +criteria defined for age > 5 years. Therefore, we add another row with age <= 5 years +and set grade to missing. Similarly, for TERM = "LDL, Fasting, High" there is only grading +criteria defined for age > 2 years. Therefore, we add another row with age <= 2 years and +set grade to missing. + +```{r, eval=TRUE, echo=FALSE} +atoxgr_criteria_daids %>% + filter(str_detect(COMMENT, "No criteria given")) %>% + dataset_vignette( + display_vars = exprs(TERM, FILTER, GRADE_CRITERIA_CODE) + ) +``` + + +## Assumptions made when grading + + +For terms "INR, High", "PT, High" and "PTT, High", the criteria is based on subjects +"not on anticoagulation therapy", this is captured in COMMENT field. + +
+```{r, eval=TRUE, echo=FALSE} +atoxgr_criteria_daids %>% + filter(TERM %in% c("INR, High", "PT, High", "PTT, High")) %>% + dataset_vignette( + display_vars = exprs(TERM, COMMENT) + ) +``` +
+ +Similarly, for terms "Absolute CD4+ Count, Low" and "Absolute Lymphocyte Count, Low", +the criteria is based on subjects "not HIV infected", this is captured in COMMENT field. + +
+```{r, eval=TRUE, echo=FALSE} +atoxgr_criteria_daids %>% + filter(str_detect(COMMENT, "HIV infected")) %>% + dataset_vignette( + display_vars = exprs(TERM, COMMENT) + ) +``` +
+ + +For term "Acidosis", "Alkalosis" and "Direct Bilirubin, High (> 28 days of age)", +{admiral} grades as high as possible, so assumes worst case and subject has +"life-threatening consequences". +This is captured in COMMENT field. + +
+```{r, eval=TRUE, echo=FALSE} +atoxgr_criteria_daids %>% + filter(str_detect(COMMENT, "lifethreatening")) %>% + dataset_vignette( + display_vars = exprs(TERM, COMMENT) + ) +``` +
+Similarly, for term "Lactate, High", {admiral} only grade 1 and 2, and there is the following criteria: + +
+```{r, eval=TRUE, echo=FALSE} +atoxgr_criteria_daids %>% + filter(str_detect(TERM, "Lactate")) %>% + dataset_vignette( + display_vars = exprs(TERM, Grade_1, Grade_1) + ) +``` +
+ +`{admiral}` assumed worst case and assume "without acidosis". +The decision made was put in the `COMMENT` field. + +
+```{r, eval=TRUE, echo=FALSE} +atoxgr_criteria_daids %>% + filter(str_detect(TERM, "Lactate")) %>% + dataset_vignette( + display_vars = exprs(TERM, COMMENT) + ) +``` +
+ +For TERM "Direct Bilirubin, High (<= 28 days of age)" and "Uric Acid, High" the +criteria is not given in SI unit. The conversion to SI unit is in the comment field. + +
+```{r, eval=TRUE, echo=FALSE} +atoxgr_criteria_daids %>% + filter(str_detect(COMMENT, "conver")) %>% + dataset_vignette( + display_vars = exprs(TERM, FILTER, COMMENT) + ) +``` +
+ + # Conclusion -With NCI-CTCAEv4 and NCI-CTCAEv5 now implemented, {admiral} may look to implement other -industry standard grading criteria. Providing tools for users to easily interact with -the metadata to update criteria, based on their companies needs will also be looked at. -Ideally, users should be able to create their own metadata for company specific grading schemes. +With NCI-CTCAEv4, NCI-CTCAEv5 and DAIDS grading now implemented, {admiral} may look to +implement other industry standard grading criteria. Providing tools for users to easily +interact with the metadata to update criteria, based on their companies needs will also +be looked at. Ideally, users should be able to create their own metadata for company specific +grading schemes. diff --git a/vignettes/occds.Rmd b/vignettes/occds.Rmd index 104a9c8405..335610b27d 100644 --- a/vignettes/occds.Rmd +++ b/vignettes/occds.Rmd @@ -50,18 +50,18 @@ the environment. This will be a company specific process. Some of the data frames needed may be `AE` and `ADSL` For example purpose, the CDISC Pilot SDTM and ADaM datasets ---which are -included in `{admiral.test}`--- are used. +included in `{pharmaversesdtm}`--- are used. ```{r, message=FALSE, warning=FALSE} library(admiral) library(dplyr, warn.conflicts = FALSE) -library(admiral.test) +library(pharmaversesdtm) library(lubridate) -data("admiral_ae") +data("ae") data("admiral_adsl") -ae <- convert_blanks_to_na(admiral_ae) +ae <- convert_blanks_to_na(ae) adsl <- admiral_adsl ``` ```{r echo = FALSE} @@ -304,7 +304,7 @@ The expected result is the input dataset with an additional column named `ONTRTFL` with a value of `"Y"` or `NA`. If you want to also check an end date, you could add the `end_date` argument. -Note that in this scenario you could set `span_period = "Y"` if you want occurrences that started +Note that in this scenario you could set `span_period = TRUE` if you want occurrences that started prior to drug intake, and was ongoing or ended after this time to be considered as on-treatment. ```{r eval=TRUE} diff --git a/vignettes/pk_adnca.Rmd b/vignettes/pk_adnca.Rmd index df24f633f8..38c60f4805 100644 --- a/vignettes/pk_adnca.Rmd +++ b/vignettes/pk_adnca.Rmd @@ -101,36 +101,36 @@ baseline variables if needed. These may come from either the SDTM or ADaM source. For the purpose of example, the CDISC Pilot SDTM and ADaM -datasets---which are included in `{admiral.test}`---are used. +datasets---which are included in `{pharmaversesdtm}`---are used. ```{r message=FALSE} library(dplyr, warn.conflicts = FALSE) library(admiral) -library(admiral.test) +library(pharmaversesdtm) library(lubridate) library(stringr) library(tibble) data("admiral_adsl") -data("admiral_ex") -data("admiral_pc") -data("admiral_vs") -data("admiral_lb") +data("ex") +data("pc") +data("vs") +data("lb") adsl <- admiral_adsl -ex <- convert_blanks_to_na(admiral_ex) +ex <- convert_blanks_to_na(ex) # Load PC -pc <- convert_blanks_to_na(admiral_pc) +pc <- convert_blanks_to_na(pc) # Load VS for baseline height and weight -vs <- convert_blanks_to_na(admiral_vs) +vs <- convert_blanks_to_na(vs) # Load LB for baseline lab values -lb <- convert_blanks_to_na(admiral_lb) %>% +lb <- convert_blanks_to_na(lb) %>% filter(LBBLFL == "Y") # ---- Lookup tables ---- @@ -966,7 +966,7 @@ in `ADPC` but did not keep. ## Find First Dose `ADPPK` {#ppkfirst} The initial programming steps for `ADPPK` will follow the same sequence -as the `ADPC`. This includes reading in the `{admiral.test}` data, +as the `ADPC`. This includes reading in the `{pharmaversesdtm}` data, deriving analysis dates, defining the nominal relative time from first dose `NFRLT`, and expanding dosing records. For more detail see these steps above ([Read in Data](#readdata)). @@ -1377,11 +1377,11 @@ covar_vslb <- covar %>% ), # Derive CRCLBL and EGFRBL using new function CRCLBL = compute_egfr( - creat = CREATBL, creatu = "SI", age = AGE, wt = WTBL, sex = SEX, + creat = CREATBL, creatu = "SI", age = AGE, weight = WTBL, sex = SEX, method = "CRCL" ), EGFRBL = compute_egfr( - creat = CREATBL, creatu = "SI", age = AGE, wt = WTBL, sex = SEX, + creat = CREATBL, creatu = "SI", age = AGE, weight = WTBL, sex = SEX, method = "CKD-EPI" ) ) %>%