diff --git a/.github/workflows/R-CMD-check-main.yaml b/.github/workflows/R-CMD-check-main.yaml new file mode 100644 index 00000000..9fe2e60d --- /dev/null +++ b/.github/workflows/R-CMD-check-main.yaml @@ -0,0 +1,46 @@ +# Run R CMD Check on PR to dev + +on: + pull_request: + branches: + - main + +name: R-CMD-check + +jobs: + R-CMD-check: + runs-on: macOS-latest + env: + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + steps: + - uses: actions/checkout@v2 + - uses: r-lib/actions/setup-r@v1 + - name: Install dependencies + run: | + install.packages(c("remotes", "rcmdcheck")) + remotes::install_deps(dependencies = TRUE) + shell: Rscript {0} + - name: Find PhantomJS path + id: phantomjs + run: | + echo "::set-output name=path::$(Rscript -e 'cat(shinytest:::phantom_paths()[[1]])')" + - name: Cache PhantomJS + uses: actions/cache@v2 + with: + path: ${{ steps.phantomjs.outputs.path }} + key: ${{ matrix.config.os }}-phantomjs + restore-keys: ${{ matrix.config.os }}-phantomjs + - name: Install PhantomJS + shell: Rscript {0} + run: | + options(install.packages.check.source = "no") + if (!shinytest::dependenciesInstalled()) shinytest::installDependencies() + - name: Check + env: + _R_CHECK_CRAN_INCOMING_: false + run: rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran", "--ignore-vignettes"), build_args = c("--no-build-vignettes"), error_on = "warning", check_dir = "check") + shell: Rscript {0} + - name: Show testthat output + if: always() + run: find check -name 'testthat.Rout*' -exec cat '{}' \; || true + shell: bash diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index bd25402d..ca9bc8a9 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -38,7 +38,7 @@ jobs: - name: Check env: _R_CHECK_CRAN_INCOMING_: false - run: rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran"), error_on = "warning", check_dir = "check") + run: rcmdcheck::rcmdcheck(args = c("--no-manual", "--as-cran", "--ignore-vignettes"), build_args = c("--no-build-vignettes"), error_on = "warning", check_dir = "check") shell: Rscript {0} - name: Show testthat output if: always() diff --git a/DESCRIPTION b/DESCRIPTION index d15e10ff..4e502d36 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -8,7 +8,7 @@ Authors@R: c( person("Xiao","Ni", role = "aut"), person("James","Buchanan", role="aut"), person("Susan","Duke", role="aut")) -Maintainer: Jeremy Wildfire +Maintainer: Jeremy Wildfire Description: A framework for evaluation of clinical trial safety. Users can interactively explore their data using the 'Shiny' application or create standalone 'htmlwidget' charts. Interactive charts are built using 'd3.js' and 'webcharts.js' 'JavaScript' libraries. URL: https://github.com/SafetyGraphics/safetyGraphics BugReports: https://github.com/SafetyGraphics/safetyGraphics/issues @@ -16,42 +16,34 @@ Depends: R (>= 3.5) License: MIT + file LICENSE Encoding: UTF-8 LazyData: true -RoxygenNote: 7.1.1 +RoxygenNote: 7.1.2 Suggests: - fs, - ggplot2, - knitr, - plotly, - rmarkdown, - markdown, - rstudioapi, - rprojroot, - shinydashboard, - shinyFiles, - shinytest, - testthat, - usethis + ggplot2 (>= 3.3.0), + knitr (>= 1.34), + rmarkdown (>= 2.10), + shinydashboard (>= 0.7.1), + shinytest (>= 1.5.0), + testthat (>= 3.0.4), + usethis (>= 2.0.1), + listviewer (>= 3.0.0), + shinybusy (>= 0.2.2), + shinyWidgets (>= 0.6.1) Imports: - dplyr, - DT, - datamods, - htmlwidgets, - jsonlite, - listviewer, - magrittr, - pharmaRTF, - purrr, - rclipboard, - rlang, - safetyData, - safetyCharts, - shiny, - shinyjs, - shinyWidgets, - sortable, - stringr, - yaml, - shinybusy -Remotes: safetyGraphics/safetyCharts + dplyr (>= 1.0.0), + DT (>= 0.19), + datamods (>= 1.1.5), + htmlwidgets (>= 1.5.0), + jsonlite (>= 1.7.0), + magrittr (>= 2.0.0), + purrr (>= 0.3.0), + rclipboard (>= 0.1.3), + rlang (>= 0.4.11), + safetyData (>= 1.0.0), + safetyCharts (>= 0.2), + shiny (>= 1.6.0), + shinyjs (>= 2.0.0), + sortable (>= 0.4.4), + stringr (>= 1.4.0), + yaml (>= 2.2.1) VignetteBuilder: knitr Roxygen: list(markdown = TRUE) diff --git a/NAMESPACE b/NAMESPACE index ba3befaa..6259b329 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -52,18 +52,12 @@ import(safetyData) import(shiny) import(yaml) importFrom(DT,renderDT) -importFrom(listviewer,jsonedit) -importFrom(listviewer,jsoneditOutput) -importFrom(listviewer,renderJsonedit) importFrom(purrr,keep) importFrom(purrr,map) importFrom(purrr,map2) importFrom(rlang,.data) importFrom(shiny,dataTableOutput) importFrom(shiny,renderDataTable) -importFrom(shinyWidgets,progressBar) -importFrom(shinyWidgets,updateProgressBar) -importFrom(shinybusy,add_busy_spinner) importFrom(shinyjs,addClass) importFrom(shinyjs,delay) importFrom(shinyjs,disable) diff --git a/NEWS.md b/NEWS.md index ab8a59dc..4a1bf14d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -10,4 +10,4 @@ The first production release of safetyGraphics includes many improvements includ Initial CRAN release for safetyGraphics. The safetyGraphics package provides framework for evaluation of clinical trial safety. Users can interactively explore their data using the 'Shiny' application or create standalone 'htmlwidget' charts. Interactive charts are built using 'd3.js' and 'webcharts.js' 'JavaScript' libraries. -See the [GitHub release tracker](https://github.com/ASA-DIA-InteractiveSafetyGraphics/safetyGraphics/releases) for additional release documentation and links to issues. \ No newline at end of file +See the [GitHub release tracker](https://github.com/safetyGraphics/safetyGraphics/releases) for additional release documentation and links to issues. \ No newline at end of file diff --git a/R/app_startup.R b/R/app_startup.R index 818f1ceb..bf9f9d90 100644 --- a/R/app_startup.R +++ b/R/app_startup.R @@ -8,7 +8,7 @@ #' @param mapping list specifying the initial mapping values for each data mapping for each domain (e.g. list(aes= list(id_col='USUBJID', seq_col='AESEQ')). #' @param autoMapping boolean indicating whether the app should attempt to automatically detect data standards and generate mappings for the data provided. Values specified in the `mapping` parameter overwrite automatically generated mappings when both are found. Defaults to true. #' @param filterDomain domain used for the data/filter tab. Demographics ("`dm`") is used by default. Using a domain that is not one record per participant is not recommended. -#' @param chartSettingsPaths path(s) where customization functions are saved relative to your working directory. All charts can have itialization (e.g. myChart_Init.R) and static charts can have charting functions (e.g. myGraphic_Chart.R). All R files in this folder are sourced and files with the correct naming convention are linked to the chart. See the Custom Charts vignette for more details. +#' @param chartSettingsPaths path(s) where customization functions are saved relative to your working directory. All charts can have initialization (e.g. myChart_Init.R) and static charts can have charting functions (e.g. myGraphic_Chart.R). All R files in this folder are sourced and files with the correct naming convention are linked to the chart. See the Custom Charts vignette for more details. #' #' #' @return List of elements for used to initialize the shiny app with the following parameters diff --git a/R/makeChartExport.R b/R/makeChartExport.R index a911decb..ef4f2d85 100644 --- a/R/makeChartExport.R +++ b/R/makeChartExport.R @@ -3,7 +3,7 @@ #' Creates R code that allows chart to be exported #' #' @param chart chart object like the one generated by makeChartConfig(). -#' @param mapping mapping object like the one generatedf by makeMapping(). +#' @param mapping mapping object like the one generated by makeMapping(). #' #' @import purrr #' @importFrom yaml as.yaml diff --git a/R/mod_filterTab.R b/R/mod_filterTab.R index aa31ad70..2cc6ec66 100644 --- a/R/mod_filterTab.R +++ b/R/mod_filterTab.R @@ -9,7 +9,13 @@ filterTabUI <- function(id){ ns <- NS(id) - + if(isNamespaceLoaded("shinyWidgets")){ + countObj<- shinyWidgets::progressBar( + id = ns("pbar"), value = 100, + total = 100, display_pct = TRUE + ) + } + filter_ui<-list( h1(paste("Participant Selector")), span("This page dynamically filters participants across all data domains. Only the selected participants are included in charts."), @@ -20,10 +26,7 @@ filterTabUI <- function(id){ ), column( width = 9, - progressBar( - id = ns("pbar"), value = 100, - total = 100, display_pct = TRUE - ), + countObj, DT::dataTableOutput(outputId = ns("table")), tags$p("Code dplyr:"), verbatimTextOutput(outputId = ns("code_dplyr")), @@ -52,7 +55,6 @@ filterTabUI <- function(id){ #' @return filtered data set #' #' @import datamods -#' @importFrom shinyWidgets progressBar updateProgressBar #' @importFrom shinyjs show hide #' @importFrom shiny renderDataTable #' @@ -68,7 +70,6 @@ filterTab <- function(input, output, session, domainData, filterDomain, current_ req(filterCheck()) shinyjs::show(selector = paste0(".navbar li a[data-value=",tabID,"]")) shinyjs::show(selector = paste0(".navbar #population-header")) - domainData[[filterDomain]] }) @@ -86,11 +87,13 @@ filterTab <- function(input, output, session, domainData, filterDomain, current_ ) observeEvent(res_filter$filtered(), { - updateProgressBar( - session = session, - id = "pbar", - value = nrow(res_filter$filtered()), total = nrow(raw()) - ) + if(isNamespaceLoaded("shinyWidgets")){ + shinyWidgets::updateProgressBar( + session = session, + id = "pbar", + value = nrow(res_filter$filtered()), total = nrow(raw()) + ) + } shinyjs::html( "header-count", diff --git a/R/mod_filterTabChecks.R b/R/mod_filterTabChecks.R index 5d93abbc..91bfd20f 100644 --- a/R/mod_filterTabChecks.R +++ b/R/mod_filterTabChecks.R @@ -4,7 +4,7 @@ #' @param filterDomain domain to use for filtering (typically "dm") #' @param current_mapping current data mapping (REACTIVE) #' -#' @return reactive that returns a boolean indicating whether the checks passed and filtering can be initiailized +#' @return reactive that returns a boolean indicating whether the checks passed and filtering can be initialized #' #' @export diff --git a/R/mod_homeTab.R b/R/mod_homeTab.R index cea29776..06f83ede 100644 --- a/R/mod_homeTab.R +++ b/R/mod_homeTab.R @@ -32,7 +32,7 @@ homeTab <- function(input, output, session){

