Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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: 2 additions & 0 deletions .Rbuildignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,5 @@ cran-comments.md
^LICENSE\.md$
^CRAN-RELEASE$
^CRAN-SUBMISSION$
^docs$
^inst/sandbox$
8 changes: 3 additions & 5 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
Package: safetyCharts
Title: Charts for Monitoring Clinical Trial Safety
Version: 0.4.0
Version: 0.5.0
Authors@R:
person(
given = "Jeremy",
Expand All @@ -9,13 +9,13 @@ Authors@R:
email = "jwildfire@gmail.com"
)
Maintainer: Jeremy Wildfire <jwildfire@gmail.com>
Description: Contains chart code for monitoring clinical trial safety. Charts can be used as standalone output, but are also designed for use with the 'safetyGraphics' package, which makes it easy to load data and customize the charts using an interactive web-based interface created with Shiny.
Description: Contains chart code for monitoring clinical trial safety. Charts can be used as standalone output, but are also designed for use with the 'safetyGraphics' package, which makes it easy to load data and customize the charts using an interactive web-based interface created with 'Shiny'.
URL: https://github.com/SafetyGraphics/safetyCharts
BugReports: https://github.com/SafetyGraphics/safetyCharts/issues
License: MIT + file LICENSE
Encoding: UTF-8
LazyData: true
RoxygenNote: 7.2.3
RoxygenNote: 7.3.2
Roxygen: list(markdown = TRUE)
Imports:
dplyr,
Expand All @@ -34,15 +34,13 @@ Imports:
rlang,
shiny,
stringr,
Tendril,
tibble,
tidyr,
Tplyr
Suggests:
testthat,
shinytest,
safetyData,
safetyGraphics,
yaml
Depends:
R (>= 4.0)
1 change: 0 additions & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import(shiny)
importFrom(DT,DTOutput)
importFrom(DT,renderDT)
importFrom(RColorBrewer,brewer.pal)
importFrom(Tendril,Tendril)
importFrom(dplyr,left_join)
importFrom(dplyr,select)
importFrom(forcats,fct_drop)
Expand Down
31 changes: 31 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,34 @@
# safetyCharts v0.5.0 (Upcoming)

This is the first release since v0.3.0 and is the release that returns safetyCharts to CRAN.

## Removed: the Tendril Plot

- The `Tendril` package was archived from CRAN on 2026-03-25 ("issues were not corrected despite reminders") and has had no release since 2020. Because safetyCharts imported it, safetyCharts was archived the same day, and safetyGraphics was archived for importing safetyCharts.
- `Tendril` has been dropped from `Imports`. That is the whole reason both packages could not stay on CRAN, and dropping it is what lets them return.
- The Tendril Plot has been removed from the chart list (`inst/config/tendril.yaml` deleted), so it no longer appears in the safetyGraphics Shiny application.
- `tendril_chart()` is still exported and still documented, but it is now defunct: calling it raises an error explaining what happened and how to draw the chart directly with the archived `Tendril` package. Existing code gets an explanation rather than an "object not found" error.
- The last working implementation remains in version control at the `v0.4.0` tag.

## Packaging changes for the CRAN resubmission

- `safetyGraphics` has been dropped from `Suggests`. It was never used by any code, test or vignette in this package, and because safetyGraphics imports safetyCharts the declaration was circular: with both packages archived, neither could be checked until one of them stopped requiring the other.
- The pkgdown output directory `docs/` is now listed in `.Rbuildignore`, so it is no longer shipped inside the source tarball.
- `aeExplorer()`, `hepExplorer()`, `paneledOutlierExplorer()` and `render_widget()` now document their return values. CRAN asks for a return value on every exported function, and these four had none.
- The examples for `aeExplorer()`, `hepExplorer()` and `paneledOutlierExplorer()` now run. They were wrapped in `\dontrun{}`, which was not warranted — each renders in well under a second. They are guarded with `@examplesIf requireNamespace("safetyData")` instead, because `safetyData` is a Suggests.

## New since the v0.3.0 CRAN release

These changes were made after v0.3.0 and released on GitHub as v0.4.0 (2024-09-20). They reach CRAN for the first time in this release.

