# Introduction

Mediana is an R package which provides a general framework for clinical trial simulations based on the Clinical Scenario Evaluation approach. The package supports a broad class of data models (including clinical trials with continuous, binary, survival-type and count-type endpoints as well as multivariate outcomes that are based on combinations of different endpoints), analysis strategies and commonly used evaluation criteria.

## Expert and development teams

Package design: Alex Dmitrienko (Mediana Inc.).

Core development team: Gautier Paux (Servier), Alex Dmitrienko (Mediana Inc.).

Extended development team: Thomas Brechenmacher (Novartis), Fei Chen (Johnson and Johnson), Ilya Lipkovich (Quintiles), Ming-Dauh Wang (Lilly), Jay Zhang (MedImmune), Haiyan Zheng (Osaka University).

Expert team: Keaven Anderson (Merck), Frank Harrell (Vanderbilt University), Mani Lakshminarayanan (Pfizer), Brian Millen (Lilly), Jose Pinheiro (Johnson and Johnson), Thomas Schmelter (Bayer).

## Installation

### Latest release

Install the latest version of the Mediana package from CRAN using the install.packages command in R:

install.packages("Mediana")

### Development version

The up-to-date development version can be found and installed directly from the GitHub web site. You need to install the devtools package and then call the install_github function in R:

# install.packages("devtools")
devtools::install_github("gpaux/Mediana")

## Clinical Scenario Evaluation Framework

The Mediana R package was developed to provide a general software implementation of the Clinical Scenario Evaluation (CSE) framework. This framework introduced by Benda et al. (2010) and Friede et al. (2010) recognizes that sample size calculation and power evaluation in clinical trials are high-dimensional statistical problems. This approach helps decompose this complex problem by identifying key elements of the evaluation process. These components are termed models:

• Data models define the process of generating trial data (e.g., sample sizes, outcome distributions and parameters).
• Analysis models define the statistical methods applied to the trial data (e.g., statistical tests, multiplicity adjustments).
• Evaluation models specify the measures for evaluating the performance of the analysis strategies (e.g., traditional success criteria such as marginal power or composite criteria such as disjunctive power).

Find out more about the role of each model and how to specify the three models to perform Clinical Scenario Evaluation by reviewing the dedicated pages (click on the links above).

## Case studies

Multiple case studies are provided on the web site’s package to facilitate the implementation of Clinical Scenario Evaluation in different clinical trial settings using the Mediana package. These case studies will be updated on a regular basis. Another vignette accessible with the following command is also available presenting these case studies.

vignette("case-studies", package = "Mediana")

The Mediana package has been successfully used in multiple clinical trials to perform power calculations as well as optimally select trial designs and analysis strategies (clinical trial optimization). For more information on applications of the Mediana package, download the following papers:

# Data model

Data models define the process of generating patient data in clinical trials.

## Initialization

A data model can be initialized using the following command

# DataModel initialization
data.model = DataModel()

It is highly recommended to use this command as it will simplify the process of specifying components of the data model, e.g., OutcomeDist, Sample, SampleSize, Event and Design objects.

## Components of a data model

Once the DataModel object has been initialized, components of the data model can be specified by adding objects to the model using the ‘+’ operator as shown below.

# Outcome parameter set 1
outcome1.placebo = parameters(mean = 0, sd = 70)
outcome1.treatment = parameters(mean = 40, sd = 70)

# Outcome parameter set 2
outcome2.placebo = parameters(mean = 0, sd = 70)
outcome2.treatment = parameters(mean = 50, sd = 70)

# Data model
case.study1.data.model =  DataModel() +
OutcomeDist(outcome.dist = "NormalDist") +
SampleSize(c(50, 55, 60, 65, 70)) +
Sample(id = "Placebo",
outcome.par = parameters(outcome1.placebo, outcome2.placebo)) +
Sample(id = "Treatment",
outcome.par = parameters(outcome1.treatment, outcome2.treatment))

### OutcomeDist object

#### Description

This object specifies the distribution of patient outcomes in a data model. An OutcomeDist object is defined by two arguments:

• outcome.dist defines the outcome distribution.

• outcome.type defines the outcome type (optional). There are two acceptable values of this argument: standard (fixed-design setting) and event (event-driven design setting).

Several distributions that can be specified using the outcome.dist argument are already implemented in the Mediana package. These distributions are listed below along with the required parameters to be included in the outcome.par argument of the Sample object:

• UniformDist: generate data following a univariate distribution. Required parameter: max.

• NormalDist: generate data following a normal distribution. Required parameters: mean and sd.

• BinomDist: generate data following a binomial distribution. Required parameter: prop.

• BetaDist: generate data following a beta distribution. Required parameter: a and b.

• ExpoDist: generate data following an exponential distribution. Required parameter: rate.

• WeibullDist: generate data following a weibull distribution. Required parameter: shape and scale.

• TruncatedExpoDist: generate data following a truncated exponential distribution. Required parameter: rate an trunc.

• PoissonDist: generate data following a Poisson distribution. Required parameter: lambda.

• NegBinomDist: generate data following a negative binomial distribution. Required parameters: dispersion and mean.

• MultinomialDist: generate data following a multinomial distribution. Required parameters: prob.

• MVNormalDist: generate data following a multivariate normal distribution. Required parameters: par and corr. For each generated endpoint, the par parameter must contain the required parameters mean and sd. The corr parameter specifies the correlation matrix for the endpoints.

• MVBinomDist: generate data following a multivariate binomial distribution. Required parameters: par and corr. For each generated endpoint, the par parameter must contain the required parameter prop. The corr parameter specifies the correlation matrix for the endpoints.