Using the app

- Detailed instructions about using the app can be found in our vignette. + Detailed instructions about using the app can be found in our vignette. In short, the user will initialize the app with their data, adjust settings as needed, and view the interactive charts. Finally, the user may export a self-contained, fully reproducible snapshot of the charts that can be easily shared with others.

@@ -40,8 +40,8 @@ homeTab <- function(input, output, session){

Charts

The app is built to support a wide variety of chart types including static plots (e.g. from {ggplot2}), shiny modules, {htmlwidgets} and even static outputs like RTFs. - Several pre-configured charts are included in the companion {safetyCharts} R Package, and are available by default in the app. - Other charts can be added using the process descibed in this vignette. + Several pre-configured charts are included in the companion {safetyCharts} R Package, and are available by default in the app. + Other charts can be added using the process descibed in this vignette.

diff --git a/R/mod_safetyGraphicsUI.R b/R/mod_safetyGraphicsUI.R index db044db5..02f5dc6e 100644 --- a/R/mod_safetyGraphicsUI.R +++ b/R/mod_safetyGraphicsUI.R @@ -8,7 +8,6 @@ #' @param standards a list of information regarding data standards. Each list item should use the format returned by safetyGraphics::detectStandard. #' #' @importFrom shinyjs useShinyjs -#' @importFrom shinybusy add_busy_spinner #' #' @export @@ -30,11 +29,16 @@ safetyGraphicsUI <- function(id, meta, domainData, mapping, standards){ header.append('

/
');" ) ) - + if(isNamespaceLoaded("shinybusy")){ + spinner<-shinybusy::add_busy_spinner(spin = "atom", position="bottom-right") + }else{ + spinner<-NULL + } + #app UI using calls to modules ui<-tagList( shinyjs::useShinyjs(), - add_busy_spinner(spin = "atom", position="bottom-right"), + spinner, tags$head( tags$style(app_css), tags$link( diff --git a/R/mod_settingsCharts.R b/R/mod_settingsCharts.R index 2d69976d..98fafc9d 100644 --- a/R/mod_settingsCharts.R +++ b/R/mod_settingsCharts.R @@ -2,11 +2,23 @@ #' #' @param id module id #' -#' @importFrom listviewer jsoneditOutput #' @export settingsChartsUI <- function(id){ ns <- NS(id) + if(isNamespaceLoaded("listviewer")){ + tabs<-tabsetPanel( + tabPanel("List Explorer", listviewer::jsoneditOutput(ns("chartObj"), height = "800px")), + tabPanel("Verbatim", verbatimTextOutput(ns("chartList"))), + tabPanel("YAML", verbatimTextOutput(ns("chartYAML"))) + ) + }else{ + tabs<- tabsetPanel( + tabPanel("Verbatim", verbatimTextOutput(ns("chartList"))), + tabPanel("YAML", verbatimTextOutput(ns("chartYAML"))) + ) + } + list( br(), p( @@ -14,11 +26,7 @@ settingsChartsUI <- function(id){ "Full details regarding the charts are shown below. Charts specifications are saved in an R list, and can be exported for re-use on the settings/code tab. ", class="info" ), - tabsetPanel( - tabPanel("jsonedit View", listviewer::jsoneditOutput(ns("chartObj"), height = "800px") ), - tabPanel("Verbatim", verbatimTextOutput(ns("chartList"))), - tabPanel("YAML", verbatimTextOutput(ns("chartYAML"))) - ) + tabs ) } @@ -29,17 +37,17 @@ settingsChartsUI <- function(id){ #' @param session Shiny session object #' @param charts list data frame summarizing the charts #' -#' @importFrom listviewer renderJsonedit jsonedit #' @import dplyr #' #' @export settingsCharts <- function(input, output, session, charts){ ns <- session$ns - - output$chartObj <- listviewer::renderJsonedit({ - listviewer::jsonedit(charts) - }) + if(isNamespaceLoaded("listviewer")){ + output$chartObj <- listviewer::renderJsonedit({ + listviewer::jsonedit(charts) + }) + } output$chartList <- renderPrint({ print(charts) diff --git a/R/prepareChart.R b/R/prepareChart.R index e2bf72a0..7e795d9a 100644 --- a/R/prepareChart.R +++ b/R/prepareChart.R @@ -1,4 +1,4 @@ -#' Prepare a chart object for safetyGraphcis +#' Prepare a chart object for safetyGraphics #' #' Sets default values and binds needed functions to a chart object based on chart type. #' diff --git a/R/safetyGraphics.R b/R/safetyGraphics.R index 3e2cd3e6..f4c5c122 100644 --- a/R/safetyGraphics.R +++ b/R/safetyGraphics.R @@ -4,7 +4,7 @@ #' #' Learn more on #' \href{https://CRAN.R-project.org/package=safetyGraphics}{CRAN} -#' or \href{https://github.com/ASA-DIA-InteractiveSafetyGraphics/safetyGraphics}{GitHub} +#' or \href{https://github.com/SafetyGraphics/safetyGraphics}{GitHub} #' #' @docType package #' @name SafetyGraphics diff --git a/R/safetyGraphicsApp.R b/R/safetyGraphicsApp.R index 1b90206c..024e922c 100644 --- a/R/safetyGraphicsApp.R +++ b/R/safetyGraphicsApp.R @@ -6,7 +6,7 @@ #' @param mapping list specifying the initial mapping values for each data mapping for each domain (e.g. list(aes= list(id_col='USUBJID', seq_col='AESEQ')). #' @param autoMapping boolean indicating whether the app should attempt to automatically detect data standards and generate mappings for the data provided. Values specified in the `mapping` parameter overwrite automatically generated mappings when both are found. Defaults to true. #' @param filterDomain domain used for the data/filter tab. Demographics ("`dm`") is used by default. Using a domain that is not one record per participant is not recommended. -#' @param chartSettingsPaths path(s) where customization functions are saved relative to your working directory. All charts can have itialization (e.g. myChart_Init.R) and static charts can have charting functions (e.g. myGraphic_Chart.R). All R files in this folder are sourced and files with the correct naming convention are linked to the chart. See the Custom Charts vignette for more details. +#' @param chartSettingsPaths path(s) where customization functions are saved relative to your working directory. All charts can have initialization (e.g. myChart_Init.R) and static charts can have charting functions (e.g. myGraphic_Chart.R). All R files in this folder are sourced and files with the correct naming convention are linked to the chart. See the Custom Charts vignette for more details. #' #' @import shiny #' @import safetyData diff --git a/README.md b/README.md index a62df0da..0253c04d 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ - [![R build status](https://github.com/ASA-DIA-InteractiveSafetyGraphics/safetyGraphics/workflows/R-CMD-check/badge.svg)](https://github.com/ASA-DIA-InteractiveSafetyGraphics/safetyGraphics/actions) + [![R build status](https://www.github.com/safetyGraphics/safetyGraphics/workflows/R-CMD-check-main/badge.svg)](https://github.com/SafetyGraphics/safetyGraphics/actions) # safetyGraphics: Clinical Trial Monitoring with R -The {safetyGraphics} package provides a framework for the evaluation of clinical trial safety data in R using a flexible data pipeline. The package includes a shiny application that allows users to explore safety data using a series of interactive graphics, including the hepatic safety explorer shown below. The package has been developed as part of the Interactive Safety Graphics (ISG) workstream of the ASA Biopharm-DIA Safety Working Group. +The {safetyGraphics} package provides a framework for evaluating of clinical trial safety in R using a flexible data pipeline. The package includes a shiny application that allows users to explore safety data using a series of interactive graphics, including the hepatic safety explorer shown below. The package has been developed as part of the Interactive Safety Graphics (ISG) workstream of the ASA Biopharm-DIA Safety Working Group. ![edishgif](https://user-images.githubusercontent.com/3680095/45834450-02b3a000-bcbc-11e8-8172-324c2fe43521.gif) @@ -13,15 +13,15 @@ The {safetyGraphics} package provides a framework for the evaluation of clinical A demo of the app using sample data is available [here](https://jwildfire.shinyapps.io/safetyGraphics/) or can be initialized as follows: ```r -devtools::install_github("SafetyGraphics/safetyGraphics") +install.packages("safetyGraphics") library("safetyGraphics") safetyGraphicsApp() #open the shiny application ``` The most common workflow is for a user to initialize the app with their data, adjust settings as needed, and view the interactive charts. Finally, the user can share any chart by exporting its source code or by generating a self-contained, fully reproducible report that can be shared with others. -Instructions for loading study data are provided in the introductory vignette and more complex customizations are provided in the cookbook vignette. +Instructions for loading study data are provided in the introductory vignette and more complex customizations are provided in the cookbook vignette. # Charts -The app is built to support a wide variety of chart types including static plots (e.g. from {ggplot2}), shiny modules, {htmlwidgets} and even static outputs like RTFs. Several pre-configured charts are included in the companion {safetyCharts} R Package, and are available by default in the app. Other charts can be added using the process descibed in this vignette. +The app is built to support a wide variety of chart types including static plots (e.g. from {ggplot2}), shiny modules, {htmlwidgets} and even static outputs like RTFs. Several pre-configured charts are included in the companion {safetyCharts} R Package, and are available by default in the app. Other charts can be added using the process descibed in this vignette. diff --git a/docs/articles/Cookbook.html b/docs/articles/Cookbook.html index 24121fd4..8c1cafed 100644 --- a/docs/articles/Cookbook.html +++ b/docs/articles/Cookbook.html @@ -88,13 +88,13 @@ -
+