- New charts and modules: `aeExplorer()`, `paneledOutlierExplorer()`, `init_cmExplorer()`, `init_mhExplorer()`.
- New event-stacking utilities: `stack_events()` and `standardize_events()`, for combining event domains into a single timeline-ready data frame.
- New chart configurations: concomitant medications (`cmExplorer`), medical history (`mhExplorer`) and vitals over time (`safetyVitalsOverTime`).
- New chart metadata data sets: `meta_cm`, `meta_ex`, `meta_mh`, `meta_vitals`.
- The `%>%` pipe is now re-exported.
- `aeExplorer()` renders without a treatment column, and treatment-column handling accepts both `NULL` and `""`.
- Chart configuration YAML cleaned up, `NAMESPACE` warnings fixed, and `htmltools`, `magrittr`, `tibble` and `tidyr` added to `Imports` to declare dependencies that were already in use.

# safetyCharts v0.3

This release adds several new features and bug fixes. New features include:
Expand Down
7 changes: 4 additions & 3 deletions R/aeExplorer.R
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,7 @@
#' For more options see the [full specs](https://github.com/RhoInc/aeexplorer/wiki/Configuration) in
#' the JavaScript library.
#'
#' @examples
#' \dontrun{
#' @examplesIf requireNamespace("safetyData", quietly = TRUE)
#' # Render widget with defaults.
#' aeExplorer()
#'
Expand All @@ -48,13 +47,15 @@
#' )
#' )
#' )
#' }
#'
#' @param data `list` Named list of data frames that includes participant-level subject data (`dm`)
#' and event-level adverse event data (`aes`).
#' @param mapping `list` Named list with current data mappings. See details for default mapping.
#' @param ... additional options to be added to mapping. Will overwrite mapping.
#'
#' @return An `htmlwidget` object of class `aeExplorer`, ready to print in the
#' RStudio viewer, embed in R Markdown, or render inside a Shiny application.
#'
#' @importFrom purrr list_modify
#'
#' @export
Expand Down
23 changes: 16 additions & 7 deletions R/hepExplorer.R
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,27 @@
#'
#' For more options see the [full specs](https://github.com/SafetyGraphics/hep-explorer/wiki/Configuration) in the javascript library.
#'
#' @examples
#' \dontrun{
#' @examplesIf requireNamespace("safetyData", quietly = TRUE)
#' # A 20-subject slice of the bundled lab data. The examples below use it so
#' # that each one renders in a fraction of a second; `hepExplorer()` with no
#' # arguments uses all 254 subjects of `safetyData::adam_adlbc`.
#' adlbc <- safetyData::adam_adlbc
#' adlbc <- adlbc[adlbc$USUBJID %in% unique(adlbc$USUBJID)[1:20], ]
#'
#' # Render widget with defaults
#' hepExplorer()
#' hepExplorer(data = adlbc)
#'
#' # Add age group to default
#' hepExplorer(group_cols=c("SEX","AGEGR1"))
#' hepExplorer(data = adlbc, group_cols=c("SEX","AGEGR1"))
#'
#' # Enable interactive y-axis
#' hepExplorer(y_options='all')
#' hepExplorer(data = adlbc, y_options='all')
#'
#' # Use custom mapping for SDTM data
#' lb <- safetyData::sdtm_lb
#' lb <- lb[lb$USUBJID %in% unique(lb$USUBJID)[1:20], ]
#' hepExplorer(
#' data=safetyData::sdtm_lb,
#' data=lb,
#' measure_col = "LBTEST",
#' measure_values = list(
#' ALT = "Alanine Aminotransferase",
Expand All @@ -64,12 +71,14 @@
#' visit_col = "VISIT",
#' visitn_col = "VISITNUM"
#' )
#' }
#'
#' @param data `data.frame` Data frame containing lab data used to render `hepExplorer`. Default: `safetyData::adam_adlbc`
#' @param mapping `list` named list with the current data mappings. See details for default mapping.
#' @param ... additional options to be added to mapping. Will overwrite mapping.
#'
#' @return An `htmlwidget` object of class `hepExplorer`, ready to print in the
#' RStudio viewer, embed in R Markdown, or render inside a Shiny application.
#'
#' @importFrom purrr list_modify
#'
#' @export
Expand Down
20 changes: 15 additions & 5 deletions R/paneledOutlierExplorer.R
Original file line number Diff line number Diff line change
Expand Up @@ -42,33 +42,43 @@
#'
#' For more options see the [full specs](https://github.com/rhoinc/paneled-outlier-explorer/wiki/Configuration) in the javascript library.
#'
#' @examples
#' \dontrun{
#' @examplesIf requireNamespace("safetyData", quietly = TRUE)
#' # A 20-subject slice of the bundled lab data. The examples below use it so
#' # that each one renders in a fraction of a second; `paneledOutlierExplorer()`
#' # with no arguments uses all 254 subjects of `safetyData::adam_adlbc`.
#' adlbc <- safetyData::adam_adlbc
#' adlbc <- adlbc[adlbc$USUBJID %in% unique(adlbc$USUBJID)[1:20], ]
#'
#' # Render widget with defaults
#' paneledOutlierExplorer()
#' paneledOutlierExplorer(df = adlbc)
#'
#' # Add Sex and Age Filters
#' paneledOutlierExplorer(
#' df = adlbc,
#' filters=list(
#' list(value_col="SEX"),
#' list(value_col="AGEGR1",label="Age")
#' )
#' )
#'
#' # customize panel size (in pixels)
#' paneledOutlierExplorer(multiples_sizing=list("width"= 500,"height"= 300))
#' paneledOutlierExplorer(df = adlbc, multiples_sizing=list("width"= 500,"height"= 300))
#'
#' # customize default normal range
#' paneledOutlierExplorer(
#' df = adlbc,
#' normal_range_method = 'quantiles',
#' normal_range_quantile_low = 0.2,
#' normal_range_quantile_high = 0.8,
#' )
#' }
#' @param df data frame containing lab data used to render for paneledOutlierExplorer. Default is safetyData::adam_adlbc.
#' @param mapping named list with the current data mappings. See details for default mapping.
#' @param ... additional options to be added to mapping. Will overwrite mapping.
#'
#' @return An `htmlwidget` object of class `paneledOutlierExplorer`, ready to
#' print in the RStudio viewer, embed in R Markdown, or render inside a Shiny
#' application.
#'
#' @importFrom purrr list_modify
#'
#' @export
Expand Down
4 changes: 4 additions & 0 deletions R/render_widget.R
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@
#' @param data named list of current data sets
#' @param mapping named list with the current data mappings
#'
#' @return An `htmlwidget` object whose class is the value of `widgetName`,
#' ready to print in the RStudio viewer, embed in R Markdown, or render
#' inside a Shiny application.
#'
#' @importFrom htmlwidgets createWidget sizingPolicy
#' @importFrom jsonlite toJSON
#'
Expand Down
118 changes: 39 additions & 79 deletions R/tendril_chart.R
Original file line number Diff line number Diff line change
@@ -1,90 +1,50 @@