• MVExpoDist: generate data following a multivariate exponential distribution. Required parameters: par and corr. For each generated endpoint, the par parameter must contain the required parameter rate. The corrparameter specifies the correlation matrix for the endpoints.

• MVExpoPFSOSDist: generate data following a multivariate exponential distribution to generate PFS and OS endpoints. The PFS value is imputed to the OS value if the latter occurs earlier. Required parameters: par and corr. For each generated endpoint, the par parameter must contain the required parameter rate. Thecorr parameter specifies the correlation matrix for the endpoints.

• MVMixedDist: generate data following a multivariate mixed distribution. Required parameters: type, par and corr. The type parameter assumes the following values: NormalDist, BinomDist and ExpoDist. For each generated endpoint, the par parameter must contain the required parameters according to the distribution type. The corr parameter specifies the correlation matrix for the endpoints.

The outcome.type argument defines the outcome’s type. This argument accepts only two values:

• standard: for fixed design setting.

• event: for event-driven design setting.

The outcome’s type must be defined for each endpoint in case of multivariate disribution, e.g. c("event","event") in case of multivariate exponential distribution. The outcome.type argument is essential to get censored events for time-to-event endpoints if the SampleSize object is used to specify the number of patients to generate.

A single OutcomeDist object can be added to a DataModel object.

For more information about the OutcomeDist object, see the documentation for OutcomeDist on the CRAN web site.

If a certain outcome distribution is not implemented in the Mediana package, the user can create a custom function and use it within the package (see the dedicated vignette vignette("custom-functions", package = "Mediana")).

#### Example

Examples of OutcomeDist objects:

Specify popular univariate distributions:

# Normal distribution
OutcomeDist(outcome.dist = "NormalDist")

# Binomial distribution
OutcomeDist(outcome.dist = "BinomDist")

# Exponential distribution
OutcomeDist(outcome.dist = "ExpoDist")

Specify a mixed multivariate distribution:

# Multivariate Mixed distribution
OutcomeDist(outcome.dist = "MVMixedDist")

### Sample object

#### Description

This object specifies parameters of a sample (e.g., treatment arm in a trial) in a data model. Samples are defined as mutually exclusive groups of patients, for example, treatment arms. A Sample object is defined by three arguments:

• id defines the sample’s unique ID (label).

• outcome.par defines the parameters of the outcome distribution for the sample.

• sample.size defines the sample’s size (optional).

The sample.size argument is optional but must be used to define the sample size only if an unbalanced design is considered (i.e., the sample size varies across the samples). The sample size must be either defined in the Sample object or in the SampleSize object, but not in both.

Several Sample objects can be added to a DataModel object.

For more information about the Sample object, see the documentation Sample on the CRAN web site.

#### Example

Examples of Sample objects:

Specify two samples with a continuous endpoint following a normal distribution:

# Outcome parameters set 1
outcome1.placebo = parameters(mean = 0, sd = 70)
outcome1.treatment = parameters(mean = 40, sd = 70)

# Outcome parameters set 2
outcome2.placebo = parameters(mean = 0, sd = 70)
outcome2.treatment = parameters(mean = 50, sd = 70)

# Placebo sample object
Sample(id = "Placebo",
outcome.par = parameters(outcome1.placebo,
outcome2.placebo))

# Treatment sample object
Sample(id = "Treatment",
outcome.par = parameters(outcome1.treatment,
outcome2.treatment))

Specify two samples with a binary endpoint following a binomial distribution:

# Outcome parameters set
outcome.placebo = parameters(prop = 0.30)
outcome.treatment = parameters(prop = 0.50)

# Placebo sample object
Sample(id = "Placebo",
outcome.par = parameters(outcome1.placebo))

# Treatment sample object
Sample(id = "Treatment",
outcome.par = parameters(outcome1.treatment))

Specify two samples with a time-to-event (survival) endpoint following an exponential distribution:

# Outcome parameters
median.time.placebo = 6
rate.placebo = log(2)/median.time.placebo
outcome.placebo = parameters(rate = rate.placebo)

median.time.treatment = 9
rate.treatment = log(2)/median.time.treatment
outcome.treatment = parameters(rate = rate.treatment)

# Placebo sample object
Sample(id = "Placebo",
outcome.par = parameters(outcome.placebo))

# Treatment sample object
Sample(id = "Treatment",
outcome.par = parameters(outcome.treatment))

Specify three samples with two primary endpoints that follow a binomial and a normal distribution, respectively:

# Variable types
var.type = list("BinomDist", "NormalDist")

# Outcome distribution parameters
placebo.par = parameters(parameters(prop = 0.3),
parameters(mean = -0.10, sd = 0.5))

dosel.par = parameters(parameters(prop = 0.40),
parameters(mean = -0.20, sd = 0.5))

doseh.par = parameters(parameters(prop = 0.50),
parameters(mean = -0.30, sd = 0.5))

# Correlation between two endpoints
corr.matrix = matrix(c(1.0, 0.5,
0.5, 1.0), 2, 2)

# Outcome parameters set
outcome.placebo = parameters(type = var.type,
par = plac.par,
corr = corr.matrix)

outcome.dosel = parameters(type = var.type,
par = dosel.par,
corr = corr.matrix)

outcome.doseh = parameters(type = var.type,
par = doseh.par,
corr = corr.matrix)

# Placebo sample object
Sample(id = list("Plac ACR20", "Plac HAQ-DI"),
outcome.par = parameters(outcome.placebo))

# Low Dose sample object
Sample(id = list("DoseL ACR20", "DoseL HAQ-DI"),
outcome.par = parameters(outcome.dosel))

