- name
- mediana-fundamentals
- description
- Core Mediana package functions for Clinical Scenario Evaluation (CSE). Use when designing data models, analysis models, evaluation models, and running comprehensive trial simulations.
# Mediana Fundamentals
## When to Use This Skill
- Building Clinical Scenario Evaluation (CSE) frameworks
- Defining data models with various endpoint distributions
- Configuring analysis models with statistical tests
- Setting up multiplicity adjustment procedures
- Defining evaluation criteria (power metrics)
- Running comprehensive trial simulations
- Generating Word-based simulation reports
## Package Overview
**Mediana** by Gautier Paux and Alex Dmitrienko provides a general framework for clinical trial simulations based on the Clinical Scenario Evaluation approach (Benda et al., 2010).
### CSE Framework Components
1. **Data Models** - Define data generation process
2. **Analysis Models** - Define statistical methods
3. **Evaluation Models** - Define success criteria
## Data Model
### Initialization
```r
data.model <- DataModel()
```
### OutcomeDist - Outcome Distribution
Specifies the distribution of patient outcomes.
```r
OutcomeDist(
outcome.dist = "NormalDist", # Distribution type
outcome.type = "standard" # "standard" or "event"
)
```
**Supported Distributions:**
| Distribution | Parameters | Use Case |
|--------------|------------|----------|
| `UniformDist` | `max` | Uniform outcomes |
| `NormalDist` | `mean`, `sd` | Continuous endpoints |
| `BinomDist` | `prop` | Binary endpoints |
| `BetaDist` | `a`, `b` | Proportions |
| `ExpoDist` | `rate` | Time-to-event |
| `WeibullDist` | `shape`, `scale` | Survival with shape |
| `TruncatedExpoDist` | `rate`, `trunc` | Truncated survival |
| `PoissonDist` | `lambda` | Count data |
| `NegBinomDist` | `dispersion`, `mean` | Overdispersed counts |
| `MultinomialDist` | `prob` | Categorical outcomes |
**Multivariate Distributions:**
| Distribution | Parameters | Use Case |
|--------------|------------|----------|
| `MVNormalDist` | `par`, `corr` | Correlated continuous |
| `MVBinomDist` | `par`, `corr` | Correlated binary |
| `MVExpoDist` | `par`, `corr` | Correlated survival |
| `MVExpoPFSOSDist` | `par`, `corr` | PFS/OS endpoints |
| `MVMixedDist` | `type`, `par`, `corr` | Mixed endpoint types |
### Sample - Treatment Arm Definition
```r
# Normal distribution parameters
outcome.placebo <- parameters(mean = 0, sd = 70)
outcome.treatment <- parameters(mean = 40, sd = 70)
# Define samples
Sample(id = "Placebo",
outcome.par = parameters(outcome.placebo))
Sample(id = "Treatment",
outcome.par = parameters(outcome.treatment))
```
**Multiple Scenarios:**
```r
# Define multiple effect size scenarios
outcome1.placebo <- parameters(mean = 0, sd = 70)
outcome1.treatment <- parameters(mean = 40, sd = 70) # Conservative
outcome2.placebo <- parameters(mean = 0, sd = 70)
outcome2.treatment <- parameters(mean = 50, sd = 70) # Optimistic
Sample(id = "Placebo",
outcome.par = parameters(outcome1.placebo, outcome2.placebo))
Sample(id = "Treatment",
outcome.par = parameters(outcome1.treatment, outcome2.treatment))
```
### SampleSize - Balanced Design
```r
SampleSize(c(50, 55, 60, 65, 70)) # Per arm
SampleSize(seq(50, 100, 10))
```
### Event - Event-Driven Design
```r
Event(
n.events = c(390, 420), # Total event counts to evaluate
rando.ratio = c(1, 2) # Control:Treatment ratio
)
```
### Design - Enrollment and Dropout
```r
# Non-uniform enrollment with beta distribution
# 50% enrolled at 75% of enrollment period
enroll.par <- parameters(
a = log(0.5)/log(0.75),
b = 1
)
Design(
enroll.period = 12, # Enrollment duration (months)
study.duration = 36, # Total study duration
enroll.dist = "BetaDist", # Or "UniformDist"
enroll.dist.par = enroll.par,
dropout.dist = "ExpoDist",
dropout.dist.par = parameters(rate = 0.0115)
)
```
### Complete Data Model Example
```r
# Time-to-event trial with PFS and OS
median.pfs.placebo <- 6
median.pfs.treatment <- 9
median.os.placebo <- 15
median.os.treatment <- 19
placebo.par <- parameters(
parameters(rate = log(2)/median.pfs.placebo),
parameters(rate = log(2)/median.os.placebo)
)
treatment.par <- parameters(
parameters(rate = log(2)/median.pfs.treatment),
parameters(rate = log(2)/median.os.treatment)
)
corr.matrix <- matrix(c(1.0, 0.3, 0.3, 1.0), 2, 2)
data.model <- DataModel() +
OutcomeDist(outcome.dist = "MVExpoPFSOSDist",
outcome.type = c("event", "event")) +
Event(n.events = c(390, 420), rando.ratio = c(1, 2)) +
Design(enroll.period = 12, study.duration = 30,
enroll.dist = "BetaDist",
enroll.dist.par = parameters(a = log(0.5)/log(0.75), b = 1),
dropout.dist = "ExpoDist",
dropout.dist.par = parameters(rate = 0.0115)) +
Sample(id = list("Placebo PFS", "Placebo OS"),
outcome.par = parameters(parameters(par = placebo.par,
corr = corr.matrix))) +
Sample(id = list("Treatment PFS", "Treatment OS"),
outcome.par = parameters(parameters(par = treatment.par,
corr = corr.matrix)))
```
## Analysis Model
### Initialization
```r
analysis.model <- AnalysisModel()
```
### Test - Statistical Tests
```r
Test(
id = "Primary", # Unique test ID
samples = samples("Placebo", "Treatment"), # Samples to compare
method = "TTest", # Test method
par = parameters(...) # Optional parameters
)
```
**Built-in Tests:**
| Method | Description | Parameters |
|--------|-------------|------------|
| `TTest` | Two-sample t-test | `larger` (optional) |
| `TTestNI` | Non-inferiority t-test | `margin`, `larger` |
| `WilcoxTest` | Wilcoxon-Mann-Whitney | `larger` |
| `PropTest` | Two-sample proportion | `yates`, `larger` |
| `PropTestNI` | NI proportion test | `margin`, `yates`, `larger` |
| `FisherTest` | Fisher exact test | `larger` |
| `GLMPoissonTest` | Poisson regression | `larger` |
| `GLMNegBinomTest` | Negative binomial | `larger` |
| `LogrankTest` | Log-rank test | `larger` |
| `OrdinalLogisticRegTest` | Ordinal logistic | `larger` |
**Note:** Tests are one-sided. By default, larger values expected in Sample 2. Set `larger = FALSE` if larger values expected in Sample 1.
### Statistic - Descriptive Statistics
```r
Statistic(
id = "Mean Treatment",
method = "MeanStat",
samples = samples("Treatment")
)
```
**Built-in Statistics:**
| Method | Description | Samples Required |
|--------|-------------|------------------|
| `MeanStat` | Mean | 1 |
| `MedianStat` | Median | 1 |
| `SdStat` | Standard deviation | 1 |
| `MinStat` | Minimum | 1 |
| `MaxStat` | Maximum | 1 |
| `PropStat` | Proportion | 1 |
| `DiffMeanStat` | Difference in means | 2 |
| `DiffPropStat` | Difference in proportions | 2 |
| `EffectSizeContStat` | Effect size (continuous) | 2 |
| `EffectSizePropStat` | Effect size (binary) | 2 |
| `EffectSizeEventStat` | Effect size (survival) | 2 |
| `HazardRatioStat` | Hazard ratio | 2 |
| `EventCountStat` | Number of events | 1+ |
| `PatientCountStat` | Number of patients | 1+ |
### MultAdjProc - Multiplicity Adjustment
```r
MultAdjProc(
proc = "HolmAdj",
par = parameters(weight = c(0.5, 0.5)),
tests = tests("Test1", "Test2") # Optional: applies to all if omitted
)
```
**Built-in Procedures:**
| Procedure | Type | Parameters |
|-----------|------|------------|
| `BonferroniAdj` | Single-step | `weight` |
| `HolmAdj` | Step-down | `weight` |
| `HochbergAdj` | Step-up | `weight` |
| `HommelAdj` | Step-up | `weight` |
| `FixedSeqAdj` | Sequential | (order from tests) |
| `ChainAdj` | Graphical | `weight`, `transition` |
| `FallbackAdj` | Fallback | `weight` |
| `NormalParamAdj` | Parametric | `corr`, `weight` |
| `ParallelGatekeepingAdj` | Gatekeeping | `family`, `proc`, `gamma` |
| `MultipleSequenceGatekeepingAdj` | Gatekeeping | `family`, `proc`, `gamma` |
| `MixtureGatekeepingAdj` | Gatekeeping | `family`, `proc`, `gamma`, `serial`, `parallel` |
### Multiplicity Examples
**Chain Procedure:**
```r
MultAdjProc(
proc = "ChainAdj",
par = parameters(
weight = c(0.5, 0.5),
transition = matrix(c(0, 1,
1, 0), 2, 2, byrow = TRUE)
)
)
```
**Parallel Gatekeeping:**
```r
MultAdjProc(
proc = "ParallelGatekeepingAdj",
par = parameters(
family = families(
family1 = c(1, 2), # Primary endpoints
family2 = c(3, 4) # Secondary endpoints
),
proc = families(
family1 = "HolmAdj",
family2 = "HolmAdj"
),
gamma = families(
family1 = 0.8, # Truncation parameter
family2 = 1
)
),
tests = tests("Primary1", "Primary2", "Secondary1", "Secondary2")
)
```
**Multiple-Sequence Gatekeeping:**
```r
MultAdjProc(
proc = "MultipleSequenceGatekeepingAdj",
par = parameters(
family = families(family1 = c(1, 2), family2 = c(3, 4)),
proc = families(family1 = "HolmAdj", family2 = "HochbergAdj"),
gamma = families(family1 = 0.8, family2 = 1)
)
)
```
### Complete Analysis Model Example
```r
analysis.model <- AnalysisModel() +
# Primary tests
Test(id = "PFS test",
samples = samples("Placebo PFS", "Treatment PFS"),
method = "LogrankTest") +
Test(id = "OS test",
samples = samples("Placebo OS", "Treatment OS"),
method = "LogrankTest") +
# Fixed-sequence multiplicity adjustment
MultAdjProc(proc = "FixedSeqAdj") +
# Descriptive statistics
Statistic(id = "Patients Placebo",
samples = samples("Placebo PFS"),
method = "PatientCountStat") +
Statistic(id = "Patients Treatment",
samples = samples("Treatment PFS"),
method = "PatientCountStat")
```
## Evaluation Model
### Initialization
```r
evaluation.model <- EvaluationModel()
```
GitHubで見る