Skip to content

Commit

Permalink
Merge pull request #39 from Merck/prepcran
Browse files Browse the repository at this point in the history
Simplify bootstrap functions and calculations
  • Loading branch information
dom-muston authored May 4, 2024
2 parents aec8720 + e271de2 commit ea249a6
Show file tree
Hide file tree
Showing 5 changed files with 23 additions and 117 deletions.
1 change: 0 additions & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# Generated by roxygen2: do not edit by hand

export(calc_allrmds)
export(calc_allrmds_boot)
export(calc_haz_psm)
export(calc_likes)
export(calc_rmd)
Expand Down
54 changes: 10 additions & 44 deletions R/resmeans.R
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ calc_rmd_first <- function(ds, cuttime) {
#' @param discrate Discount rate (% per year)
#' @param rmdmethod can be "int" (default for full integral calculations) or "disc" for approximate discretized calculations
#' @param timestep required if method=="int", default being 1
#' @param boot logical flag to indicate whether abbreviated output is required (default = FALSE), for example for bootstrapping
#' @return List of detailed numeric results
#' - cutadj indicates the survival function and area under the curves for PFS and OS up to the cutpoint
#' - results provides results of the restricted means calculations, by model and state.
Expand All @@ -430,7 +431,7 @@ calc_rmd_first <- function(ds, cuttime) {
#' \donttest{
#' # Create dataset and fit survival models (splines)
#' bosonc <- create_dummydata("flexbosms")
#' fits <- fit_ends_mods_spl(bosonc)
#' fits <- fit_ends_mods_par(bosonc)
#' # Pick out best distribution according to min AIC
#' params <- list(
#' ppd = find_bestfit(fits$ppd, "aic")$fit,
Expand All @@ -443,7 +444,7 @@ calc_rmd_first <- function(ds, cuttime) {
#' # RMD using default "int" method, no lifetable constraint
#' calc_allrmds(bosonc, dpam=params)
#' # RMD using discretized ("disc") method, no lifetable constraint
#' calc_allrmds(bosonc, dpam=params, rmdmethod="disc", timestep=1)
#' calc_allrmds(bosonc, dpam=params, rmdmethod="disc", timestep=1, boot=TRUE)
#' }
calc_allrmds <- function(ptdata,
inclset = 0,
Expand All @@ -454,9 +455,8 @@ calc_allrmds <- function(ptdata,
lifetable = NA,
discrate = 0,
rmdmethod = "int",
timestep = 1) {
# Set-up variables

timestep = 1,
boot = FALSE) {
# Check calculations valid
chvalid <- is.na(dpam[1])==FALSE
if (chvalid==FALSE) stop("No validly fitted endpoints")
Expand Down Expand Up @@ -508,43 +508,9 @@ calc_allrmds <- function(ptdata,
rmdres$pf <- rmdres$pf + first$pfarea
rmdres$pd <- rmdres$pd + first$osarea - first$pfarea
rmdres$os <- rmdres$os + first$osarea
return(list(cutadj=first, results=rmdres))
}

#' Wrapper to enable bootstrap sampling of restricted mean durations for each health state and all three models.
#' @description Wrapper function to [calc_allrmds] to enable bootstrap sampling of calculations of restricted mean durations for each health state (progression free and progressed disease) for all three models (partitioned survival, clock forward state transition model, clock reset state transition model).
#' @inheritParams calc_allrmds
#' @return Numeric vector of restricted mean durations - PF for each model (PSM, STM-CF, STM-CR), then PD, then OS.
#' @export
#' @examples
#' \donttest{
#' bosonc <- create_dummydata("flexbosms")
#' fits <- fit_ends_mods_spl(bosonc)
#' # Pick out best distribution according to min AIC
#' params <- list(
#' ppd = find_bestfit(fits$ppd, "aic")$fit,
#' ttp = find_bestfit(fits$ttp, "aic")$fit,
#' pfs = find_bestfit(fits$pfs, "aic")$fit,
#' os = find_bestfit(fits$os, "aic")$fit,
#' pps_cf = find_bestfit(fits$pps_cf, "aic")$fit,
#' pps_cr = find_bestfit(fits$pps_cr, "aic")$fit
#' )
#' calc_allrmds_boot(ptdata=bosonc, dpam=params)
#' }
calc_allrmds_boot <- function(ptdata,
inclset = 0,
dpam,
cuttime = 0,
Ty = 10,
lifetable = NA,
discrate = 0) {
if (inclset[1]==0) {inclset <- 1:length(ptdata$ptid)}
mb <- calc_allrmds(ptdata = ptdata,
inclset = inclset,
dpam = dpam,
cuttime = cuttime,
Ty = Ty,
lifetable = lifetable,
discrate = discrate)
c(mb$results$pf, mb$results$pd, mb$results$os)
if (boot==TRUE) {
c(rmdres$pf, rmdres$pd, rmdres$os)
} else {
list(cutadj=first, results=rmdres)
}
}
9 changes: 6 additions & 3 deletions man/calc_allrmds.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

62 changes: 0 additions & 62 deletions man/calc_allrmds_boot.Rd

This file was deleted.

14 changes: 7 additions & 7 deletions vignettes/example.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -182,17 +182,17 @@ The two STMs estimate a duration in the PF state slightly longer than the PSM. T

The above output can be bootstrapped to generate standard errors. Here we use just 10 boostrap samples (`R=10`) just to illustrate the process. In practice, we would want to use far more than 10 samples.

```{r boot, include=FALSE}
# Bootstrap to calculate SE over R bootstrap samples
bootlys <- boot(
```{r boot}
# Bootstrap to calculate SE over 10 bootstrap samples
boot::boot(
data = bosonc,
statistic = calc_allrmds_boot,
R = 10, # Number of simulations
statistic = calc_allrmds,
R = 10, # Number of samples
cuttime = 0,
Ty = 10,
dpam = params
dpam = params,
boot = TRUE
)
bootlys
```

Note that the percentiles information reported indicates that in a small number of samples, the restricted mean duration in PD was restricted to be negative in the PSM. This indicates an inconsistency between the statistical models used in this case for modeling PFS and OS, and may be an additional reason why STMs may be preferred in this case.
Expand Down

0 comments on commit ea249a6

Please sign in to comment.