From d17389575cbc3fbf03fade40cec9b97e76a2c14a Mon Sep 17 00:00:00 2001 From: m-kolomanski Date: Thu, 23 Jan 2025 13:22:16 +0100 Subject: [PATCH 01/19] refactor: allow to pass parameters into shiny::runApp function --- R/run_app.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/run_app.R b/R/run_app.R index be05fefa..b040e7bb 100644 --- a/R/run_app.R +++ b/R/run_app.R @@ -27,6 +27,6 @@ #' @importFrom utils read.csv write.csv #' @importFrom zip zipr #' @export -run_app <- function() { - shiny::runApp(system.file("shiny", package = "aNCA")) +run_app <- function(...) { + shiny::runApp(system.file("shiny", package = "aNCA"), ...) } From 627def27c33475b0fa7ff1487c7c86352993c35a Mon Sep 17 00:00:00 2001 From: m-kolomanski Date: Thu, 23 Jan 2025 13:25:24 +0100 Subject: [PATCH 02/19] refactor: added `require` statements to the run_app function --- R/run_app.R | 23 +++++++++++++++++++++++ man/run_app.Rd | 5 ++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/R/run_app.R b/R/run_app.R index b040e7bb..0c9b7351 100644 --- a/R/run_app.R +++ b/R/run_app.R @@ -3,6 +3,8 @@ #' List of functions imported for the shiny application. #' When adding new imports, please keep the alphabetical order, at lest for packages. #' +#' @param ... Arguments passed to `shiny::runApp()` +#' #' @import shiny #' @import bslib #' @importFrom dplyr mutate filter select group_by summarise pull arrange ungroup @@ -28,5 +30,26 @@ #' @importFrom zip zipr #' @export run_app <- function(...) { + require(aNCA) + + require(shiny) + require(bslib) + + require(dplyr) + require(DT) + require(ggpplot2) + require(htmlwidgets) + require(PKNCA) + require(plotly) + require(reactable) + require(rio) + require(rmarkdown) + require(shinyBS) + require(shinycssloaders) + require(shinyjqui) + require(stringi) + require(tools) + require(utils) + require(zipr) shiny::runApp(system.file("shiny", package = "aNCA"), ...) } diff --git a/man/run_app.Rd b/man/run_app.Rd index ac183c06..3fc491b6 100644 --- a/man/run_app.Rd +++ b/man/run_app.Rd @@ -4,7 +4,10 @@ \alias{run_app} \title{Run the Shiny app} \usage{ -run_app() +run_app(...) +} +\arguments{ +\item{...}{Arguments passed to \code{shiny::runApp()}} } \description{ List of functions imported for the shiny application. From 1491a24112e5ff909d3e8b10807da655a1c17106 Mon Sep 17 00:00:00 2001 From: m-kolomanski Date: Thu, 23 Jan 2025 13:28:49 +0100 Subject: [PATCH 03/19] refactor: removed redundant import statements --- NAMESPACE | 51 -------------------------------------------------- R/run_app.R | 29 +--------------------------- man/run_app.Rd | 3 +-- 3 files changed, 2 insertions(+), 81 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index d76fe367..6fc6658a 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -29,60 +29,37 @@ export(pkcg01) export(pptestcd_dict) export(run_app) export(set_empty_label) -import(bslib) import(dplyr) import(forcats) import(ggplot2) import(haven) import(nestcolor) import(plotly) -import(shiny) import(tidyr) -importFrom(DT,DTOutput) -importFrom(DT,datatable) -importFrom(DT,formatStyle) -importFrom(DT,renderDataTable) -importFrom(DT,styleEqual) -importFrom(PKNCA,PKNCA.options) -importFrom(PKNCA,PKNCAconc) -importFrom(PKNCA,PKNCAdata) -importFrom(PKNCA,PKNCAdose) importFrom(PKNCA,pk.calc.c0) -importFrom(PKNCA,pk.nca) -importFrom(PKNCA,pknca_units_table) importFrom(checkmate,assert_numeric) importFrom(dplyr,across) importFrom(dplyr,arrange) -importFrom(dplyr,case_when) importFrom(dplyr,distinct) importFrom(dplyr,filter) importFrom(dplyr,group_by) importFrom(dplyr,left_join) importFrom(dplyr,mutate) importFrom(dplyr,n) -importFrom(dplyr,pull) importFrom(dplyr,rename) -importFrom(dplyr,rename_with) importFrom(dplyr,rowwise) importFrom(dplyr,select) importFrom(dplyr,slice) -importFrom(dplyr,summarise) importFrom(dplyr,ungroup) importFrom(dplyr,where) importFrom(ggh4x,scale_y_facet) importFrom(ggplot2,aes) -importFrom(ggplot2,facet_wrap) -importFrom(ggplot2,geom_errorbar) -importFrom(ggplot2,geom_line) -importFrom(ggplot2,geom_point) -importFrom(ggplot2,ggplot) importFrom(ggplot2,ggplot_build) importFrom(ggplot2,ggplot_gtable) importFrom(ggplot2,labs) importFrom(ggplot2,scale_x_continuous) importFrom(glue,glue) importFrom(grid,convertUnit) -importFrom(htmlwidgets,JS) importFrom(logger,log_debug) importFrom(logger,log_error) importFrom(logger,log_fatal) @@ -90,41 +67,13 @@ importFrom(logger,log_info) importFrom(logger,log_trace) importFrom(logger,log_warn) importFrom(magrittr,`%>%`) -importFrom(plotly,event_data) -importFrom(plotly,plotlyOutput) -importFrom(plotly,plotly_build) -importFrom(plotly,renderPlotly) importFrom(purrr,imap) -importFrom(reactable,colDef) -importFrom(reactable,getReactableState) -importFrom(reactable,reactable) -importFrom(reactable,reactableOutput) -importFrom(reactable,reactableTheme) -importFrom(reactable,renderReactable) -importFrom(reactable.extras,dropdown_extra) -importFrom(reactable.extras,text_extra) -importFrom(rio,export_list) importFrom(rlang,sym) -importFrom(rmarkdown,render) importFrom(scales,breaks_log) importFrom(scales,label_log) -importFrom(shinyBS,bsModal) -importFrom(shinyFiles,shinyDirChoose) -importFrom(shinyWidgets,dropdown) -importFrom(shinyWidgets,pickerInput) -importFrom(shinyWidgets,switchInput) -importFrom(shinyWidgets,updatePickerInput) -importFrom(shinycssloaders,withSpinner) -importFrom(shinyjqui,orderInput) -importFrom(shinyjqui,updateOrderInput) importFrom(stats,sd) -importFrom(stringi,stri_rand_strings) importFrom(tern,g_ipp) importFrom(tidyr,pivot_longer) importFrom(tidyr,pivot_wider) -importFrom(tools,file_ext) importFrom(units,set_units) -importFrom(utils,read.csv) -importFrom(utils,write.csv) importFrom(yaml,read_yaml) -importFrom(zip,zipr) diff --git a/R/run_app.R b/R/run_app.R index 0c9b7351..63baa4ea 100644 --- a/R/run_app.R +++ b/R/run_app.R @@ -1,33 +1,5 @@ #' Run the Shiny app -#' -#' List of functions imported for the shiny application. -#' When adding new imports, please keep the alphabetical order, at lest for packages. -#' #' @param ... Arguments passed to `shiny::runApp()` -#' -#' @import shiny -#' @import bslib -#' @importFrom dplyr mutate filter select group_by summarise pull arrange ungroup -#' @importFrom dplyr rename_with across case_when left_join rename -#' @importFrom DT DTOutput renderDataTable datatable formatStyle styleEqual -#' @importFrom ggplot2 ggplot geom_errorbar geom_point geom_line labs aes facet_wrap -#' @importFrom htmlwidgets JS -#' @importFrom PKNCA PKNCAconc PKNCAdose PKNCAdata pk.nca PKNCA.options pknca_units_table -#' @importFrom plotly plotlyOutput renderPlotly plotly_build event_data -#' @importFrom reactable reactable reactableOutput renderReactable colDef reactableTheme -#' @importFrom reactable getReactableState -#' @importFrom reactable.extras text_extra dropdown_extra -#' @importFrom rio export_list -#' @importFrom rmarkdown render -#' @importFrom shinyBS bsModal -#' @importFrom shinycssloaders withSpinner -#' @importFrom shinyFiles shinyDirChoose -#' @importFrom shinyjqui orderInput updateOrderInput -#' @importFrom shinyWidgets dropdown pickerInput switchInput updatePickerInput -#' @importFrom stringi stri_rand_strings -#' @importFrom tools file_ext -#' @importFrom utils read.csv write.csv -#' @importFrom zip zipr #' @export run_app <- function(...) { require(aNCA) @@ -47,6 +19,7 @@ run_app <- function(...) { require(shinyBS) require(shinycssloaders) require(shinyjqui) + require(shinyWidgets) require(stringi) require(tools) require(utils) diff --git a/man/run_app.Rd b/man/run_app.Rd index 3fc491b6..a36bd273 100644 --- a/man/run_app.Rd +++ b/man/run_app.Rd @@ -10,6 +10,5 @@ run_app(...) \item{...}{Arguments passed to \code{shiny::runApp()}} } \description{ -List of functions imported for the shiny application. -When adding new imports, please keep the alphabetical order, at lest for packages. +Run the Shiny app } From 2c6ab83798635f898da96f667e46f7c57e442b48 Mon Sep 17 00:00:00 2001 From: m-kolomanski Date: Thu, 23 Jan 2025 13:34:07 +0100 Subject: [PATCH 04/19] refactor: export slope selector utils functions --- R/utils-slope_selector.R | 7 +++-- inst/shiny/modules/slope_selector.R | 8 +++--- tests/testthat/test-utils-slope_selector.R | 32 +++++++++++----------- 3 files changed, 24 insertions(+), 23 deletions(-) diff --git a/R/utils-slope_selector.R b/R/utils-slope_selector.R index 068cf1f4..556b08b4 100644 --- a/R/utils-slope_selector.R +++ b/R/utils-slope_selector.R @@ -11,8 +11,8 @@ #' @returns Original dataset, with `is.included.hl`, `is.excluded.hl` and `exclude_half.life` #' columns modified in accordance to the provided slope filters. #' @importFrom dplyr filter group_by mutate -#' -.filter_slopes <- function(data, slopes, profiles) { +#' @export +filter_slopes <- function(data, slopes, profiles) { if (is.null(data) || is.null(data$conc) || is.null(data$conc$data)) stop("Please provide valid data.") @@ -84,7 +84,8 @@ #' that the user wants to remove rule if new range already exists in the dataset. #' If TRUE, in that case full range will be kept. #' @returns Data frame with full ruleset, adjusted for new rules. -.check_slope_rule_overlap <- function(existing, new, .keep = FALSE) { +#' @export +check_slope_rule_overlap <- function(existing, new, .keep = FALSE) { # check if any rule already exists for specific patient and profile # existing_index <- which( existing$TYPE == new$TYPE & diff --git a/inst/shiny/modules/slope_selector.R b/inst/shiny/modules/slope_selector.R index c318d7aa..383b2f1c 100644 --- a/inst/shiny/modules/slope_selector.R +++ b/inst/shiny/modules/slope_selector.R @@ -356,12 +356,12 @@ slope_selector_server <- function( # Observe input$nca observeEvent(profiles_per_patient(), { - mydata(.filter_slopes(mydata(), manual_slopes(), profiles_per_patient())) + mydata(filter_slopes(mydata(), manual_slopes(), profiles_per_patient())) }) #' saves and implements provided ruleset observeEvent(input$save_ruleset, { - mydata(.filter_slopes(mydata(), manual_slopes(), profiles_per_patient())) + mydata(filter_slopes(mydata(), manual_slopes(), profiles_per_patient())) pk_nca_trigger(pk_nca_trigger() + 1) }) @@ -370,7 +370,7 @@ slope_selector_server <- function( #' and exclusions before applying them to the actual dataset. plot_data <- reactive({ req(mydata(), manual_slopes(), profiles_per_patient()) - .filter_slopes(mydata(), manual_slopes(), profiles_per_patient()) + filter_slopes(mydata(), manual_slopes(), profiles_per_patient()) }) %>% shiny::debounce(750) @@ -410,7 +410,7 @@ slope_selector_server <- function( ) # Check if there is any overlap with existing rules, adda new or edit accordingly - new_manual_slopes <- .check_slope_rule_overlap(manual_slopes(), new_slope_rule) + new_manual_slopes <- check_slope_rule_overlap(manual_slopes(), new_slope_rule) manual_slopes(new_manual_slopes) diff --git a/tests/testthat/test-utils-slope_selector.R b/tests/testthat/test-utils-slope_selector.R index 0b03ccba..1c9015fe 100644 --- a/tests/testthat/test-utils-slope_selector.R +++ b/tests/testthat/test-utils-slope_selector.R @@ -1,4 +1,4 @@ -DATA_FIXTURE <- list( +eDATA_FIXTURE <- list( conc = list( data = data.frame( STUDYID = 1, @@ -21,7 +21,7 @@ PROFILES_FIXTURE <- list( "4" = list(1) ) -describe(".filter_slopes", { +describe("filter_slopes", { it("should handle slope selection", { selection <- data.frame( TYPE = rep("Selection", 2), @@ -31,7 +31,7 @@ describe(".filter_slopes", { REASON = "Test selection" ) - res <- .filter_slopes(DATA_FIXTURE, selection, PROFILES_FIXTURE) + res <- filter_slopes(DATA_FIXTURE, selection, PROFILES_FIXTURE) expect_true(all(res$is.included.hl[c(1:3, 6:8)])) expect_true(all(res$REASON[c(1:3, 6:8)] == "Test selection")) }) @@ -45,19 +45,19 @@ describe(".filter_slopes", { REASON = "Test exclusion" ) - res <- .filter_slopes(DATA_FIXTURE, exclusion, PROFILES_FIXTURE) + res <- filter_slopes(DATA_FIXTURE, exclusion, PROFILES_FIXTURE) expect_true(all(res$is.excluded.hl[c(5, 6, 14, 15)])) expect_true(all(res$REASON[c(5, 6, 14, 15)] == "Test exclusion")) }) it("should throw an error for invalid data", { - expect_error(.filter_slopes(NULL, NULL, PROFILES_FIXTURE), "Please provide valid data.") - expect_error(.filter_slopes(list(), NULL, PROFILES_FIXTURE), "Please provide valid data.") + expect_error(filter_slopes(NULL, NULL, PROFILES_FIXTURE), "Please provide valid data.") + expect_error(filter_slopes(list(), NULL, PROFILES_FIXTURE), "Please provide valid data.") expect_error( - .filter_slopes(list(conc = list()), NULL, PROFILES_FIXTURE), "Please provide valid data." + filter_slopes(list(conc = list()), NULL, PROFILES_FIXTURE), "Please provide valid data." ) expect_error( - .filter_slopes(list(conc = list()), NULL, PROFILES_FIXTURE), "Please provide valid data." + filter_slopes(list(conc = list()), NULL, PROFILES_FIXTURE), "Please provide valid data." ) }) }) @@ -69,7 +69,7 @@ EXISTING_FIXTURE <- data.frame( IXrange = "3:6" ) -describe(".check_slope_rule_overlap", { +describe("check_slope_rule_overlap", { it("should add new row if no overlap is detected", { # different type # NEW <- data.frame( @@ -78,7 +78,7 @@ describe(".check_slope_rule_overlap", { PROFILE = 1, IXrange = "1:3" ) - expect_equal(nrow(.check_slope_rule_overlap(EXISTING_FIXTURE, NEW)), 2) + expect_equal(nrow(check_slope_rule_overlap(EXISTING_FIXTURE, NEW)), 2) # different patient # NEW <- data.frame( @@ -87,7 +87,7 @@ describe(".check_slope_rule_overlap", { PROFILE = 1, IXrange = "1:3" ) - expect_equal(nrow(.check_slope_rule_overlap(EXISTING_FIXTURE, NEW)), 2) + expect_equal(nrow(check_slope_rule_overlap(EXISTING_FIXTURE, NEW)), 2) # different profile # NEW <- data.frame( @@ -96,7 +96,7 @@ describe(".check_slope_rule_overlap", { PROFILE = 2, IXrange = "1:3" ) - expect_equal(nrow(.check_slope_rule_overlap(EXISTING_FIXTURE, NEW)), 2) + expect_equal(nrow(check_slope_rule_overlap(EXISTING_FIXTURE, NEW)), 2) }) it("should remove overlapping points if no new points are detected", { @@ -106,7 +106,7 @@ describe(".check_slope_rule_overlap", { PROFILE = 1, IXrange = "4:5" ) - expect_equal(.check_slope_rule_overlap(EXISTING_FIXTURE, NEW)$IXrange, "3,6") + expect_equal(check_slope_rule_overlap(EXISTING_FIXTURE, NEW)$IXrange, "3,6") NEW <- data.frame( TYPE = "Exclusion", @@ -114,7 +114,7 @@ describe(".check_slope_rule_overlap", { PROFILE = 1, IXrange = "3:4" ) - expect_equal(.check_slope_rule_overlap(EXISTING_FIXTURE, NEW)$IXrange, "5:6") + expect_equal(check_slope_rule_overlap(EXISTING_FIXTURE, NEW)$IXrange, "5:6") }) it("should add new points of partial overlap is detected", { @@ -124,7 +124,7 @@ describe(".check_slope_rule_overlap", { PROFILE = 1, IXrange = "4:9" ) - expect_equal(.check_slope_rule_overlap(EXISTING_FIXTURE, NEW)$IXrange, "3:9") + expect_equal(check_slope_rule_overlap(EXISTING_FIXTURE, NEW)$IXrange, "3:9") }) it("should remove full row if full range of rule is removed", { @@ -134,6 +134,6 @@ describe(".check_slope_rule_overlap", { PROFILE = 1, IXrange = "3:6" ) - expect_equal(nrow(.check_slope_rule_overlap(EXISTING_FIXTURE, NEW)), 0) + expect_equal(nrow(check_slope_rule_overlap(EXISTING_FIXTURE, NEW)), 0) }) }) From 8bf811a15993cd0b383dce17a1407d41635f4fe6 Mon Sep 17 00:00:00 2001 From: m-kolomanski Date: Thu, 23 Jan 2025 13:35:27 +0100 Subject: [PATCH 05/19] deps: bumped package version --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 463c91ba..4f8e0e89 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: aNCA Title: (Pre-)Clinical NCA in a Dynamic Shiny App -Version: 0.0.0.9000 +Version: 0.0.0.9001 Authors@R: c( person("Ercan", "Suekuer", , "ercan.suekuer@roche.com", role = c("aut", "cre"), comment = c(ORCID = "0009-0001-1626-1526")), From f27ab4811f4ce2736e3a7a2aeaabe80fdf84c80b Mon Sep 17 00:00:00 2001 From: m-kolomanski Date: Thu, 23 Jan 2025 13:44:33 +0100 Subject: [PATCH 06/19] fix: typos in required packages --- R/run_app.R | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/run_app.R b/R/run_app.R index 63baa4ea..b01f8f44 100644 --- a/R/run_app.R +++ b/R/run_app.R @@ -9,7 +9,7 @@ run_app <- function(...) { require(dplyr) require(DT) - require(ggpplot2) + require(ggplot2) require(htmlwidgets) require(PKNCA) require(plotly) @@ -23,6 +23,6 @@ run_app <- function(...) { require(stringi) require(tools) require(utils) - require(zipr) + require(zip) shiny::runApp(system.file("shiny", package = "aNCA"), ...) } From 72fda72d41df44f05f610e587ad1d3881ea85f13 Mon Sep 17 00:00:00 2001 From: m-kolomanski Date: Thu, 23 Jan 2025 13:46:48 +0100 Subject: [PATCH 07/19] fix: added missing required packages --- R/run_app.R | 23 +++++++++++++++++++++-- 1 file changed, 21 insertions(+), 2 deletions(-) diff --git a/R/run_app.R b/R/run_app.R index b01f8f44..bbefb1d3 100644 --- a/R/run_app.R +++ b/R/run_app.R @@ -4,25 +4,44 @@ run_app <- function(...) { require(aNCA) - require(shiny) require(bslib) - + require(checkmate) require(dplyr) require(DT) + require(forcats) + require(ggh4x) require(ggplot2) + require(glue) + require(haven) require(htmlwidgets) + require(logger) + require(magrittr) + require(nestcolor) require(PKNCA) require(plotly) + require(purrr) require(reactable) + require(reactable.extras) require(rio) require(rmarkdown) + require(scales) + require(shiny) require(shinyBS) require(shinycssloaders) + require(shinyFiles) require(shinyjqui) + require(shinyjs) require(shinyWidgets) + require(stats) require(stringi) + require(stringr) + require(tern) + require(tidyr) require(tools) require(utils) + require(units) + require(rlang) + require(yaml) require(zip) shiny::runApp(system.file("shiny", package = "aNCA"), ...) } From f458df0f47a0801425dd367bd9016eed8725d8e0 Mon Sep 17 00:00:00 2001 From: m-kolomanski Date: Thu, 23 Jan 2025 13:49:26 +0100 Subject: [PATCH 08/19] fix: missing exports for utilitary functions --- NAMESPACE | 2 ++ ...ck_slope_rule_overlap.Rd => check_slope_rule_overlap.Rd} | 6 +++--- man/{dot-filter_slopes.Rd => filter_slopes.Rd} | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) rename man/{dot-check_slope_rule_overlap.Rd => check_slope_rule_overlap.Rd} (86%) rename man/{dot-filter_slopes.Rd => filter_slopes.Rd} (91%) diff --git a/NAMESPACE b/NAMESPACE index 6fc6658a..585d977b 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -7,8 +7,10 @@ export(apply_filters) export(apply_labels) export(as_factor_preserve_label) export(calculate_summary_stats) +export(check_slope_rule_overlap) export(create_start_impute) export(filter_breaks) +export(filter_slopes) export(flexible_violinboxplot) export(format_pkncaconc_data) export(format_pkncadata_intervals) diff --git a/man/dot-check_slope_rule_overlap.Rd b/man/check_slope_rule_overlap.Rd similarity index 86% rename from man/dot-check_slope_rule_overlap.Rd rename to man/check_slope_rule_overlap.Rd index fc724a6f..a6188071 100644 --- a/man/dot-check_slope_rule_overlap.Rd +++ b/man/check_slope_rule_overlap.Rd @@ -1,10 +1,10 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils-slope_selector.R -\name{.check_slope_rule_overlap} -\alias{.check_slope_rule_overlap} +\name{check_slope_rule_overlap} +\alias{check_slope_rule_overlap} \title{Check overlap between existing and new slope rulesets} \usage{ -.check_slope_rule_overlap(existing, new, .keep = FALSE) +check_slope_rule_overlap(existing, new, .keep = FALSE) } \arguments{ \item{existing}{Data frame with existing selections and exclusions.} diff --git a/man/dot-filter_slopes.Rd b/man/filter_slopes.Rd similarity index 91% rename from man/dot-filter_slopes.Rd rename to man/filter_slopes.Rd index 536763c1..340a8ce6 100644 --- a/man/dot-filter_slopes.Rd +++ b/man/filter_slopes.Rd @@ -1,10 +1,10 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/utils-slope_selector.R -\name{.filter_slopes} -\alias{.filter_slopes} +\name{filter_slopes} +\alias{filter_slopes} \title{Filter dataset based on slope selections and exclusions} \usage{ -.filter_slopes(data, slopes, profiles) +filter_slopes(data, slopes, profiles) } \arguments{ \item{data}{Data to filter. Must be \code{PKNCAdata} list, containing the \code{conc} element with From 86a3e06b61dbd2c8160224221738610c6ab4306a Mon Sep 17 00:00:00 2001 From: m-kolomanski Date: Thu, 23 Jan 2025 13:52:42 +0100 Subject: [PATCH 09/19] fix: invalid `@export` statement for `export_cdisc` --- NAMESPACE | 2 +- R/export_cdisc.R | 54 +++++++++++------------ man/{pptestcd_dict.Rd => export_cdisc.Rd} | 11 ++--- 3 files changed, 29 insertions(+), 38 deletions(-) rename man/{pptestcd_dict.Rd => export_cdisc.Rd} (84%) diff --git a/NAMESPACE b/NAMESPACE index 585d977b..df47bd4a 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -9,6 +9,7 @@ export(as_factor_preserve_label) export(calculate_summary_stats) export(check_slope_rule_overlap) export(create_start_impute) +export(export_cdisc) export(filter_breaks) export(filter_slopes) export(flexible_violinboxplot) @@ -28,7 +29,6 @@ export(parse_annotation) export(parse_tlg_definitions) export(pivot_wider_pknca_results) export(pkcg01) -export(pptestcd_dict) export(run_app) export(set_empty_label) import(dplyr) diff --git a/R/export_cdisc.R b/R/export_cdisc.R index e1b8f9df..8f41d56e 100644 --- a/R/export_cdisc.R +++ b/R/export_cdisc.R @@ -18,34 +18,6 @@ #' #' @import dplyr #' @export - - -# Define the unique combinations -pptestcd_dict <- setNames( - c( - "Total CL Obs by F", "Time of Last Nonzero Conc", "Max Conc", "Vz Obs by F", "AUC Infinity Obs", - "Last Nonzero Conc", "Time of CMAX", "R Squared", "R Squared Adjusted", "Max Conc Norm by Dose", - "AUC to Last Nonzero Conc Norm by Dose", "Lambda z", "AUC to Last Nonzero Conc", - "Half-Life Lambda z", "Number of points used for Lambda z", "Last Nonzero Conc Predicted", - "Span Ratio", "Lambda z lower limit (time)", - - # Manually filled - "Trough Concentration", "Average Concentration", "AUC Infinity Predicted", - "AUMC Infinity Observed", "AUC Percent Extrapolated Observed", - "AUC Percent Extrapolated Predicted", "Clearance Observed", - "Clearance Predicted", "Mean Residence Time Intravenous Observed", - "Volume of Distribution Observed", - "Steady-State Volume of Distribution Intravenous Observed", - "AUC Infinity Observed Dose-Normalized", "Maximum Concentration Dose-Normalized" - ), - c("CLFO", "TLST", "CMAX", "VZFO", "AUCIFO", "CLST", "TMAX", "R2", "R2ADJ", "CMAXD", "AUCLSTD", - "LAMZ", "AUCLST", "LAMZHL", "LAMZNPT", "CLSTP", "LAMZSPNR", "LAMZLL", - "CTROUGH", "CAV", "AUCIFP", "AUMCINF.OBS", "AUCPEO", "AUCPEP", "CL.OBS", "CL.PRED", - "MRT.IV.OBS", "VZ.OBS", "VSS.IV.OBS", "AUCINF.OBS.DN", "CMAX.DN" - ) -) - - export_cdisc <- function(res_nca) { if (FALSE) { # uncomment in case of more added variables @@ -192,7 +164,7 @@ export_cdisc <- function(res_nca) { PPENINT = ifelse(end != Inf, end, NA) ) %>% # Map PPTEST CDISC descriptions using PPTESTCD CDISC names - mutate(PPTEST = pptestcd_dict[PPTESTCD]) %>% + mutate(PPTEST = .pptestcd_dict[PPTESTCD]) %>% group_by(USUBJID) %>% mutate(PPSEQ = if ("PCSEQ" %in% names(.)) PCSEQ else row_number()) %>% ungroup() @@ -214,3 +186,27 @@ export_cdisc <- function(res_nca) { return(list(pp = pp, adpp = adpp)) } + +.pptestcd_dict <- setNames( + c( + "Total CL Obs by F", "Time of Last Nonzero Conc", "Max Conc", "Vz Obs by F", "AUC Infinity Obs", + "Last Nonzero Conc", "Time of CMAX", "R Squared", "R Squared Adjusted", "Max Conc Norm by Dose", + "AUC to Last Nonzero Conc Norm by Dose", "Lambda z", "AUC to Last Nonzero Conc", + "Half-Life Lambda z", "Number of points used for Lambda z", "Last Nonzero Conc Predicted", + "Span Ratio", "Lambda z lower limit (time)", + + # Manually filled + "Trough Concentration", "Average Concentration", "AUC Infinity Predicted", + "AUMC Infinity Observed", "AUC Percent Extrapolated Observed", + "AUC Percent Extrapolated Predicted", "Clearance Observed", + "Clearance Predicted", "Mean Residence Time Intravenous Observed", + "Volume of Distribution Observed", + "Steady-State Volume of Distribution Intravenous Observed", + "AUC Infinity Observed Dose-Normalized", "Maximum Concentration Dose-Normalized" + ), + c("CLFO", "TLST", "CMAX", "VZFO", "AUCIFO", "CLST", "TMAX", "R2", "R2ADJ", "CMAXD", "AUCLSTD", + "LAMZ", "AUCLST", "LAMZHL", "LAMZNPT", "CLSTP", "LAMZSPNR", "LAMZLL", + "CTROUGH", "CAV", "AUCIFP", "AUMCINF.OBS", "AUCPEO", "AUCPEP", "CL.OBS", "CL.PRED", + "MRT.IV.OBS", "VZ.OBS", "VSS.IV.OBS", "AUCINF.OBS.DN", "CMAX.DN" + ) +) \ No newline at end of file diff --git a/man/pptestcd_dict.Rd b/man/export_cdisc.Rd similarity index 84% rename from man/pptestcd_dict.Rd rename to man/export_cdisc.Rd index 2495705c..5ea76af7 100644 --- a/man/pptestcd_dict.Rd +++ b/man/export_cdisc.Rd @@ -1,14 +1,10 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/export_cdisc.R -\docType{data} -\name{pptestcd_dict} -\alias{pptestcd_dict} +\name{export_cdisc} +\alias{export_cdisc} \title{Export CDISC Data} -\format{ -An object of class \code{character} of length 31. -} \usage{ -pptestcd_dict +export_cdisc(res_nca) } \value{ A list with two data frames: @@ -30,4 +26,3 @@ Outputs are the following: on but now we avoid merge conflict) } } -\keyword{datasets} From 1a9a77ce8824ad87c4929673286bb0a47f992b08 Mon Sep 17 00:00:00 2001 From: m-kolomanski Date: Thu, 23 Jan 2025 13:56:17 +0100 Subject: [PATCH 10/19] fix: test for slope selector utils failing --- R/utils-slope_selector.R | 2 +- tests/testthat/test-utils-slope_selector.R | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/R/utils-slope_selector.R b/R/utils-slope_selector.R index 556b08b4..c14bba19 100644 --- a/R/utils-slope_selector.R +++ b/R/utils-slope_selector.R @@ -39,7 +39,7 @@ filter_slopes <- function(data, slopes, profiles) { # Go over all rules and check if there is no overlap - if there is, edit accordingly slopes <- purrr::reduce( split(slopes, seq_len(nrow(slopes))), - .f = ~ .check_slope_rule_overlap(.x, .y, .keep = TRUE) + .f = ~ check_slope_rule_overlap(.x, .y, .keep = TRUE) ) } diff --git a/tests/testthat/test-utils-slope_selector.R b/tests/testthat/test-utils-slope_selector.R index 1c9015fe..afb18a44 100644 --- a/tests/testthat/test-utils-slope_selector.R +++ b/tests/testthat/test-utils-slope_selector.R @@ -1,4 +1,4 @@ -eDATA_FIXTURE <- list( +DATA_FIXTURE <- list( conc = list( data = data.frame( STUDYID = 1, From cc60e1270a8a47eefdd5f7fc7f10b0c16765537e Mon Sep 17 00:00:00 2001 From: m-kolomanski Date: Thu, 23 Jan 2025 14:04:24 +0100 Subject: [PATCH 11/19] fix: R CMD CHECK errors --- tests/testthat/test-create_start_impute.R | 8 ++++---- tests/testthat/test-format_data.R | 10 +++++----- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/tests/testthat/test-create_start_impute.R b/tests/testthat/test-create_start_impute.R index ab82c183..6fc4646a 100644 --- a/tests/testthat/test-create_start_impute.R +++ b/tests/testthat/test-create_start_impute.R @@ -28,10 +28,10 @@ intervals_data <- data.frame( auc.pred = TRUE ) -conc_obj <- PKNCAconc(conc_data, conc ~ time | USUBJID + DOSNO / analyte) -dose_obj <- PKNCAdose(dose_data, dose ~ time | USUBJID + DOSNO, - duration = "duration", route = "route") -mydata <- PKNCAdata(conc_obj, dose_obj, intervals = intervals_data) +conc_obj <- PKNCA::PKNCAconc(conc_data, conc ~ time | USUBJID + DOSNO / analyte) +dose_obj <- PKNCA::PKNCAdose(dose_data, dose ~ time | USUBJID + DOSNO, + duration = "duration", route = "route") +mydata <- PKNCA::PKNCAdata(conc_obj, dose_obj, intervals = intervals_data) # Apply the function describe("create_start_impute", { diff --git a/tests/testthat/test-format_data.R b/tests/testthat/test-format_data.R index 3efba9c4..114057d2 100644 --- a/tests/testthat/test-format_data.R +++ b/tests/testthat/test-format_data.R @@ -29,7 +29,7 @@ test_that("format_pkncaconc_data generates correct dataset", { # Test if df_conc can be used with PKNCAconc by testing its output expect_no_error( - PKNCAconc( + PKNCA::PKNCAconc( df_conc, formula = AVAL ~ TIME | STUDYID + PCSPEC + DRUG + USUBJID / ANALYTE, exclude_half.life = "exclude_half.life", @@ -77,7 +77,7 @@ test_that("format_pkncaconc_data generates correct dataset with multiple doses", # Test if df_conc can be used with PKNCAconc by testing its output expect_no_error( - PKNCAconc( + PKNCA::PKNCAconc( df_conc, formula = AVAL ~ TIME | STUDYID + PCSPEC + DRUG + USUBJID / ANALYTE, exclude_half.life = "exclude_half.life", @@ -173,7 +173,7 @@ test_that("format_pkncadose_data generates when missing the dose number column", # Test if df_dose can be used with PKNCAdose by testing its output expect_no_error( - PKNCAdose( + PKNCA::PKNCAdose( data = df_dose, formula = DOSEA ~ TIME | STUDYID + PCSPEC + DRUG + USUBJID, route = "ROUTE", @@ -279,14 +279,14 @@ test_that("format_pkncadata_intervals generates correct dataset", { since_lastdose_time_column = "ARRLT") # Generate PKNCAconc and PKNCAdose objects - myconc <- PKNCAconc( + myconc <- PKNCA::PKNCAconc( df_conc, formula = AVAL ~ TIME | STUDYID + PCSPEC + DRUG + USUBJID / ANALYTE, exclude_half.life = "exclude_half.life", time.nominal = "NFRLT" ) - mydose <- PKNCAdose( + mydose <- PKNCA::PKNCAdose( data = df_dose, formula = DOSEA ~ TIME | STUDYID + PCSPEC + DRUG + USUBJID, route = "ROUTE", From cf6971ba82995c3f86df3d1aecb562ec2d25de39 Mon Sep 17 00:00:00 2001 From: m-kolomanski Date: Thu, 23 Jan 2025 14:04:44 +0100 Subject: [PATCH 12/19] chore: removed deprecated `imports.R` file --- R/imports.R | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 R/imports.R diff --git a/R/imports.R b/R/imports.R deleted file mode 100644 index c8abf01d..00000000 --- a/R/imports.R +++ /dev/null @@ -1,2 +0,0 @@ -#' @importFrom logger log_trace log_debug log_info log_warn log_error log_fatal -NULL From 521167858f2a492f837d77aac496c7f1578e7dac Mon Sep 17 00:00:00 2001 From: m-kolomanski Date: Thu, 23 Jan 2025 14:16:02 +0100 Subject: [PATCH 13/19] docs: updated README with installation instructions --- README.md | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 0446d9a6..33cda733 100644 --- a/README.md +++ b/README.md @@ -28,19 +28,33 @@ This application enables users to upload their datasets and perform Non-Compartm * **Save your analysis settings** and reupload them later to keep on analysing! ## Installation -To install the application, clone the repository and load it locally using the following commands in your terminal: -``` sh -git clone https://github.com/pharmaverse/aNCA.git # Clone the repository +### Via pak (recommended) +We recommend using [pak](https://github.com/r-lib/pak) for package installation, along with all system dependencies. If you do not have `pak` available, you will need to set it up first: +```R +install.packages("pak") ``` -You can then run the application from the R console anytime. Just make sure first your working directory is set to the aNCA folder: -``` r -# install devtools if not present -if (!requireNamespace('devtools', quietly = TRUE)) install.packages('devtools') -devtools::load_all() # load all dependencies -aNCA::run_app() # run the application +then you can install [aNCA](.) by running: +```R +pak::install("pharmaverse/aNCA") +``` +in your R console. + +### Via cloning the repository (for contributors) +Alternatively, you can set up the package by cloning the repository: +```bash +git clone https://github.com/pharmaverse/aNCA.git +``` +and then loading it directly using [devtools](https://github.com/r-lib/devtools): +```R +devtools::load_all() ``` ## Quick start +To run the application, simply invoke: +```R +aNCA::run_app() +``` + The testing data will be automatically loaded upon application startup. You can provide your own dataset in the **data** tab. Here you can also specify pre-processing filters. In the **NCA** tab, start off by loading the pre-processed data using *Submit* button. You will also need to choose dose number in the *Settings*. Then, you will be able to run the NCA analysis. From there, you can also specify different analysis options, like applying flag rule sets and selecting slopes. From 56bb3a5f1299497b72113f19211a083e09fa99d3 Mon Sep 17 00:00:00 2001 From: m-kolomanski Date: Thu, 23 Jan 2025 15:04:05 +0100 Subject: [PATCH 14/19] build: added workflow to automatically bump package version --- .github/workflows/bump-version.yml | 37 ++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/bump-version.yml diff --git a/.github/workflows/bump-version.yml b/.github/workflows/bump-version.yml new file mode 100644 index 00000000..af3a6fe2 --- /dev/null +++ b/.github/workflows/bump-version.yml @@ -0,0 +1,37 @@ +name: Bump Package Version + +on: + pull_request: + types: [closed] + branches: + - main + +jobs: + bump_version: + name: Bump package version + if: github.event.pull_request.merged == true + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + fetch-depth: 0 + + - name: Bump version + shell: bash + run: | + current_version=$(grep -E '^Version:' DESCRIPTION | awk '{print $2}') + IFS='.' read -r -a version_parts <<< "$current_version" + version_parts[${#version_parts[@]}-1]=$((version_parts[${#version_parts[@]}-1]+1)) + new_version=$(IFS=.; echo "${version_parts[*]}") + sed -i "s/^Version: .*/Version: $new_version/" DESCRIPTION + + # Commit the changes + git config user.name 'github-actions[bot]' + git config user.email '41898282+github-actions[bot]@users.noreply.github.com' + git commit -am "Bump version to $new_version" + + - name: Push changes + uses: ad-m/github-push-action@master + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + branch: main \ No newline at end of file From 1c0b97663873de7f1362675f9aaf33b7e1178fe9 Mon Sep 17 00:00:00 2001 From: m-kolomanski Date: Thu, 23 Jan 2025 16:08:49 +0100 Subject: [PATCH 15/19] fix: spellcheck --- inst/WORDLIST | 2 ++ 1 file changed, 2 insertions(+) diff --git a/inst/WORDLIST b/inst/WORDLIST index 4e30cc7d..f0d5b7c1 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -26,11 +26,13 @@ cmax codebase csv customizable +devtools df ggplot ggplots lastdose nca +pak pharmacokinetic pkcg pknca From dcf47469c5eed8d0dc13c9a5de97f55ccfe78de4 Mon Sep 17 00:00:00 2001 From: m-kolomanski Date: Thu, 23 Jan 2025 16:34:31 +0100 Subject: [PATCH 16/19] build: removed invalid git workflow --- .github/workflows/bump-version.yml | 37 ------------------------------ 1 file changed, 37 deletions(-) delete mode 100644 .github/workflows/bump-version.yml diff --git a/.github/workflows/bump-version.yml b/.github/workflows/bump-version.yml deleted file mode 100644 index af3a6fe2..00000000 --- a/.github/workflows/bump-version.yml +++ /dev/null @@ -1,37 +0,0 @@ -name: Bump Package Version - -on: - pull_request: - types: [closed] - branches: - - main - -jobs: - bump_version: - name: Bump package version - if: github.event.pull_request.merged == true - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - with: - fetch-depth: 0 - - - name: Bump version - shell: bash - run: | - current_version=$(grep -E '^Version:' DESCRIPTION | awk '{print $2}') - IFS='.' read -r -a version_parts <<< "$current_version" - version_parts[${#version_parts[@]}-1]=$((version_parts[${#version_parts[@]}-1]+1)) - new_version=$(IFS=.; echo "${version_parts[*]}") - sed -i "s/^Version: .*/Version: $new_version/" DESCRIPTION - - # Commit the changes - git config user.name 'github-actions[bot]' - git config user.email '41898282+github-actions[bot]@users.noreply.github.com' - git commit -am "Bump version to $new_version" - - - name: Push changes - uses: ad-m/github-push-action@master - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - branch: main \ No newline at end of file From 0764cff80f9106865a62c4cb0ed195a77d74e29f Mon Sep 17 00:00:00 2001 From: m-kolomanski Date: Fri, 24 Jan 2025 08:11:35 +0100 Subject: [PATCH 17/19] docs: fix incorrect pak function name --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 33cda733..4cb8fb14 100644 --- a/README.md +++ b/README.md @@ -35,7 +35,7 @@ install.packages("pak") ``` then you can install [aNCA](.) by running: ```R -pak::install("pharmaverse/aNCA") +pak::pak("pharmaverse/aNCA") ``` in your R console. From 9820401be92a6ed4ed82b244119d31cb19dd8403 Mon Sep 17 00:00:00 2001 From: m-kolomanski Date: Fri, 24 Jan 2025 08:14:25 +0100 Subject: [PATCH 18/19] docs: more verbose setup instructions --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4cb8fb14..11a61a4e 100644 --- a/README.md +++ b/README.md @@ -40,11 +40,11 @@ pak::pak("pharmaverse/aNCA") in your R console. ### Via cloning the repository (for contributors) -Alternatively, you can set up the package by cloning the repository: +Alternatively, you can set up the package by cloning the repository through your terminal/shell: ```bash git clone https://github.com/pharmaverse/aNCA.git ``` -and then loading it directly using [devtools](https://github.com/r-lib/devtools): +and then loading it directly using [devtools](https://github.com/r-lib/devtools) in your IDE (e.g. RStudio) console: ```R devtools::load_all() ``` From bc95a6f83d1492243dcb583e5986d0083e2175b3 Mon Sep 17 00:00:00 2001 From: m-kolomanski Date: Fri, 24 Jan 2025 12:30:01 +0100 Subject: [PATCH 19/19] docs: updated CONTRIBUTING.md with caveats --- CONTRIBUTING.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index aea46ea6..114dd273 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -75,6 +75,10 @@ When the change is done, pull request is open and the description is filled, ple #### For reviewers When reviewing a pull request, please do try to follow the [conventional comments](https://conventionalcomments.org/) guidelines. Ideas and labels described in that convention can be very helpful in getting your thoughts across and facilitate meaningful cooperation. That said, they are not applicable in every circumstance and you are free to do whatever you feel is suitable, as long as it aims to provide valid discussion. +# Beware +- The package is split into two parts: the R package and a shiny application. Logic code, which is useful on its own and can be easily run via the console should be placed in the `R/` directory. Code that is strictly related to **Shiny** application, especially code that generates some interface elements, should be placed in `inst/shiny/` folder. +- The package requires some dependencies for which there are no explicit `@import` statements in the `NAMESPACE` file. This is because some of those functions are not used in the **package** itself, but rather in the **Shiny application**. Please beware of this situation when managing the package dependencies - some functions might be used in the app, even though they are not verbosely imported. + # In-depth guides Here are some useful links with in-depth documentation regarding specific parts of the pacakage and how to utilise in-build tools to extend the capabilities of the application: