diff --git a/NAMESPACE b/NAMESPACE index e14d801..fef31e4 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -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) diff --git a/R/resmeans.R b/R/resmeans.R index afaf9b7..d13a900 100644 --- a/R/resmeans.R +++ b/R/resmeans.R @@ -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. @@ -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, @@ -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, @@ -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") @@ -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) + } } diff --git a/man/calc_allrmds.Rd b/man/calc_allrmds.Rd index 3df0d1e..fb92540 100644 --- a/man/calc_allrmds.Rd +++ b/man/calc_allrmds.Rd @@ -14,7 +14,8 @@ calc_allrmds( lifetable = NA, discrate = 0, rmdmethod = "int", - timestep = 1 + timestep = 1, + boot = FALSE ) } \arguments{ @@ -46,6 +47,8 @@ calc_allrmds( \item{rmdmethod}{can be "int" (default for full integral calculations) or "disc" for approximate discretized calculations} \item{timestep}{required if method=="int", default being 1} + +\item{boot}{logical flag to indicate whether abbreviated output is required (default = FALSE), for example for bootstrapping} } \value{ List of detailed numeric results @@ -61,7 +64,7 @@ Calculate restricted mean durations for each health state (progression free and \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, @@ -74,6 +77,6 @@ params <- list( # 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) } } diff --git a/man/calc_allrmds_boot.Rd b/man/calc_allrmds_boot.Rd deleted file mode 100644 index 1401232..0000000 --- a/man/calc_allrmds_boot.Rd +++ /dev/null @@ -1,62 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/resmeans.R -\name{calc_allrmds_boot} -\alias{calc_allrmds_boot} -\title{Wrapper to enable bootstrap sampling of restricted mean durations for each health state and all three models.} -\usage{ -calc_allrmds_boot( - ptdata, - inclset = 0, - dpam, - cuttime = 0, - Ty = 10, - lifetable = NA, - discrate = 0 -) -} -\arguments{ -\item{ptdata}{Dataset of patient level data. Must be a tibble with columns named: -\itemize{ -\item ptid: patient identifier -\item pfs.durn: duration of PFS from baseline -\item pfs.flag: event flag for PFS (=1 if progression or death occurred, 0 for censoring) -\item os.durn: duration of OS from baseline -\item os.flag: event flag for OS (=1 if death occurred, 0 for censoring) -\item ttp.durn: duration of TTP from baseline (usually should be equal to pfs.durn) -\item ttp.flag: event flag for TTP (=1 if progression occurred, 0 for censoring). -}} - -\item{inclset}{Vector to indicate which patients to include in analysis} - -\item{dpam}{List of statistical fits to each endpoint required in PSM, STM-CF and STM-CR models.} - -\item{cuttime}{Time cutoff - this is nonzero for two-piece models.} - -\item{Ty}{Time duration over which to calculate. Assumes input is in years, and patient-level data is recorded in weeks.} - -\item{lifetable}{Optional, a life table. Columns must include \code{lttime} (time in years, or 52.18 times shorter than the time index elsewhere, starting from zero) and \code{lx}} - -\item{discrate}{Discount rate (\% per year)} -} -\value{ -Numeric vector of restricted mean durations - PF for each model (PSM, STM-CF, STM-CR), then PD, then OS. -} -\description{ -Wrapper function to \link{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). -} -\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) -} -} diff --git a/vignettes/example.Rmd b/vignettes/example.Rmd index bb902eb..33a7a20 100644 --- a/vignettes/example.Rmd +++ b/vignettes/example.Rmd @@ -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.