Skip to content

Commit

Permalink
Merge branch 'release-0.1.5' into github-main
Browse files Browse the repository at this point in the history
  • Loading branch information
tcoroller committed Mar 21, 2024
2 parents c4e63e6 + a463433 commit 531377d
Show file tree
Hide file tree
Showing 22 changed files with 566 additions and 258 deletions.
4 changes: 0 additions & 4 deletions .Rprofile
Original file line number Diff line number Diff line change
@@ -1,5 +1 @@
source("renv/activate.R")

if (Sys.getenv("LOAD_MONITOS_PACKAGE") == "true") {
devtools::load_all(".")
}
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
/*.Rcheck/

# RStudio files
.Rproj.user/
.Rproj.user
paths
public/
Expand Down Expand Up @@ -52,3 +53,4 @@ inst/doc

# vim
*.swp
docs
97 changes: 97 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
stages: # List of stages for jobs, and their order of execution
- setup
- check
- coverage
- rhub
- shiny
- deploy_pages

before_script: ## Check this part

- export http_proxy=http://proxy.eu.novartis.net:2010/
- export https_proxy=http://proxy.eu.novartis.net:2010/
- export NOT_CRAN=true
- export CCACHE_DIR=/tmp
- export PATH=/usr/lib/ccache:$PATH


# <DON'T REMOVE!>
variables:
RENV_PATHS_CACHE: "~/.renv/cache"
RENV_PATHS_LIBRARY_ROOT: "~/.renv/library"

# <DON'T REMOVE!>
cache:
key: ${CI_JOB_NAME}
paths:
- ${RENV_PATHS_CACHE}
- ${RENV_PATHS_LIBRARY}

Setup:
stage: setup
script:
- >
if [ ! -d "$RENV_PATHS_CACHE" ]; then
mkdir -p $RENV_PATHS_CACHE;
echo "Installing RENV_PATHS_CACHE in ${RENV_PATHS_CACHE}...";
fi
- Rscript -e "if (!requireNamespace('renv', quietly = TRUE)) install.packages('renv');"
- Rscript -e "renv::restore();"

Check:
stage: check
allow_failure: true
script:
- Rscript -e "if (!requireNamespace('devtools', quietly = TRUE)) install.packages('devtools');"
- Rscript -e 'devtools::check()'

Coverage:
stage: coverage
only:
- main
- dev
allow_failure: true
script:
- Rscript -e "if (!requireNamespace('covr', quietly = TRUE)) install.packages('covr');"
- Rscript -e "if (!requireNamespace('DT', quietly = TRUE)) install.packages('DT');"
- Rscript -e 'covr::gitlab(quiet = FALSE)'

RHUB:
stage: rhub
only:
- main
- dev
script:
- Rscript -e "if (!requireNamespace('devtools', quietly = TRUE)) install.packages('devtools');"
- Rscript -e "if (!requireNamespace('rhub', quietly = TRUE)) install.packages('rhub');"
- Rscript -e "rhub::validate_email(email = $RHUB_EMAIL, token = $RHUB_TOKEN);"
- Rscript -e "devtools::check_rhub()"

Shiny:
stage: shiny
only:
- shiny
allow_failure: true
script:
- Rscript -e 'source("inst/shiny/deploy.R"); deploy_app_rsc()'

pages:
stage: deploy_pages
script:
- echo "We are on branch $CI_COMMIT_REF_NAME"
- mkdir -p public/$CI_COMMIT_REF_NAME
- Rscript -e "if (!requireNamespace('pkgdown', quietly = TRUE)) install.packages('pkgdown');"
- Rscript -e "if (!requireNamespace('devtools', quietly = TRUE)) install.packages('devtools');"
- Rscript -e "devtools::build('.')"
- export LOAD_MONITOS_PKG=TRUE
- Rscript -e "pkgdown::build_site(override = list(destination = 'public/$CI_COMMIT_REF_NAME'))"
artifacts:
name: "$CI_COMMIT_REF_NAME"
paths:
- public
expire_in: never
only:
- dev
- main
except:
- schedules
6 changes: 3 additions & 3 deletions CRAN-SUBMISSION
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Version: 0.1.4
Date: 2024-03-05 15:50:18 UTC
SHA: 1c522f9d25643b3a09c626ef648e0b56dc08c27a
Version: 0.1.5
Date: 2024-03-21 19:08:12 UTC
SHA: 0e0bf2cda5fea0dfd200beed7efd144d2f096ca8
3 changes: 2 additions & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
Package: monitOS
Title: Monitoring Overall Survival in Pivotal Trials in Indolent Cancers
Version: 0.1.4
URL: https://opensource.nibr.com/monitOS/
Version: 0.1.5
Authors@R: c(
person("Thomas", "Fleming", email = "[email protected]", role ="ctb"),
person("Lisa", "Hampson", email = "[email protected]", role ="aut"),
Expand Down
10 changes: 9 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
# monitOS 0.1.5

- Improved `DESCRIPTION`, added website URL, screenshot Shiny app
- Improved `README`
- Improved code style using `styler`
- Fixed bug deploying `Shiny` app (relative import error)
- Fixed package coverage by focusing only on statistical tool (no shiny app)

# monitOS 0.1.4

- Added a `NEWS.md` file to track changes to the package.
- Added `Shiny` section in `README.md` file.
- Improved `monitOS::run_app()`: new layout, new descriptions, new use case.
- Created `pkgdown` public website.

# monitOS 0.1.3 | `2023-10-31`
# monitOS 0.1.3

- Initial CRAN submission.
70 changes: 37 additions & 33 deletions R/bounds.R
Original file line number Diff line number Diff line change
Expand Up @@ -34,22 +34,26 @@
#' @examples
#' # Example 01: OS monitoring guideline retrospectively applied to Motivating Example 1
#' # with delta null = 1.3, delta alt = 0.80, gamma_FA = 0.025 and beta_PA = 0.10.
#' bounds(events=c(60, 89, 110, 131, 178),
#' power_int=0.9, # beta_PA
#' falsepos=0.025, # gamma_FA
#' hr_null = 1.3, # delta_null
#' hr_alt = 0.8, # delta_alt
#' rand_ratio = 1, # rand_ratio
#' hr_marg_benefit = NULL)
#' bounds(
#' events = c(60, 89, 110, 131, 178),
#' power_int = 0.9, # beta_PA
#' falsepos = 0.025, # gamma_FA
#' hr_null = 1.3, # delta_null
#' hr_alt = 0.8, # delta_alt
#' rand_ratio = 1, # rand_ratio
#' hr_marg_benefit = NULL
#' )
#' # Example 02: OS monitoring guideline applied to Motivating Example 2
#' # with delta null = 4/3, delta alt = 0.7, gamma_FA = 0.20 and beta_PA = 0.1.
#' bounds(events=c(60, 89, 110, 131, 178),
#' power_int=0.9, # beta_PA
#' falsepos=0.025, # gamma_FA
#' hr_null = 1.3, # delta_null
#' hr_alt = 0.8, # delta_alt
#' rand_ratio = 1, # rand_ratio
#' hr_marg_benefit = 0.95)
#' bounds(
#' events = c(60, 89, 110, 131, 178),
#' power_int = 0.9, # beta_PA
#' falsepos = 0.025, # gamma_FA
#' hr_null = 1.3, # delta_null
#' hr_alt = 0.8, # delta_alt
#' rand_ratio = 1, # rand_ratio
#' hr_marg_benefit = 0.95
#' )
bounds <- function(events,
# OS events at each analysis
power_int = 0.9,
Expand All @@ -64,16 +68,15 @@ bounds <- function(events,
# for every patient randomized to control, rand_ratio patients are allocated to experimental intervention
hr_marg_benefit = NULL
# evaluate probability of meeting positivity thresholds under a second plausible beneficial effect of treatment on OS (HR = hr_marg_benefit)
) {

) {
# Log scale
lhr_null <- log(hr_null)
lhr_alt <- log(hr_alt)

# Init variables
nstage <- length(events) # total number of analyses planned
info <-
rand_ratio*events / ((rand_ratio + 1)^2) # Fisher's information for log-HR at each analysis
rand_ratio * events / ((rand_ratio + 1)^2) # Fisher's information for log-HR at each analysis
se <-
sqrt(1 / info) # asymptotic standard error for log-HR at each analysis

Expand All @@ -100,34 +103,36 @@ bounds <- function(events,
post_pos <- calc_posterior(lhr_pos, lhr_null, events)
pred_pos <- calc_predictive(lhr_pos, events)

summary <- data.frame('Deaths' = events)
summary <- data.frame("Deaths" = events)

# OS HR thresholds for positivity
summary$'OS HR threshold for positivity' <- round(exp(lhr_pos), 3)
summary$"OS HR threshold for positivity" <- round(exp(lhr_pos), 3)

# One sided false positive error_rate at each analysis
summary$'One-sided false positive error rate' <- round(falsepos_all, 3)
summary$"One-sided false positive error rate" <- round(falsepos_all, 3)

# Level of 2-sided CI needed to rule out δnull at given analysis (%)
summary$'Level of 2-sided CI needed to rule out delta null' <- round(pmax(0, CI_level_monit_null), 0)
summary$"Level of 2-sided CI needed to rule out delta null" <- round(pmax(0, CI_level_monit_null), 0)

# Probability of meeting positivity threshold under plausible OS benefit
summary$'Probability of meeting positivity threshold under delta alt' <- round(power_all, 3)
summary$"Probability of meeting positivity threshold under delta alt" <- round(power_all, 3)

# Pr(true OS HR >= detrimental OS HR | current data)
summary$'Posterior probability the true OS HR exceeds delta null given the data' <- round(post_pos, 3)
summary$'Predictive probability the OS HR estimate at Final Analysis does not exceed the positivity threshold' <- c(round(pred_pos * 100, 3), NA)
summary$"Posterior probability the true OS HR exceeds delta null given the data" <- round(post_pos, 3)
summary$"Predictive probability the OS HR estimate at Final Analysis does not exceed the positivity threshold" <- c(round(pred_pos * 100, 3), NA)

if (!is.null(hr_marg_benefit)) {
# calculate the probability of meeting positivity thresholds under lhr_marg_benefit
summary$'Probability of meeting positivity threshold under incremental benefit' <-
round(meeting_probs(
summary = summary,
lhr_pos = lhr_pos,
lhr_target = log(hr_marg_benefit),
rand_ratio = rand_ratio
),
3)
summary$"Probability of meeting positivity threshold under incremental benefit" <-
round(
meeting_probs(
summary = summary,
lhr_pos = lhr_pos,
lhr_target = log(hr_marg_benefit),
rand_ratio = rand_ratio
),
3
)
}

return(list(
Expand All @@ -136,5 +141,4 @@ bounds <- function(events,
lhr_pos = lhr_pos,
summary = summary
))

}
2 changes: 1 addition & 1 deletion R/posteriors.R
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ calc_predictive <- function(lhr_con, events) {
pred_pos[i] <- pnorm(
lhr_con[nstage] * sqrt(info[nstage]),
mean = lhr_con[i] * sqrt(info[i]) * sqrt(info[nstage] /
info[i]),
info[i]),
sd = sqrt((info[nstage] - info[i]) / info[i])
)
}
Expand Down
9 changes: 5 additions & 4 deletions R/probs.R
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,17 @@ meeting_probs <-
rand_ratio = 1) {
events <- summary$Deaths
info <-
rand_ratio * events / ((rand_ratio + 1) ^ 2) # Fisher's information for log-HR at each analysis
rand_ratio * events / ((rand_ratio + 1)^2) # Fisher's information for log-HR at each analysis
se <-
sqrt(1 / info) # asymptotic standard error for log-HR at each analysis
prob <- list()
for (i in 1:length(events)) {
prob[i] <-
pnorm(lhr_pos[i],
mean = lhr_target,
sd = se[i],
lower.tail = TRUE)
mean = lhr_target,
sd = se[i],
lower.tail = TRUE
)
}
return(as.numeric(prob))
}
3 changes: 2 additions & 1 deletion R/runApp.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#' @import shiny
#' @export
#' @return No return value, runs shiny app
# nocov start
run_app <- function() {
shinyApp(
ui = app_ui,
Expand All @@ -15,4 +16,4 @@ run_app <- function() {
# uiPattern = uiPattern
)
}

# nocov end
18 changes: 10 additions & 8 deletions R/server.R
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,18 @@
#' @param input generic shiny var
#' @param output generic shiny var
#' @param session generic shiny var
# nocov start
app_server <- function(input, output, session) {
wrap <-
function(X, decimal = 3)
function(X, decimal = 3) {
return(paste(round(X, decimal), collapse = ","))
}
unwrap <-
function(X)
function(X) {
return(as.numeric(unlist(strsplit(
gsub(" ", "", X), ","
))))
}

# Core reactive function - OCs plots & results
react <- reactive({
Expand All @@ -21,7 +24,7 @@ app_server <- function(input, output, session) {
updateTextInput(session, "events", value = wrap(events))

# boundaries
boundaries = bounds(
boundaries <- bounds(
events = events,
power_int = input$power_int,
falsepos = input$falsepos,
Expand All @@ -32,7 +35,7 @@ app_server <- function(input, output, session) {
)


hr_pos = exp(boundaries$lhr_pos)
hr_pos <- exp(boundaries$lhr_pos)
updateTextInput(session, "hr_pos", value = wrap(hr_pos))


Expand All @@ -49,11 +52,10 @@ app_server <- function(input, output, session) {
# ) # Optional
# names(boundaries$summary) <- columns

return(boundaries)

return(boundaries)
})

# Rendering
output$bounds <- renderTable(react()$summary[,-c(6, 7)])

output$bounds <- renderTable(react()$summary[, -c(6, 7)])
}
# nocov end
Loading

0 comments on commit 531377d

Please sign in to comment.