# High Dose sample object
Sample(id = list("DoseH ACR20", "DoseH HAQ-DI"),
outcome.par = parameters(outcome.doseh))

### SampleSize object

#### Description

This object specifies the sample size in a balanced trial design (all samples will have the same sample size). A SampleSize object is defined by one argument:

• sample.size specifies a list or vector of sample size(s).

A single SampleSize object can be added to a DataModel object.

For more information about the SampleSize object, see the package’s documentation SampleSize.

#### Example

Examples of SampleSize objects:

Several equivalent specifications of the SampleSize object:

SampleSize(c(50, 55, 60, 65, 70))
SampleSize(list(50, 55, 60, 65, 70))
SampleSize(seq(50, 70, 5))

### Event object

#### Description

This object specifies the total number of events (total event count) among all samples in an event-driven clinical trial. An Event object is defined by two arguments:

• n.events defines a vector of the required event counts.

• rando.ratio defines a vector of randomization ratios for each Sample object defined in the DataModel object.

A single Event object can be added to a DataModel object.

For more information about the Event object, see the package’s documentation Event.

#### Example

Examples of Event objects:

Specify the required number of events in a trial with a 2:1 randomization ratio (Treatment:Placebo):

# Event parameters
event.count.total = c(390, 420)
randomization.ratio = c(1,2)

# Event object
Event(n.events = event.count.total,
rando.ratio = randomization.ratio)

### Design object

#### Description

This object specifies the design parameters used in event-driven designs if the user is interested in modeling the enrollment (or accrual) and dropout (or loss to follow up) processes. A Design object is defined by seven arguments:

• enroll.period defines the length of the enrollment period.

• enroll.dist defines the enrollment distribution.

• enroll.dist.par defines the parameters of the enrollment distribution (optional).

• followup.period defines the length of the follow-up period for each patient in study designs with a fixed follow-up period, i.e., the length of time from the enrollment to planned discontinuation is constant across patients. The user must specify either followup.period or study.duration.

• study.duration defines the total study duration in study designs with a variable follow-up period. The total study duration is defined as the length of time from the enrollment of the first patient to the discontinuation of the last patient.

• dropout.dist defines the dropout distribution.

• dropout.dist.par defines the parameters of the dropout distribution.

Several Design objects can be added to a DataModel object.

For more information about the Design object, see the package’s documentation Design.

A convienient way to model non-uniform enrollment is to use a beta distribution (BetaDist). If enroll.dist = "BetaDist", the enroll.dist.par should contain the parameter of the beta distribution (a and b). These parameters must be derived according to the expected enrollment at a specific timepoint. For example, if half the patients are expected to be enrolled at 75% of the enrollment period, the beta distribution is a Beta(log(0.5)/log(0.75), 1). Generally, let q be the proportion of enrolled patients at 100p% of the enrollment period, the Beta distribution can be derived as follows:

• If q < p, the Beta distribution is Beta(a,1) with a = log(q) / log(p)

• If q > p, the Beta distribution is Beta (1,b) with b = log(1-q) / log(1-p)

• Otherwise the Beta distribution is Beta(1,1)

#### Example

Examples of Design objects:

Specify parameters of the enrollment and dropout processes with a uniform enrollment distribution and exponential dropout distribution:

# Design parameters (in months)
Design(enroll.period = 9,
study.duration = 21,
enroll.dist = "UniformDist",
dropout.dist = "ExpoDist",
dropout.dist.par = parameters(rate = 0.0115)) 

# Analysis model

Analysis models define statistical methods (e.g., significance tests or descriptive statistics) that are applied to the study data in a clinical trial.

## Initialization

An analysis model can be initialized using the following command:

# AnalysisModel initialization
analysis.model = AnalysisModel()

It is highly recommended to use this command to initialize an analysis model as it will simplify the process of specifying components of the data model, including the MultAdj, MultAdjProc, MultAdjStrategy, Test, Statistic objects.

## Components of an analysis model

After an AnalysisModel object has been initialized, components of the analysis model can be specified by adding objects to the model using the ‘+’ operator as shown below.

# Analysis model
case.study1.analysis.model = AnalysisModel() +
Test(id = "Placebo vs treatment",
samples = samples("Placebo", "Treatment"),
method = "TTest") +
Statistic(id = "Mean Treatment",
method = "MeanStat",
samples = samples("Treatment"))

### Test object

#### Description

This object specifies a significance test that will be applied to one or more samples defined in a data model. A Test object is defined by the following four arguments:

• id defines the test’s unique ID (label).

• method defines the significance test.

• samples defines the IDs of the samples (defined in the data model) that the significance test is applied to.

• par defines the parameter(s) of the statistical test.

Several commonly used significance tests are already implemented in the Mediana package. In addition, the user can easily define custom significance tests (see the dedicated vignette vignette("custom-functions", package = "Mediana")). The built-in tests are listed below along with the required parameters that need to be included in the par argument:

• TTest: perform the two-sample t-test between the two samples defined in the samples argument. Optional parameter: larger (Larger value is expected in the second sample (TRUE or FALSE)).

• TTestNI: perform the non-inferiority two-sample t-test between the two samples defined in the samples argument. Required parameter: margin (positive non-inferiority margin). Optional parameter: larger (Larger value is expected in the second sample (TRUE or FALSE)).

• WilcoxTest: perform the Wilcoxon-Mann-Whitney test between the two samples defined in the samples argument. Optional parameter: larger (Larger value is expected in the second sample (TRUE or FALSE)).

• PropTest: perform the two-sample test for proportions between the two samples defined in the samples argument. Optional parameter: yates (Yates’ continuity correction flag that is set to TRUE or FALSE) and larger (Larger value is expected in the second sample (TRUE or FALSE)).

• PropTestNI: perform the non-inferiority two-sample test for proportions between the two samples defined in the samples argument. Required parameter: margin (positive non-inferiority margin). Optional parameter: yates (Yates’ continuity correction flag that is set to TRUE or FALSE) and larger (Larger value is expected in the second sample (TRUE or FALSE)).

• FisherTest: perform the Fisher exact test between the two samples defined in the samples argument. Optional parameter: larger (Larger value is expected in the second sample (TRUE or FALSE)).

• GLMPoissonTest: perform the Poisson regression test between the two samples defined in the samples argument. Optional parameter: larger (Larger value is expected in the second sample (TRUE or FALSE)).

• GLMNegBinomTest: perform the Negative-binomial regression test between the two samples defined in the samples argument. Optional parameter: larger (Larger value is expected in the second sample (TRUE or FALSE)).

• LogrankTest: perform the Log-rank test between the two samples defined in the samples argument. Optional parameter: larger (Larger value is expected in the second sample (TRUE or FALSE)).

• OrdinalLogisticRegTest: perform an ordinal logistic regression test between the two samples defined in the samples argument. Optional parameter: larger (Larger value is expected in the second sample (TRUE or FALSE)).

It needs to be noted that the significance tests listed above are implemented as one-sided tests and thus the sample order in the samples argument is important. In particular, the Mediana package assumes by default that a numerically larger value of the endpoint is expected in Sample 2 compared to Sample 1. Suppose, for example, that a higher treatment response indicates a beneficial effect (e.g., higher improvement rate). In this case Sample 1 should include control patients whereas Sample 2 should include patients allocated to the experimental treatment arm. The sample order needs to be reversed if a beneficial treatment effect is associated with a lower value of the endpoint (e.g., lower blood pressure), or alternatively (from version 1.0.6), the optional parameters larger must be set to FALSE to indicate that a larger value is expected on the first Sample.

Several Test objects can be added to an AnalysisModelobject.

For more information about the Test object, see the package’s documentation Test on the CRAN web site.

#### Example

Examples of Test objects:

Carry out the two-sample t-test:

# Placebo and Treatment samples were defined in the data model
Test(id = "Placebo vs treatment",
samples = samples("Placebo", "Treatment"),
method = "TTest")

Carry out the two-sample t-test with larger values expected in the first sample (from v1.0.6):

# Placebo and Treatment samples were defined in the data model
Test(id = "Placebo vs treatment",
samples = samples("Treatment", "Placebo"),
method = "TTest",
par = parameters(larger = FALSE))

Carry out the two-sample t-test for non-inferiority:

# Placebo and Treatment samples were defined in the data model
Test(id = "Placebo vs treatment",
samples = samples("Placebo", "Treatment"),
method = "TTestNI",
par = parameters(margin = 0.2))

Carry out the two-sample t-test with pooled samples:

# Placebo M-, Placebo M+, Treatment M- and Treatment M+ samples were defined in the data model
Test(id = "OP test",
samples = samples(c("Placebo M-", "Placebo M+"),
c("Treatment M-", "Treatment M+")),
method = "TTest")

### Statistic object

#### Description

This object specifies a descriptive statistic that will be computed based on one or more samples defined in a data model. A Statistic object is defined by four arguments:

• id defines the descriptive statistic’s unique ID (label).

• method defines the type of statistic/method for computing the statistic.

• samples defines the samples (pre-defined in the data model) to be used for computing the statistic.

• par defines the parameter(s) of the statistic.

Several methods for computing descriptive statistics are already implemented in the Mediana package and the user can also define custom functions for computing descriptive statistics (see the dedicated vignette vignette("custom-functions", package = "Mediana")). These methods are shown below along with the required parameters that need to be defined in the par argument:

• MedianStat: compute the median of the sample defined in the samples argument.

• MeanStat: compute the mean of the sample defined in the samples argument.

• SdStat: compute the standard deviation of the sample defined in the samples argument.

• MinStat: compute the minimum value in the sample defined in the samples argument.

• MaxStat: compute the maximum value in the sample defined in the samples argument.

• DiffMeanStat: compute the difference of means between the two samples defined in the samples argument. Two samples must be defined.

• EffectSizeContStat: compute the effect size for a continuous endpoint. Two samples must be defined.

• RatioEffectSizeContStat: compute the ratio of two effect sizes for a continuous endpoint. Four samples must be defined.

• PropStat: generate the proportion of the sample defined in the samples argument.

• DiffPropStat: compute the difference of the proportions between the two samples defined in the samples argument. Two samples must be defined.

• EffectSizePropStat: compute the effect size for a binary endpoint. Two samples must be defined.

• RatioEffectSizePropStat: compute the ratio of two effect sizes for a binary endpoint. Four samples must be defined.

• HazardRatioStat: compute the hazard ratio of the two samples defined in the samples argument. Two samples must be defined. By default the Log-Rank method is used. Optional argument: method taking as value Log-Rank or Cox.

• EffectSizeEventStat: compute the effect size for a survival endpoint (log of the HR. Two samples must be defined. Two samples must be defined. By default the Log-Rank method is used. Optional argument: method taking as value Log-Rank or Cox.

• RatioEffectSizeEventStat: compute the ratio of two effect sizes for a survival endpoint based on the Log-Rank method. Four samples must be defined. By default the Log-Rank method is used. Optional argument: method taking as value Log-Rank or Cox.

• EventCountStat: compute the number of events observed in the sample(s) defined in the samples argument.

• PatientCountStat: compute the number of patients observed in the sample(s) defined in the samples argument

Several Statistic objects can be added to an AnalysisModel object.

For more information about the Statistic object, see the R documentation Statistic.

#### Example

Examples of Statistic objects:

Compute the mean of a single sample:

# Treatment sample was defined in the data model
Statistic(id = "Mean Treatment",
method = "MeanStat",
samples = samples("Treatment"))

### MultAdjProc object

#### Description

This object specifies a multiplicity adjustment procedure that will be applied to the significance tests in order to protect the overall Type I error rate. A MultAdjProc object is defined by three arguments:

• proc defines a multiplicity adjustment procedure.

• par defines the parameter(s) of the multiplicity adjustment procedure (optional).

• tests defines the specific tests (defined in the analysis model) to which the multiplicity adjustment procedure will be applied.

If no tests are defined, the multiplicity adjustment procedure will be applied to all tests defined in the AnalysisModel object.

Several commonly used multiplicity adjustment procedures are included in the Mediana package. In addition, the user can easily define custom multiplicity adjustments. The built-in multiplicity adjustments are defined below along with the required parameters that need to be included in the par argument:

• BonferroniAdj: Bonferroni procedure. Optional parameter: weight (vector of hypothesis weights).

• HolmAdj: Holm procedure. Optional parameter: weight (vector of hypothesis weights).

• HochbergAdj: Hochberg procedure. Optional parameter: weight (vector of hypothesis weights).

• HommelAdj: Hommel procedure. Optional parameter: weight (vector of hypothesis weights).

• FixedSeqAdj: Fixed-sequence procedure.

• ChainAdj: Family of chain procedures. Required parameters: weight (vector of hypothesis weights) and transition (matrix of transition parameters).

• FallbackAdj: Fallback procedure. Required parameters: weight (vector of hypothesis weights).

• NormalParamAdj: Parametric multiple testing procedure derived from a multivariate normal distribution. Required parameter: corr (correlation matrix of the multivariate normal distribution). Optional parameter: weight (vector of hypothesis weights).

• ParallelGatekeepingAdj: Family of parallel gatekeeping procedures. Required parameters: family (vectors of hypotheses included in each family), proc (vector of procedure names applied to each family), gamma (vector of truncation parameters).

• MultipleSequenceGatekeepingAdj: Family of multiple-sequence gatekeeping procedures. Required parameters: family (vectors of hypotheses included in each family), proc (vector of procedure names applied to each family), gamma (vector of truncation parameters).

• MixtureGatekeepingAdj: Family of mixture-based gatekeeping procedures. Required parameters: family (vectors of hypotheses included in each family), proc (vector of procedure names applied to each family), gamma (vector of truncation parameters), serial (matrix of indicators), parallel (matrix of indicators).

Several MultAdjProc objects can be added to an AnalysisModelobject using the ‘+’ operator or by grouping them into a MultAdj object.

For more information about the MultAdjProc object, see the package’s documentation MultAdjProc.

#### Example

Examples of MultAdjProc objects:

Apply a multiplicity adjustment based on the chain procedure:

# Parameters of the chain procedure (equivalent to a fixed-sequence procedure)
# Vector of hypothesis weights
chain.weight = c(1, 0)
# Matrix of transition parameters
chain.transition = matrix(c(0, 1,
0, 0), 2, 2, byrow = TRUE)

par = parameters(weight = chain.weight,
transition = chain.transition))

This procedure implementation is facilicated by the use of the FixedSeqAdj method intoduced in version 1.0.4.

# MultAdjProc
MultAdjProc(proc = "FixedSeqAdj")

Apply a multiple-sequence gatekeeping procedure:

# Parameters of the multiple-sequence gatekeeping procedure
# Tests to which the multiplicity adjustment will be applied (defined in the AnalysisModel)
test.list = tests("Pl vs DoseH - ACR20",
"Pl vs DoseL - ACR20",
"Pl vs DoseH - HAQ-DI",
"Pl vs DoseL - HAQ-DI")

# Hypothesis included in each family (the number corresponds to the position of the test in the test.list vector)
family = families(family1 = c(1, 2),
family2 = c(3, 4))

# Component procedure of each family

# Truncation parameter of each family
gamma = families(family1 = 0.8,
family2 = 1)

par = parameters(family = family,
proc = component.procedure,
gamma = gamma),
tests = test.list)

### MultAdjStrategy object

#### Description

This object specifies a multiplicity adjustment strategy that can include several multiplicity adjustment procedures. A multiplicity adjustment strategy may be defined when the same Clinical Scenario Evaluation approach is applied to several clinical trials.

A MultAdjStrategy object serves as a wrapper for several MultAdjProc objects.

For more information about the MultAdjStrategy object, see the package’s documentation MultAdjStrategy.

#### Example

Example of a MultAdjStrategy object:

Perform complex multiplicity adjustments based on gatekeeping procedures in two clinical trials with three endpoints:

# Parallel gatekeeping procedure parameters
family = families(family1 = c(1),
family2 = c(2, 3))

gamma = families(family1 = 0.8,
family2 = 1)

# Multiple sequence gatekeeping procedure parameters for Trial A
par = parameters(family = family,
proc = component.procedure,
gamma = gamma),
tests = tests("Trial A Pla vs Trt End1",
"Trial A Pla vs Trt End2",
"Trial A Pla vs Trt End3"))

par = parameters(family = family,
proc = component.procedure,
gamma = gamma),
tests = tests("Trial B Pla vs Trt End1",
"Trial B Pla vs Trt End2",
"Trial B Pla vs Trt End3"))

# Analysis model
analysis.model = AnalysisModel() +
# Tests for study A
Test(id = "Trial A Pla vs Trt End1",
method = "PropTest",
samples = samples("Trial A Plac End1", "Trial A Trt End1")) +
Test(id = "Trial A Pla vs Trt End2",
method = "TTest",
samples = samples("Trial A Plac End2", "Trial A Trt End2")) +
Test(id = "Trial A Pla vs Trt End3",
method = "TTest",
samples = samples("Trial A Plac End3", "Trial A Trt End3")) +
# Tests for study B
Test(id = "Trial B Pla vs Trt End1",
method = "PropTest",
samples = samples("Trial B Plac End1", "Trial B Trt End1")) +
Test(id = "Trial B Pla vs Trt End2",
method = "TTest",
samples = samples("Trial B Plac End2", "Trial B Trt End2")) +
Test(id = "Trial B Pla vs Trt End3",
method = "TTest",
samples = samples("Trial B Plac End3", "Trial B Trt End3"))

### MultAdj object

#### Description

This object can be used to combine several MultAdjProc or MultAdjStrategy objects and add them as a single object to an AnalysisModel object . This object is provided mainly for convenience and its use is optional. Alternatively, MultAdjProc or MultAdjStrategy objects can be added to an AnalysisModel object incrementally using the ‘+’ operator.

For more information about the MultAdj object, see the package’s documentation MultAdj.

#### Example

Example of a MultAdj object:

Perform Clinical Scenario Evaluation to compare three candidate multiplicity adjustment procedures:

# Multiplicity adjustments to compare

# Analysis model
analysis.model = AnalysisModel() +
Test(id = "Pl vs Dose L",
samples = samples("Placebo", "Dose L"),
method = "TTest") +
Test(id = "Pl vs Dose M",
samples = samples ("Placebo", "Dose M"),
method = "TTest") +
Test(id = "Pl vs Dose H",
samples = samples("Placebo", "Dose H"),
method = "TTest")

# Note that the code presented above is equivalent to:
analysis.model = AnalysisModel() +
Test(id = "Pl vs Dose L",
samples = samples("Placebo", "Dose L"),
method = "TTest") +
Test(id = "Pl vs Dose M",
samples = samples ("Placebo", "Dose M"),
method = "TTest") +
Test(id = "Pl vs Dose H",
samples = samples("Placebo", "Dose H"),
method = "TTest")

# Evaluation model

Evaluation models are used within the Mediana package to specify the success criteria or metrics for evaluating the performance of the selected clinical scenario (combination of data and analysis models).

## Initialization

An evaluation model can be initialized using the following command:

# EvaluationModel initialization
evaluation.model = EvaluationModel()

It is highly recommended to use this command to initialize an evaluation model because it simplifies the process of specifying components of the evaluation model such as Criterion objects.

## Components of an evaluation model

After an EvaluationModel object has been initialized, components of the evaluation model can be specified by adding objects to the model using the ‘+’ operator as shown below.

# Evaluation model
case.study1.evaluation.model = EvaluationModel() +
Criterion(id = "Marginal power",
method = "MarginalPower",
tests = tests("Placebo vs treatment"),
labels = c("Placebo vs treatment"),
par = parameters(alpha = 0.025))  +
Criterion(id = "Average Mean",
method = "MeanSumm",
statistics = statistics("Mean Treatment"),
labels = c("Average Mean Treatment"))

### Criterion object

#### Description

This object specifies the success criteria that will be applied to a clinical scenario to evaluate the performance of selected analysis methods. A Criterion object is defined by six arguments:

• id defines the criterion’s unique ID (label).

• method defines the criterion.

• tests defines the IDs of the significance tests (defined in the analysis model) that the criterion is applied to.

• statistics defines the IDs the descriptive statistics (defined in the analysis model) that the criterion is applied to.

• par defines the parameter(s) of the criterion.

• label defines the label(s) of the criterion values (the label(s) will be used in the simulation report).

Several commonly used success criteria are implemented in the Mediana package. The user can also define custom significance criteria. The built-in success criteria are listed below along with the required parameters that need to be included in the par argument:

• MarginalPower: compute the marginal power of all tests included in the test argument. Required parameter: alpha (significance level used in each test).

• WeightedPower: compute the weighted power of all tests included in the test argument. Required parameters: alpha (significance level used in each test) and weight (vector of weights assigned to the significance tests).

• DisjunctivePower: compute the disjunctive power (probability of achieving statistical significance in at least one test included in the test argument). Required parameter: alpha (significance level used in each test).

• ConjunctivePower: compute the conjunctive power (probability of achieving statistical significance in all tests included in the test argument). Required parameter: alpha (significance level used in each test).

• ExpectedRejPower: compute the expected number of statistical significant tests. Required parameter: alpha(significance level used in each test).

Several Criterion objects can be added to an EvaluationModel object.

For more information about the Criterion object, see the package’s documentation Criterion.

If a certain success criterion is not implemented in the Mediana package, the user can create a custom function and use it within the package (see the dedicated vignette vignette("custom-functions", package = "Mediana")).

#### Examples

Examples of Criterion objects:

Compute marginal power with alpha = 0.025:

Criterion(id = "Marginal power",
method = "MarginalPower",
tests = tests("Placebo vs treatment"),
labels = c("Placebo vs treatment"),
par = parameters(alpha = 0.025))

Compute weighted power with alpha = 0.025 and unequal test-specific weights:

Criterion(id = "Weighted power",
method = "WeightedPower",
tests = tests("Placebo vs treatment - Endpoint 1",
"Placebo vs treatment - Endpoint 2"),
labels = c("Weighted power"),
par = parameters(alpha = 0.025,
weight = c(2/3, 1/3)))

Compute disjunctive power with alpha = 0.025:

