-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3977cac
commit c62832a
Showing
60 changed files
with
6,105 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
^renv$ | ||
^renv\.lock$ | ||
^aNCA\.Rproj$ | ||
^\.Rproj\.user$ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
.Rproj.user | ||
.Rhistory | ||
.RData | ||
.Ruserdata | ||
aNCA.Rproj | ||
inst/guidelines | ||
inst/templates | ||
inst/shiny/data | ||
!inst/shiny/data/DummyRO_ADNCA.csv |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
* | ||
!inst/shiny/* | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
Package: aNCA | ||
Title: (Pre-)clinical NCA in a dynamic shiny app. | ||
Version: 0.0.0.9000 | ||
Authors@R: c( | ||
person("Ercan", "Suekuer", , "[email protected]", role = c("aut", "cre"), | ||
comment = c(ORCID = "0009-0001-1626-1526")), | ||
person("Gerardo Jose", "Rodriguez", , "[email protected]", role = "aut", | ||
comment = c(ORCID = "0000-0003-1413-0060")), | ||
person("Pascal", "Baertschi", , "[email protected]", role = "aut", | ||
comment = c(ORCID = "0000-0002-6533-0399")), | ||
person("Jana", "Spinner", , "[email protected]", role = "aut", | ||
comment = c(ORCID = "0009-0009-2197-9530")), | ||
person("F. Hoffmann-La Roche AG", role = c("cph", "fnd")) | ||
) | ||
Description: This application enables users to upload their datasets and | ||
perform Non-Compartment Analysis (NCA) on both pre-clinical and | ||
clinical datasets, with the results being easily visualizable. The NCA | ||
can be tailored to calculate pharmacokinetic parameters for various | ||
dosing regimens and time points, given certain restrictions. It also | ||
features manual slope selection, simplifying the process of conducting | ||
lambda-z-regression and PK-timepoint exclusions. Furthermore, the | ||
pharmacokinetic parameters can be dynamically visualized through | ||
customized graphics such as line and mean plots. The calculated | ||
pharmacokinetic parameters can be compiled in a dynamic table, | ||
visualized using boxplots, or exported as a comprehensive report. | ||
Designed with user-friendliness in mind, this app aims to make NCA | ||
accessible and straightforward for all scientists. | ||
License: MIT | ||
Imports: | ||
checkmate, | ||
dplyr, | ||
DT, | ||
forcats, | ||
ggplot2, | ||
haven, | ||
nestcolor, | ||
PKNCA, | ||
plotly, | ||
rio, | ||
rmarkdown, | ||
shiny, | ||
shinyBS, | ||
shinyjqui, | ||
shinyWidgets, | ||
stats, | ||
tern, | ||
tidyr, | ||
tools, | ||
utils, | ||
zip | ||
Encoding: UTF-8 | ||
Roxygen: list(markdown = TRUE) | ||
RoxygenNote: 7.3.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
# Generated by roxygen2: do not edit by hand | ||
|
||
export(anonymize_pk_data) | ||
export(app_server) | ||
export(app_ui) | ||
export(apply_filters) | ||
export(as_factor_preserve_label) | ||
export(calculate_summary_stats) | ||
export(create_conc) | ||
export(create_dose) | ||
export(create_filter) | ||
export(flexible_violinboxplot) | ||
export(format_data) | ||
export(general_lineplot) | ||
export(general_meanplot) | ||
export(geometric.mean) | ||
export(has_label) | ||
export(lambda_slope_plot) | ||
export(pptestcd_dict) | ||
export(reshape_PKNCA_results) | ||
export(run_app) | ||
export(set_empty_label) | ||
import(checkmate) | ||
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.nca) | ||
importFrom(PKNCA,pknca_units_table) | ||
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,pull) | ||
importFrom(dplyr,rename) | ||
importFrom(dplyr,rename_with) | ||
importFrom(dplyr,select) | ||
importFrom(dplyr,slice) | ||
importFrom(dplyr,summarise) | ||
importFrom(dplyr,ungroup) | ||
importFrom(dplyr,where) | ||
importFrom(ggplot2,aes) | ||
importFrom(ggplot2,facet_wrap) | ||
importFrom(ggplot2,geom_errorbar) | ||
importFrom(ggplot2,geom_line) | ||
importFrom(ggplot2,geom_point) | ||
importFrom(ggplot2,ggplot) | ||
importFrom(ggplot2,labs) | ||
importFrom(plotly,event_data) | ||
importFrom(plotly,plotlyOutput) | ||
importFrom(plotly,plotly_build) | ||
importFrom(plotly,renderPlotly) | ||
importFrom(rio,export_list) | ||
importFrom(rmarkdown,render) | ||
importFrom(shiny,actionButton) | ||
importFrom(shiny,checkboxInput) | ||
importFrom(shiny,column) | ||
importFrom(shiny,conditionalPanel) | ||
importFrom(shiny,downloadButton) | ||
importFrom(shiny,fileInput) | ||
importFrom(shiny,fluidPage) | ||
importFrom(shiny,fluidRow) | ||
importFrom(shiny,helpText) | ||
importFrom(shiny,icon) | ||
importFrom(shiny,insertUI) | ||
importFrom(shiny,mainPanel) | ||
importFrom(shiny,modalButton) | ||
importFrom(shiny,modalDialog) | ||
importFrom(shiny,navbarPage) | ||
importFrom(shiny,numericInput) | ||
importFrom(shiny,observeEvent) | ||
importFrom(shiny,plotOutput) | ||
importFrom(shiny,radioButtons) | ||
importFrom(shiny,reactiveVal) | ||
importFrom(shiny,reactiveValues) | ||
importFrom(shiny,removeUI) | ||
importFrom(shiny,renderUI) | ||
importFrom(shiny,req) | ||
importFrom(shiny,selectInput) | ||
importFrom(shiny,showModal) | ||
importFrom(shiny,sidebarLayout) | ||
importFrom(shiny,sidebarPanel) | ||
importFrom(shiny,tabPanel) | ||
importFrom(shiny,tags) | ||
importFrom(shiny,textInput) | ||
importFrom(shiny,uiOutput) | ||
importFrom(shiny,updateCheckboxInput) | ||
importFrom(shiny,updateNavbarPage) | ||
importFrom(shiny,updateNumericInput) | ||
importFrom(shiny,updateSelectInput) | ||
importFrom(shiny,updateTabsetPanel) | ||
importFrom(shinyBS,bsModal) | ||
importFrom(shinyFiles,shinyDirChoose) | ||
importFrom(shinyWidgets,dropdown) | ||
importFrom(shinyWidgets,pickerInput) | ||
importFrom(shinyWidgets,switchInput) | ||
importFrom(shinyWidgets,updatePickerInput) | ||
importFrom(shinyjqui,orderInput) | ||
importFrom(shinyjqui,updateOrderInput) | ||
importFrom(stats,sd) | ||
importFrom(tern,g_ipp) | ||
importFrom(tidyr,pivot_longer) | ||
importFrom(tidyr,pivot_wider) | ||
importFrom(tools,file_ext) | ||
importFrom(utils,read.csv) | ||
importFrom(utils,write.csv) | ||
importFrom(zip,zipr) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,166 @@ | ||
#' This function anonymizes RO numbers and Study IDs of pk data files. | ||
#' | ||
#' @import haven | ||
#' @import dplyr | ||
#' @import checkmate | ||
#' | ||
#' @param path path to dataframe in xpt, sas or csv format | ||
#' @param overwrite decides whether file at input location `path` is overwritten. default is TRUE | ||
#' | ||
#' @return anonymized dataframe file | ||
#' | ||
#' @export | ||
#' | ||
#' | ||
#'@author Pascal Bärtschi | ||
#' | ||
|
||
anonymize_pk_data <- function(path, | ||
drug_map = NULL, | ||
overwrite = TRUE){ | ||
|
||
# assert file | ||
checkmate::assert_file_exists(path) | ||
# if (!is.null(drug_map)){ | ||
# # check named vector | ||
# # checkmate::assert(checkNamed(drug_map)) | ||
# # # assert names of drug dict somewhere in values of dataframe (with regex) | ||
# # drug_regex <- paste(names(drug_map), collapse = "|") | ||
# # checkmate::assert(any(grep(drug_regex, strings))) | ||
# } | ||
|
||
|
||
# file extension | ||
extension <- str_split_i(path, "\\.", i = -1) | ||
|
||
# extension decision read-in | ||
if (extension == "csv"){ | ||
data <- read.csv(path) | ||
} else if (extension == "sas7bdat"){ | ||
data <- read_sas(path) | ||
} else if (extension == "xpt"){ | ||
data <- read_xpt(path) | ||
} else { | ||
stop("This file extension is not supported yet.") | ||
} | ||
|
||
#assert data loading | ||
checkmate::assert(checkDataFrame(data)) | ||
|
||
# find all ronumbers | ||
all_ronum <- lapply(X = data, FUN = function(x) str_extract(x, "\\bRO\\d{7}\\b")) %>% | ||
unlist() %>% | ||
unique() %>% | ||
na.omit() | ||
|
||
# find all tracknumbers | ||
all_tracknum <- lapply(X = data, FUN = function(x) str_extract(x, "\\bTrack\\d{2}\\b")) %>% | ||
unlist() %>% | ||
unique() %>% | ||
na.omit() | ||
|
||
all_studyid <- lapply(X = data, FUN = function(x) str_extract(x, "\\b..\\d{5}\\b")) %>% | ||
unlist() %>% | ||
unique() %>% | ||
na.omit() | ||
|
||
if (length(all_ronum) > 0){ | ||
# instead of seq along, generate random numbers with 7 digits | ||
ronum_map <- setNames(paste0("Analyte", sprintf("%02d", seq_along(all_ronum))), | ||
all_ronum) | ||
} else { | ||
ronum_map <- character(0) | ||
} | ||
|
||
if (length(all_tracknum) > 0){ | ||
# instead of seq along, generate random numbers with 7 digits | ||
tracknum_map <- setNames(paste0("Analyte", sprintf("%02d", seq_along(all_tracknum))), | ||
all_tracknum) | ||
} else { | ||
tracknum_map <- character(0) | ||
} | ||
|
||
if (length(all_studyid) > 0){ | ||
studyid_map <- setNames(paste0("XX", sprintf("%02d", seq_along(all_studyid))), | ||
all_studyid) | ||
} else { | ||
studyid_map <- character(0) | ||
} | ||
|
||
|
||
|
||
# checkmate::assert(checkVector(ronum_map, min.len = 1), | ||
# checkVector(studyid_map, min.len = 1), | ||
# combine = "and") | ||
|
||
# concatenate the maps | ||
concat_map <- c(ronum_map, studyid_map, tracknum_map, drug_map) | ||
|
||
# function to replace according to the map | ||
replace_str_with_map <- function(x, map) { | ||
for (str_ in names(map)) { | ||
x <- gsub(str_, map[[str_]], x) | ||
} | ||
return(x) | ||
} | ||
|
||
# columns required for NCA | ||
req4nca <- c("STUDYID", "USUBJID", "ANALYTE", "PCSPEC", "DOSEFRQ", 'DOSNO', "AFRLT", "ARRLT", "NRRLT", "NFRLT", "PCSTRESC", "PARAM", "TAU", | ||
"PCSTRESU", "ROUTE", "DOSEA", "AGE", "SEX", "RACE", "ADOSEDUR", 'DOSEDURU', "NDOSEDUR", "RRLTU", "DOSEA", "DOSEU", "PCLLOQ", "DRUG", | ||
"AVISIT", "AVAL", "AVALU", "DOSEU", "EVID", "ATPTREF", "SITEID", "TRT01A", "TRT01P", "PCRFTDTM", "WTBL", "WTBLU", "HTBL", "HTBLU") | ||
|
||
# mutate and rename | ||
data <- data %>% | ||
# apply the map to all columns that hold RO and STUDYNUMBERS | ||
mutate_all(~replace_str_with_map(., concat_map)) %>% | ||
rename_with(~replace_str_with_map(., concat_map)) %>% | ||
# select only columns that are needed to perform NCA | ||
select(any_of(req4nca)) | ||
|
||
# find the req4nca columns that are not in data | ||
if (setdiff(req4nca, colnames(data)) %>% length > 0){ | ||
message(paste("The dataframe with path", path, | ||
"is missing the following colnames: ", | ||
paste(setdiff(req4nca, colnames(data)), collapse = ", "))) | ||
} | ||
|
||
# compose a message warning that the unique values of start_with("TRT") are ... and that DRUG names have to anonymized by hand | ||
if (any(grepl("TRT", colnames(data)))){ | ||
message(paste("The unique values of the columns starting with TRT are: ", data %>% | ||
select(all_of(data %>% | ||
select(starts_with("TRT")) %>% | ||
colnames(.))) %>% | ||
unique() %>% | ||
paste(., collapse = ", "), toupper(". Please make sure to replace drugnames!"))) | ||
|
||
} | ||
|
||
|
||
# save the file | ||
if (extension == "csv"){ | ||
if (overwrite){ | ||
write.csv(data, path, row.names = F) | ||
} else { | ||
write.csv(data, paste0(gsub(".csv", "", path), "_anonymized.csv"), row.names = F) | ||
} | ||
} else if (extension == "sas7bdat"){ | ||
if (overwrite){ | ||
write_xpt(data, gsub(".sas7bdat", ".xpt", path)) | ||
file.remove(path) | ||
message("The sas7bdat file was converted to xpt and the original file was removed, as the sas7bdat format was deprecated in haven.") | ||
} else { | ||
write_xpt(data, paste0(gsub(".sas7bdat", "", path), "_anonymized.xpt")) | ||
file.remove(path) | ||
message("The sas7bdat file was converted to xpt and the original file was removed, as the sas7bdat format was deprecated in haven.") | ||
} | ||
} else if (extension == "xpt"){ | ||
if (overwrite){ | ||
write_xpt(data, path) | ||
} else { | ||
write_xpt(data, paste0(gsub(".xpt", "", path), "_anonymized.xpt")) | ||
} | ||
} | ||
|
||
} | ||
#*~*# | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
#' Server function for the Shiny app | ||
#' | ||
#' @import shiny | ||
#' @importFrom shiny observeEvent reactiveVal reactiveValues insertUI removeUI updateSelectInput updateNavbarPage updateTabsetPanel updateCheckboxInput updateNumericInput showModal modalDialog textInput actionButton modalButton numericInput renderUI req | ||
#' @importFrom dplyr mutate filter select group_by summarise pull arrange ungroup rename_with across case_when left_join rename | ||
#' @importFrom tools file_ext | ||
#' @importFrom DT renderDataTable datatable formatStyle styleEqual | ||
#' @importFrom PKNCA PKNCAconc PKNCAdose PKNCAdata pk.nca PKNCA.options pknca_units_table | ||
#' @importFrom utils read.csv write.csv | ||
#' @importFrom plotly renderPlotly plotlyOutput plotly_build event_data | ||
#' @importFrom shinyWidgets pickerInput switchInput updatePickerInput | ||
#' @importFrom shinyjqui orderInput | ||
#' @importFrom ggplot2 ggplot geom_errorbar geom_point geom_line labs aes facet_wrap | ||
#' @importFrom zip zipr | ||
#' @importFrom rio export_list | ||
#' @importFrom rmarkdown render | ||
#' @importFrom shinyFiles shinyDirChoose | ||
#' | ||
#' @export | ||
app_server <- function(input, output, session) { | ||
source(system.file("shiny/server.R", package = "aNCA"), local = TRUE)$value(input, output, session) | ||
} |
Oops, something went wrong.