#' ---
#' title: ' Using the inverse normal combination test for analysing a trial with continuous endpoint and potential sample size reassessment'
#' author: "Gernot Wassmer and Friedrich Pahlke"
#' date: "`r format(Sys.time(), '%d %B, %Y')`"
#' number: 13
#' header-includes:
#' - \usepackage{fancyhdr}
#' - \pagestyle{fancy}
#' - \setlength{\headheight}{23pt}
#' - \fancyfoot[C]{www.rpact.com}
#' - \fancyfoot[L]{\thepage}
#' output:
#' bookdown::html_document2:
#' highlight: pygments
#' number_sections: yes
#' self_contained: yes
#' fig_caption: yes
#' toc: yes
#' toc_depth: 3
#' toc_float: yes
#' css: style.css
#' includes:
#' before_body: header.html
#' after_body: footer.html
#' ---
#'
## ----setup, include=FALSE-----------------------------------------------------
knitr::opts_chunk$set(echo = TRUE)
options(scipen=999)
#'
#'
#'
#' # Summary {-}
#'
#' This [R Markdown](https://rmarkdown.rstudio.com) document provides an example for analysing trials with
#' a continuous endpoint and sample size reassessment using [rpact](https://cran.r-project.org/package=rpact).
#'
#'
#'
#' # Define the type of design to be used for the analysis
#'
#' **First, load the rpact package**
#'
## ---- include=TRUE, echo=TRUE-------------------------------------------------
library(rpact)
packageVersion("rpact") # version should be version 2.0.5 or later
#'
#'
#' Since we want to illustrate a design where at interim stages we are able
#' to perform data-driven sample size adaptations, we use the *inverse normal
#' combination test* for combining the $p$-values from the stages of the trial. We
#' want to use a three stage design with O`Brien and Fleming boundaries and
#' additionally want to consider futility bounds -0.5 and 0.5 for the test
#' statistics at the interim stages. Accordingly,
#'
## ---- include=TRUE, echo=TRUE-------------------------------------------------
# Example of an inverse normal combination test:
designIN <- getDesignInverseNormal(futilityBounds = c(-0.5, 0.5))
#'
#' defines the design to be used for this purpose. By default, this is a design
#' with equally spaced information rates and one sided $\alpha=0.025$. The critical
#' values can be displayed on the $z$-value or the $p$-value scale:
#'
## ----echo=TRUE, include=TRUE--------------------------------------------------
plot(designIN, type = 1)
plot(designIN, type = 3)
#'
#' Note that we are using *non-binding* futility bounds that do not affect the
#' boundaries for the rejection of the null hypothesis. It does have an effect,
#' however, on the calculation of the conditional power.
#'
#' By the use of the function `getDesignInverseNormal()` the way to analyse the
#' data is fixed. With this definition, the *unweighted inverse normal combination
#' test* is used, i.e., the stage results are combined through the use on the
#' inverse normal combination test statistics
#'
#' $$\frac{\Phi^{-1}(1 - p_1) + \Phi^{-1}(1 - p_2)}{\sqrt{2}} \text{ and }\frac{\Phi^{-1}(1 - p_1) + \Phi^{-1}(1 - p_2)+ \Phi^{-1}(1 - p_3)}{\sqrt{3}}$$
#'
#' for the second and the third (final) stage of the trial, respectively.
#'
#' # Entering the data
#'
#' In rpact, the way of using data for adaptive analysis is through summary
#' statistics that summarize the data from the separate stages. Generally, the
#' function `getDataset()` is used and depending on which summary statistics are
#' entered, rpact knows the type of endpoint and the number of treatment groups.
#' For testing means in a two-treatment parallel group design, `means1`, `means2`,
#' `stDevs1`, `stDevs2`, `n1`, and `n2` must be defined as vectors of length of
#' the observed interim stages.
#'
#' As an example, assume that the following results in the control and the
#' experimental treatment arm were obtained for the first and the second stage of
#' the trial.
#'
#' First stage:
#'
#' | arm | n | mean | std |
#' | ----- | ----- | ----- | ----- |
#' | experimental | 34 | 112.3 | 44.4 |
#' | control | 37 | 98.1 | 46.7 |
#'
#' Second stage:
#'
#' | arm | n | mean | std |
#' | ----- | ----- | ----- | ----- |
#' | experimental | 31 | 113.1 | 42.9 |
#' | control | 33 | 99.3 | 41.1 |
#'
#' Here, sample size, mean and standard deviation were obtained *separately* from
#' the stages. Enter these results as follows to obtain a dataset object in rpact:
#'
#'
## ---- include=TRUE, echo=TRUE-------------------------------------------------
dataSetExample <- getDataset(
means1 = c(112.3, 113.1),
means2 = c(98.1, 99.3),
stDevs1 = c(44.4, 42.9),
stDevs2 = c(46.7, 41.1),
n1 = c(34, 31),
n2 = c(37, 33))
#'
#' The object
#'
## ---- include=TRUE, echo=TRUE, eval = FALSE-----------------------------------
## dataSetExample
#'
#' also contains the overall results which were calculated from the separate stage results:
#'
## ---- include=TRUE, echo=FALSE, eval = TRUE-----------------------------------
dataSetExample
#'
#' You might alternatively enter the overall results by specifying
#' `overallMeans1`, `overallMeans2`, `overallStDevs1`, `overallStDevs2`, `overallN1`, and `overallN2`:
#'
## ---- include=TRUE, echo=TRUE-------------------------------------------------
getDataset(
overallMeans1 = c(112.3, 112.68),
overallMeans2 = c(98.1, 98.67),
overallStDevs1 = c(44.4, 43.35),
overallStDevs2 = c(46.7, 43.84),
overallN1 = c(34, 65),
overallN2 = c(37, 70))
#'
#'
#' # Analysis results
#'
#' The easiest way to obtain the analysis results is through the function `getAnalysisResults()`,
#' where `design` and `dataInput` needs to be specified. In our case,
#'
## ---- include=TRUE, echo=TRUE, eval=FALSE-------------------------------------
## getAnalysisResults(design = designIN, dataInput = dataSetExample, stage = 2)
#' does the job, and the output is
#'
## ---- include=FALSE-----------------------------------------------------------
x <- getAnalysisResults(design = designIN, dataInput = dataSetExample, stage = 2)
#'
## ---- echo=FALSE, message=FALSE, warning=FALSE, include=TRUE------------------
x
#' We note that the variable `stage` needs not to be specified because it is
#' actually obtained from the data. You might, however, specify `stage = 1` in
#' order to obtain the results for the first stage only.
#'
#' The inverse normal combination test statistic is calculated to
#' be `r round(x$combinationTestStatistics[2],3)` which is smaller than
#' `r round(x$criticalValues[2],3)`. Hence, the hypothesis cannot be rejected,
#' which is also reflected in the repeated $p$-value =
#' `r round(x$repeatedPValues[2],4)` larger than $\alpha=0.025$ and the lower bound
#' of the repeated confidence interval =
#' `r round(x$repeatedConfidenceIntervalLowerBounds[2],3)` being smaller than 0
#' (i.e., the RCI contains the null hypothesis value).
#'
#' # Reassessing the sample size for the last stage
#'
#' The *conditional power* is calculated if `nPlanned` is specified. `nPlanned`
#' contains the sample size *of the remaining separate stages* for both treatment
#' groups and is a vector with that length. For example, if we specify
#' `nPlanned = 60`, the conditional power is calculated for a total of 60 patients
#' in the 2 treatment groups *for the final stage* with equal allocation between
#' the treatment groups (the latter can be changed with `allocationRatioPlanned`
#' which is 1 by default).
#'
## ---- include=TRUE, echo=TRUE, eval = FALSE-----------------------------------
## results <- getAnalysisResults(design = designIN, dataSetExample, stage = 2, nPlanned = 60)
#'
## ---- include=FALSE-----------------------------------------------------------
results <- getAnalysisResults(design = designIN, dataSetExample, stage = 2, nPlanned = 60)
#'
#' yields the following output:
#'
## ---- echo=FALSE, include=TRUE------------------------------------------------
results
#'
#' The conditional power `r round(results$conditionalPower[3], 3)` is not very
#' large and so a sample size increase might be appropriate. This conditional power
#' calculation, however, is performed with the *observed effect* and *observed
#' standard deviation* and so it might be reasonable to take a look at the effect
#' size and its variability. This is graphically illustrated by the plot of the
#' conditional power and the likelihood function over a range of alternative
#' values. E.g., specify `thetaRange = c(0,30)` and obtain the graph below.
#'
## ---- include=TRUE, echo=TRUE-------------------------------------------------
plot(results, thetaRange = c(0,30))
#'
#' You can also specify an alternative effect and standard deviation (e.g.,
#' `thetaH1 = 15, assumedStDev = 35`) for which the conditional power should be
#' calculated, and graph the results. Here, the function `getConditionalPower()`
#' together with `getStageResults()` are used but you obtain the same result when
#' specifying `thetaH1 = 15, assumedStDev = 35` in `getAnalysisResults()`.
#'
## ---- include=TRUE, echo=TRUE-------------------------------------------------
stageResults <- getStageResults(design = designIN, dataInput = dataSetExample)
getConditionalPower(design = designIN, stageResults, nPlanned = 60, thetaH1 = 15,
assumedStDev = 35)
plot(stageResults, nPlanned = 60, thetaRange = c(0,30), assumedStDev = 35)
#'
#'
#' # Final analysis
#'
#' Assume now that it was decided to continue with the originally planned sample
#' size (= 60 per stage) and the final stage shows the results:
#'
#' Final stage:
#'
#' | arm | n | mean | std |
#' | ----- | ----- | ----- | ----- |
#' | experimental | 32 | 111.3 | 41.4 |
#' | control | 31 | 100.1 | 39.5 |
#'
#' We obtain the test results for the final stage as follows:
#'
## ---- include=TRUE, echo=TRUE-------------------------------------------------
dataSetExample <- getDataset(
means1 = c(112.3, 113.1, 111.3),
means2 = c(98.1, 99.3, 100.1),
stDevs1 = c(44.4, 42.9, 41.4),
stDevs2 = c(46.7, 41.1, 39.5),
n1 = c(34, 31, 32),
n2 = c(37, 33, 31))
getAnalysisResults(design = designIN, dataInput = dataSetExample)
#'
## ---- include=FALSE-----------------------------------------------------------
x <- getAnalysisResults(design = designIN, dataInput = dataSetExample)
#'
#' The warning indicates that the calculation of the final CI can be critical if
#' sample size changes were performed. This is not the case here, and so the
#' confidence interval that is based on the stagewise ordering given by
#' (`r round(x$finalConfidenceIntervalLowerBounds[3], 2)`;
#' `r round(x$finalConfidenceIntervalUpperBounds[3],2)`) is a valid inference tool.
#' Together with the RCI at stage 3
#' (`r round(x$repeatedConfidenceIntervalLowerBounds[3], 2)`;
#' `r round(x$repeatedConfidenceIntervalUpperBounds[3],2)`) it corresponds to the
#' test decision of rejecting the null hypothesis. The test decision is also
#' reflected in both the final $p$-value and repeated $p$-value being smaller than
#' $\alpha=0.025$.
#'
#'
#' # References
#'
#' 1. Gernot Wassmer and Werner Brannath, *Group Sequential and Confirmatory
#' Adaptive Designs in Clinical Trials*, Springer 2016, ISBN 978-3319325606
#'
#'
#' ***
#'
#' System: rpact `r packageVersion("rpact")`, `r R.version.string`, platform: `r R.version$platform`
#'
## ---- include=TRUE, echo=FALSE, results='asis'--------------------------------
printCitation()
#'