Criterion(id = "Disjunctive power",
method = "DisjunctivePower",
tests = tests("Placebo vs Dose H",
"Placebo vs Dose M",
"Placebo vs Dose L"),
labels = c("Disjunctive power"),
par = parameters(alpha = 0.025))

# Clinical Scenario Evaluation

Clinical Scenario Evaluation (CSE) is performed based on the data, analysis and evaluation models as well as simulation parameters specified by the user. The simulation parameters are defined using the SimParameters object.

## Clinical Scenario Evaluation objects

### SimParameters object

#### Description

The SimParameters object is a required argument of the CSE function and has the following arguments:

• n.sims defines the number of simulations.
• seed defines the seed to be used in the simulations.
• proc.load defines the processor load in parallel computations.

The proc.load argument is used to define the number of processor cores dedicated to the simulations. A numeric value can be defined as well as character value which automatically detects the number of cores:

• low: 1 processor core.

• med: Number of available processor cores / 2.

• high: Number of available processor cores 1.

• full: All available processor cores.

#### Examples

Examples of SimParameters object specification:

Perform 10000 simulations using all available processor cores:

SimParameters(n.sims = 10000,
seed = 42938001)

Perform 10000 simulations using 2 processor cores:

SimParameters(n.sims = 10000,
seed = 42938001)

### CSE function

#### Description

The CSE function is invoked to runs simulations under the Clinical Scenario Evaluation approach. This function uses four arguments:

• data defines a DataModel object.

• analysis defines an AnalysisModel object.

• evaluation defines an EvaluationModel object.

• simulation defines a SimParameters object.

#### Examples

The following example illustrates the use of the CSE function:

# Outcome parameter set 1
outcome1.placebo = parameters(mean = 0, sd = 70)
outcome1.treatment = parameters(mean = 40, sd = 70)

# Outcome parameter set 2
outcome2.placebo = parameters(mean = 0, sd = 70)
outcome2.treatment = parameters(mean = 50, sd = 70)

# Data model
case.study1.data.model = DataModel() +
OutcomeDist(outcome.dist = "NormalDist") +
SampleSize(c(50, 55, 60, 65, 70)) +
Sample(id = "Placebo",
outcome.par = parameters(outcome1.placebo, outcome2.placebo)) +
Sample(id = "Treatment",
outcome.par = parameters(outcome1.treatment, outcome2.treatment))

# Analysis model
case.study1.analysis.model = AnalysisModel() +
Test(id = "Placebo vs treatment",
samples = samples("Placebo", "Treatment"),
method = "TTest")

# Evaluation model
case.study1.evaluation.model = EvaluationModel() +
Criterion(id = "Marginal power",
method = "MarginalPower",
tests = tests("Placebo vs treatment"),
labels = c("Placebo vs treatment"),
par = parameters(alpha = 0.025))

# Simulation Parameters
case.study1.sim.parameters = SimParameters(n.sims = 1000, proc.load = 2, seed = 42938001)

# Perform clinical scenario evaluation
case.study1.results = CSE(case.study1.data.model,
case.study1.analysis.model,
case.study1.evaluation.model,
case.study1.sim.parameters)

### Summary of results

Once Clinical Scenario Evaluation-based simulations have been run, the CSE object returned by the CSE function contains a list with the following components:

• simulation.results: a data frame containing the results of the simulations for each scenario.

• analysis.scenario.grid: a data frame containing the grid of the combination of data and analysis scenarios.

• data.structure: a list containing the data structure according to the DataModel object.

• analysis.structure: a list containing the analysis structure according to the AnalysisModel object.

• evaluation.structure: a list containing the evaluation structure according to the EvaluationModel object.

• sim.parameters: a list containing the simulation parameters according to SimParameters object.

• timestamp: a list containing information about the start time, end time and duration of the simulation runs.

The simulation results can be summarized in the R console using the summary function:

summary(case.study1.results)

A Microsoft Word-based simulation report can be generated from the simulation results produced by the CSE function using the GenerateReport function, see Simulation report.

# Simulation report

The Mediana R package uses the officer R package package to generate a Microsoft Word-based report that summarizes the results of Clinical Scenario Evaluation-based simulations.

The user can easily customize this simulation report by adding a description of the project as well as labels to each scenario, including data scenarios (sample size, outcome distribution parameters, design parameters) and analysis scenarios (multiplicity adjustment). The user can also customize the report’s structure, e.g., create sections and subsections within the report and specify how the rows will be sorted within each table.

In order to customize the report, the user has to use a PresentationModel object described below.

Once a PresentationModel object has been defined, the GenerateReport function can be called to generate a Clinical Scenario Evaluation report.

## Initialization

A presentation model can be initialized using the following command

# PresentationModel initialization
presentation.model = PresentationModel()

Initialization with this command is highly recommended as it will simplify the process of adding related objects, e.g., the Project, Section, Subsection, Table, CustomLabel objects.

## Specific objects

Once the PresentationModel object has been initialized, specific objects can be added by simply using the ‘+’ operator as in data, analysis and evaluation models.

### Project object

#### Description

This object specifies a description of the project. The Project object is defined by three optional arguments:

• username defines the username to be included in the report (by default, the username is “[Unknown User]”).

• title defines the project’s in the report (the default value is “[Unknown title]”).

• description defines the project’s description (the default value is “[No description]”).

This information will be added in the report generated using the GenerateReport function.

A single object of the Project class can be added to an object of the PresentationModel class.

#### Examples

A simple Project object can be created as follows:

Project(username = "Gautier Paux",
title = "Case study 1",
description = "Clinical trial in patients with pulmonary arterial hypertension")

### Section object

#### Description

This object specifies the sections that will be created within the simulation report. A Section object is defined by a single argument:

• by defines the rules for setting up sections.

