Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhancement/run app via package installation #172

Merged
merged 19 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -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", , "[email protected]", role = c("aut", "cre"),
comment = c(ORCID = "0009-0001-1626-1526")),
Expand Down
55 changes: 3 additions & 52 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,11 @@ 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(export_cdisc)
export(filter_breaks)
export(filter_slopes)
export(flexible_violinboxplot)
export(format_pkncaconc_data)
export(format_pkncadata_intervals)
Expand All @@ -26,105 +29,53 @@ 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(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)
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)
54 changes: 25 additions & 29 deletions R/export_cdisc.R
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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()
Expand All @@ -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"
)
)
2 changes: 0 additions & 2 deletions R/imports.R

This file was deleted.

73 changes: 44 additions & 29 deletions R/run_app.R
Original file line number Diff line number Diff line change
@@ -1,32 +1,47 @@
#' 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.
#'
#' @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
#' @param ... Arguments passed to `shiny::runApp()`
#' @export
run_app <- function() {
shiny::runApp(system.file("shiny", package = "aNCA"))
run_app <- function(...) {
require(aNCA)

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"), ...)
}
9 changes: 5 additions & 4 deletions R/utils-slope_selector.R
Original file line number Diff line number Diff line change
Expand Up @@ -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.")

Expand All @@ -39,7 +39,7 @@
# 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)
)
}

Expand Down Expand Up @@ -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 &
Expand Down
32 changes: 23 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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")
m-kolomanski marked this conversation as resolved.
Show resolved Hide resolved
```
in your R console.

### Via cloning the repository (for contributors)
Alternatively, you can set up the package by cloning the repository:
m-kolomanski marked this conversation as resolved.
Show resolved Hide resolved
```bash
git clone https://github.com/pharmaverse/aNCA.git
```
and then loading it directly using [devtools](https://github.com/r-lib/devtools):
m-kolomanski marked this conversation as resolved.
Show resolved Hide resolved
```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.
Expand Down
2 changes: 2 additions & 0 deletions inst/WORDLIST
Original file line number Diff line number Diff line change
Expand Up @@ -26,11 +26,13 @@ cmax
codebase
csv
customizable
devtools
df
ggplot
ggplots
lastdose
nca
pak
pharmacokinetic
pkcg
pknca
Expand Down
8 changes: 4 additions & 4 deletions inst/shiny/modules/slope_selector.R
Original file line number Diff line number Diff line change
Expand Up @@ -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)
})

Expand All @@ -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)

Expand Down Expand Up @@ -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)

Expand Down
Loading
Loading