#' Tendril plot
#' Tendril plot (defunct)
#'
#' Create a plot using the {{Tendril}} package
#' @description
#' `tendril_chart()` is defunct as of safetyCharts 0.5.0 and no longer works.
#'
#' @param data list of data frames including dataframes named `aes` (adverse events) and `dm` (demographics)
#' @param settings named list of domain-specific settings with the parameters specified below.
#' It drew a tendril plot using the \pkg{Tendril} package, which was archived
#' from CRAN on 2026-03-25 and has had no release since 2020. Because
#' `safetyCharts` imported \pkg{Tendril}, `safetyCharts` was archived on the same
#' day, and `safetyGraphics` followed for importing `safetyCharts`.
#'
#' @details The settings object provides details regarding the columns in the data sets.
#' The dependency has been dropped so that both packages can return to CRAN. The
#' function is kept, and kept exported, so that existing code calling it fails
#' with an explanation instead of an "object not found" error.
#'
#' \itemize{
#' \item{"settings$dm$id_col"}{ID column}
#' \item{"settings$dm$treatment_col"}{Treatment column}
#' \item{"settings$dm$treatment_values--group1"}{Name of treatment 1}
#' \item{"settings$dm$treatment_values--group2"}{Name of treatment 2}
#' \item{"settings$aes$id_col"}{ID column)}
#' \item{"settings$aes$bodsys_col"}{Body System}
#' \item{"settings$aes$stdy_col"}{Study Day}
#' }
#' @return returns a chart object
#' The Tendril Plot has also been removed from the chart list used by the
#' `safetyGraphics` Shiny application, so it no longer appears there.
#'
#' @import dplyr
#' @importFrom Tendril Tendril
#' @importFrom rlang sym
#' @param data Ignored. Formerly a list of data frames including data frames
#' named `aes` (adverse events) and `dm` (demographics).
#' @param settings Ignored. Formerly a named list of domain-specific settings.
#'
#' @details
#' The last working implementation is preserved in the package's version control
#' history at <https://github.com/SafetyGraphics/safetyCharts>. Users who still
#' need the chart can install the archived \pkg{Tendril} package from the CRAN
#' archive at <https://cran.r-project.org/src/contrib/Archive/Tendril/> and call
#' `Tendril::Tendril()` directly.
#'
#' @return This function does not return a value. It always raises an error of
#' class `defunctError`.
#'
#' @examples
#' # tendril_chart() is defunct and always raises an error:
#' try(tendril_chart(data = NULL, settings = NULL))
#'
#' @export
#'
tendril_chart <- function(data, settings) {
#########################################
# Prep data
#########################################

# Convert settings to symbols ready for standard evaluation
dm_id_sym <- rlang::sym(settings[["dm"]][["id_col"]])
dm_treatment_sym <- rlang::sym(settings[["dm"]][["treatment_col"]])

ae_id_sym <- rlang::sym(settings[["aes"]][["id_col"]])
ae_bodsys_sym <- rlang::sym(settings[["aes"]][["bodsys_col"]])
ae_stdy_sym <- rlang::sym(settings[["aes"]][["stdy_col"]])

aes_arm <- dplyr::left_join(
data$aes,
data$dm %>% dplyr::select(!!dm_id_sym, !!dm_treatment_sym),
by = settings[["dm"]][["id_col"]]
)

# get treatments
treatments <- c(
settings[["aes"]][["treatment_values--group1"]],
settings[["aes"]][["treatment_values--group2"]]
)

# TODO check that the treatments exsits in the data

if (length(treatments) < 2) {
all_treatments <- unique(aes_arm %>% dplyr::pull(!!dm_treatment_sym))
treatments <- all_treatments[1:2]
}

# subject data
subj <- data$dm %>%
dplyr::count(!!dm_id_sym, !!dm_treatment_sym) %>%
dplyr::select(-n) %>%
as.data.frame()

data.tendril <- Tendril::Tendril(
mydata = aes_arm,
rotations = rep(3, dim(aes_arm)[1]),
AEfreqThreshold = 5,
Tag = "Comment",
Treatments = treatments,
Unique.Subject.Identifier = settings[["aes"]][["id_col"]],
Terms = settings[["aes"]][["bodsys_col"]],
Treat = settings[["dm"]][["treatment_col"]],
StartDay = settings[["aes"]][["stdy_col"]],
SubjList = subj,
SubjList.subject = settings[["dm"]][["id_col"]],
SubjList.treatment = settings[["dm"]][["treatment_col"]],
filter_double_events = TRUE,
suppress_warnings = TRUE
)

p <- plot(
data.tendril,
coloring = "OR",
percentile = TRUE
.Defunct(
msg = paste0(
"'tendril_chart()' is defunct as of safetyCharts 0.5.0.\n",
"The 'Tendril' package it depended on was archived from CRAN on ",
"2026-03-25, so 'safetyCharts' dropped the dependency in order to ",
"return to CRAN.\n",
"To draw a tendril plot, install 'Tendril' from the CRAN archive ",
"(https://cran.r-project.org/src/contrib/Archive/Tendril/) and call ",
"Tendril::Tendril() directly."
)
)

return(p)
}
25 changes: 19 additions & 6 deletions cran-comments.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,24 @@
## Resubmission of an archived package

safetyCharts was archived on CRAN on 2026-03-25 because it required the archived package 'Tendril'.

This release removes that dependency. 'Tendril' is gone from Imports, the tendril chart configuration has been removed so the chart no longer appears in the 'safetyGraphics' application, and `tendril_chart()` is retained as a documented defunct function so that existing code gets an explanation rather than an "object not found" error.

Every remaining dependency is available from CRAN.

The version is 0.5.0. The last version on CRAN was 0.3.0; 0.4.0 was released on GitHub only and is not free to reuse.

`R CMD check --as-cran` reports "New submission" and "Package was archived on CRAN" in the incoming feasibility check. Both are expected for the resubmission of an archived package, and the reason for the archival is resolved as described above.

## Test environments
* local OS X install, R 4.1.0
* Fedora Linux, R-devel, clang, gfortran (rhub.io)
* Ubuntu Linux 16.04 LTS, R-release, GCC (rhub.io)
* Windows Server 2008 R2 SP1, R-devel, 32/64 bit (rhub.io)

* local macOS 14.6.1 (aarch64), R 4.3.3

## R CMD check results
There were no ERRORs, WARNINGs or NOTEs.

<!-- Replace this block with the result of the final pre-submission check, run on
the exact tarball being uploaded, using the current R-devel. -->

## Downstream dependencies
None

safetyGraphics imports safetyCharts. It was archived on the same day and for the same reason, and will be resubmitted once this package is accepted.
Loading
Loading