The by argument can contain several parameters from the following list:

• sample.size: a separate section will be created for each sample size.

• event: a separate section will be created for each event count.

• outcome.parameter: a separate section will be created for each outcome parameter scenario.

• design.parameter: a separate section will be created for each design parameter scenario.

• multiplicity.adjustment: a separate section will be created for each multiplicity adjustment scenario.

Note that, if a parameter is defined in the by argument, it must be defined only in this object (i.e., neither in the Subection object nor in the Table object).

A single object of the Section class can be added to an object of the PresentationModel class.

#### Examples

A Section object can be defined as follows:

Create a separate section within the report for each outcome parameter scenario:

Section(by = "outcome.parameter") 

Create a separate section for each unique combination of the sample size and outcome parameter scenarios:

Section(by = c("sample.size", "outcome.parameter"))

### Subsection object

#### Description

This object specifies the rules for creating subsections within the simulation report. A Subsection object is defined by a single argument:

• by defines the rules for creating subsections.

The by argument can contain several parameters from the following list:

• sample.size: a separate subsection will be created for each sample size.

• event: a separate subsection will be created for each number of events.

• outcome.parameter: a separate subsection will be created for each outcome parameter scenario.

• design.parameter: a separate subsection will be created for each design parameter scenario.

• multiplicity.adjustment: a separate subsection will be created for each multiplicity adjustment scenario.

As before, if a parameter is defined in the by argument, it must be defined only in this object (i.e., neither in the Section object nor in the Table object).

A single object of the Subsection class can be added to an object of the PresentationModel class. #### Examples

Subsection objects can be set up as follows:

Create a separate subsection for each sample size scenario:

Subsection(by = "sample.size") 

Create a separate subsection for each unique combination of the sample size and outcome parameter scenarios:

Subsection(by = c("sample.size", "outcome.parameter"))

### Table object

#### Description

This object specifies how the summary tables will be sorted within the report. A Table object is defined by a single argument:

• by defines how the tables of the report will be sorted.

The by argument can contain several parameters, the value must be contain in the following list:

• sample.size: the tables will be sorted by the sample size.

• event: the tables will be sorted by the number of events.

• outcome.parameter: the tables will be sorted by the outcome parameter scenario.

• design.parameter: the tables will be sorted by the design parameter scenario.

• multiplicity.adjustment: the tables will be sorted by the multiplicity adjustment scenario.

If a parameter is defined in the by argument it must be defined only in this object (i.e., neither in the Section object nor in the Subsection object).

A single object of class Table can be added to an object of class PresentationModel.

#### Examples

Examples of Table objects:

Create a summary table sorted by sample size scenarios:

Table(by = "sample.size") 

Create a summary table sorted by sample size and outcome parameter scenarios:

Table(by = c("sample.size", "outcome.parameter"))

### CustomLabel object

#### Description

This object specifies the labels that will be assigned to sets of parameter values or simulation scenarios. These labels will be used in the section and subsection titles of the Clinical Scenario Evaluation Report as well as in the summary tables. A CustomLabel object is defined by two arguments:

• param defines a parameter (scenario) to which the current set of labels will be assigned.

• label defines the label(s) to assign to each value of the parameter.

The param argument can contain several parameters from the following list:

• sample.size: labels will be applied to sample size values.

• event: labels will be applied to number of events values.

• outcome.parameter: labels will be applied to outcome parameter scenarios.

• design.parameter: labels will be applied to design parameter scenarios.

• multiplicity.adjustment: labels will be applied to multiplicity adjustment scenarios.

Several objects of the CustomLabel class can be added to an object of the PresentationModel class.

#### Examples

Examples of CustomLabel objects:

Assign a custom label to the sample size values:

CustomLabel(param = "sample.size",
label= paste0("N = ",c(50, 55, 60, 65, 70)))

Assign a custom label to the outcome parameter scenarios:

CustomLabel(param = "outcome.parameter",
label=c("Pessimistic", "Expected", "Optimistic"))

## GenerateReport function

### Description

The Clinical Scenario Evaluation Report is generated using the GenerateReport function. This function has four arguments:

• presentation.model defines a PresentationModel object.

• cse.result defines a CSE object returned by the CSE function.

• report.filename defines the filename of the Word-based report generated by this function.

• report.template defines a Word-based template (it is an optional argument).

The GenerateReport function requires the officer R package package to generate a Word-based simulation report. Optionally, a custom template can be selected by defining report.template, this argument specifies the name of a Word document located in the working directory.

The Word-based simulation report is structured as follows:

1. GENERAL INFORMATION
1. PROJECT INFORMATION
2. SIMULATION PARAMETERS
2. DATA MODEL
1. DESIGN (if a Design object has been defined)
2. SAMPLE SIZE (or EVENT if an Event object has been defined)
3. OUTCOME DISTRIBUTION
4. DESIGN
3. ANALYSIS MODEL
1. TESTS
4. EVALUATION MODEL
1. CRITERIA
5. RESULTS
1. SECTION (if a Section object has been defined)
1. SUBSECTION (if a Subsection object has been defined)

### Examples

This example illustrates the use of the GenerateReport function:

# Define a presentation model
case.study1.presentation.model = PresentationModel() +
Section(by = "outcome.parameter") +
Table(by = "sample.size") +
CustomLabel(param = "sample.size",
label= paste0("N = ",c(50, 55, 60, 65, 70))) +
CustomLabel(param = "outcome.parameter",
label=c("Standard 1", "Standard 2"))

# Report Generation
GenerateReport(presentation.model = case.study1.presentation.model,
cse.results = case.study1.results,
report.filename = "Case study 1 (normally distributed endpoint).docx")