agentsclimarketplace

Mediana fundamentals

Skill choxos/BiostatAgent/plugins/clinical-trial-simulation/skills/mediana-fundamentals

Claude Code plugin marketplace for biostatistics in R — 30 agents, 17 commands, and 45 skills spanning Bayesian modeling (Stan/PyMC/JAGS), indirect treatment comparisons (NMA/MAIC/STC/ML-NMR), tidy R workflows, and clinical trial simulation.

Install
npx -y skills add choxos/BiostatAgent --skill mediana-fundamentals

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 8 stars8 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Core Mediana package functions for Clinical Scenario Evaluation (CSE). Use when designing data models, analysis models, evaluation models, and running comprehensive trial simulations.

SKILL.md

14.9 KB, as published. Nobody here has run it

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

data.model <- DataModel()

OutcomeDist - Outcome Distribution

Specifies the distribution of patient outcomes.

OutcomeDist(
  outcome.dist = "NormalDist",   # Distribution type
  outcome.type = "standard"       # "standard" or "event"
)

Supported Distributions:

DistributionParametersUse Case
UniformDistmaxUniform outcomes
NormalDistmean, sdContinuous endpoints
BinomDistpropBinary endpoints
BetaDista, bProportions
ExpoDistrateTime-to-event
WeibullDistshape, scaleSurvival with shape
TruncatedExpoDistrate, truncTruncated survival
PoissonDistlambdaCount data
NegBinomDistdispersion, meanOverdispersed counts
MultinomialDistprobCategorical outcomes

Multivariate Distributions:

DistributionParametersUse Case
MVNormalDistpar, corrCorrelated continuous
MVBinomDistpar, corrCorrelated binary
MVExpoDistpar, corrCorrelated survival
MVExpoPFSOSDistpar, corrPFS/OS endpoints
MVMixedDisttype, par, corrMixed endpoint types

Sample - Treatment Arm Definition

# 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:

# 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

SampleSize(c(50, 55, 60, 65, 70))  # Per arm
SampleSize(seq(50, 100, 10))

Event - Event-Driven Design

Event(
  n.events = c(390, 420),      # Total event counts to evaluate
  rando.ratio = c(1, 2)        # Control:Treatment ratio
)

Design - Enrollment and Dropout

# 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

# 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

analysis.model <- AnalysisModel()

Test - Statistical Tests

Test(
  id = "Primary",                           # Unique test ID
  samples = samples("Placebo", "Treatment"), # Samples to compare
  method = "TTest",                          # Test method
  par = parameters(...)                      # Optional parameters
)

Built-in Tests:

MethodDescriptionParameters
TTestTwo-sample t-testlarger (optional)
TTestNINon-inferiority t-testmargin, larger
WilcoxTestWilcoxon-Mann-Whitneylarger
PropTestTwo-sample proportionyates, larger
PropTestNINI proportion testmargin, yates, larger
FisherTestFisher exact testlarger
GLMPoissonTestPoisson regressionlarger
GLMNegBinomTestNegative binomiallarger
LogrankTestLog-rank testlarger
OrdinalLogisticRegTestOrdinal logisticlarger

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

Statistic(
  id = "Mean Treatment",
  method = "MeanStat",
  samples = samples("Treatment")
)

Built-in Statistics:

MethodDescriptionSamples Required
MeanStatMean1
MedianStatMedian1
SdStatStandard deviation1
MinStatMinimum1
MaxStatMaximum1
PropStatProportion1
DiffMeanStatDifference in means2
DiffPropStatDifference in proportions2
EffectSizeContStatEffect size (continuous)2
EffectSizePropStatEffect size (binary)2
EffectSizeEventStatEffect size (survival)2
HazardRatioStatHazard ratio2
EventCountStatNumber of events1+
PatientCountStatNumber of patients1+

MultAdjProc - Multiplicity Adjustment

MultAdjProc(
  proc = "HolmAdj",
  par = parameters(weight = c(0.5, 0.5)),
  tests = tests("Test1", "Test2")  # Optional: applies to all if omitted
)

Built-in Procedures:

ProcedureTypeParameters
BonferroniAdjSingle-stepweight
HolmAdjStep-downweight
HochbergAdjStep-upweight
HommelAdjStep-upweight
FixedSeqAdjSequential(order from tests)
ChainAdjGraphicalweight, transition
FallbackAdjFallbackweight
NormalParamAdjParametriccorr, weight
ParallelGatekeepingAdjGatekeepingfamily, proc, gamma
MultipleSequenceGatekeepingAdjGatekeepingfamily, proc, gamma
MixtureGatekeepingAdjGatekeepingfamily, proc, gamma, serial, parallel

Multiplicity Examples

Chain Procedure:

MultAdjProc(
  proc = "ChainAdj",
  par = parameters(
    weight = c(0.5, 0.5),
    transition = matrix(c(0, 1,
                          1, 0), 2, 2, byrow = TRUE)
  )
)

Parallel Gatekeeping:

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:

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

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

evaluation.model <- EvaluationModel()

Criterion - Success Metrics

Criterion(
  id = "Marginal power",
  method = "MarginalPower",
  tests = tests("Primary"),
  labels = c("Primary Power"),
  par = parameters(alpha = 0.025)
)

Built-in Criteria:

MethodDescriptionParameters
MarginalPowerPower for each testalpha
WeightedPowerWeighted combinationalpha, weight
DisjunctivePowerP(reject at least one)alpha
ConjunctivePowerP(reject all)alpha
ExpectedRejPowerExpected # rejectedalpha
MeanSummMean of statistics-
MedianSummMedian of statistics-

Complete Evaluation Model Example

evaluation.model <- EvaluationModel() +
  Criterion(id = "Marginal power",
            method = "MarginalPower",
            tests = tests("PFS test", "OS test"),
            labels = c("PFS Power", "OS Power"),
            par = parameters(alpha = 0.025)) +

  Criterion(id = "Disjunctive power",
            method = "DisjunctivePower",
            tests = tests("PFS test", "OS test"),
            labels = c("At least one significant"),
            par = parameters(alpha = 0.025)) +

  Criterion(id = "Average patients",
            method = "MeanSumm",
            statistics = statistics("Patients Placebo", "Patients Treatment"),
            labels = c("Mean Placebo N", "Mean Treatment N"))

Running Simulations

SimParameters

sim.parameters <- SimParameters(
  n.sims = 10000,        # Number of simulations
  proc.load = "full",    # Parallelization: "low", "med", "high", "full", or integer
  seed = 42938001        # For reproducibility
)

CSE Function

results <- CSE(
  data.model,
  analysis.model,
  evaluation.model,
  sim.parameters
)

# View summary
summary(results)

Results Structure

The CSE function returns a list with:

  • simulation.results: Data frame of results per scenario
  • analysis.scenario.grid: Grid of data/analysis combinations
  • data.structure: Data model structure
  • analysis.structure: Analysis model structure
  • evaluation.structure: Evaluation model structure
  • sim.parameters: Simulation parameters
  • timestamp: Start/end time and duration

Report Generation

PresentationModel

presentation.model <- PresentationModel() +
  Project(username = "Analyst Name",
          title = "Phase III Trial Simulation",
          description = "Power analysis for multi-endpoint trial") +
  Section(by = "outcome.parameter") +
  Subsection(by = "sample.size") +
  Table(by = "multiplicity.adjustment") +
  CustomLabel(param = "sample.size",
              label = paste0("N = ", c(50, 60, 70))) +
  CustomLabel(param = "outcome.parameter",
              label = c("Conservative", "Expected", "Optimistic"))

GenerateReport

GenerateReport(
  presentation.model = presentation.model,
  cse.results = results,
  report.filename = "Simulation_Report.docx"
)

Complete Example: Multi-Endpoint Trial

library(Mediana)

# Data Model
outcome.placebo <- parameters(mean = 0, sd = 1)
outcome.trt.conservative <- parameters(mean = 0.3, sd = 1)
outcome.trt.expected <- parameters(mean = 0.5, sd = 1)

data.model <- DataModel() +
  OutcomeDist(outcome.dist = "NormalDist") +
  SampleSize(seq(80, 120, 10)) +
  Sample(id = "Placebo",
         outcome.par = parameters(outcome.placebo, outcome.placebo)) +
  Sample(id = "Treatment",
         outcome.par = parameters(outcome.trt.conservative, outcome.trt.expected))

# Analysis Model
analysis.model <- AnalysisModel() +
  Test(id = "Primary",
       samples = samples("Placebo", "Treatment"),
       method = "TTest") +
  Statistic(id = "Effect Size",
            samples = samples("Placebo", "Treatment"),
            method = "EffectSizeContStat")

# Evaluation Model
evaluation.model <- EvaluationModel() +
  Criterion(id = "Power",
            method = "MarginalPower",
            tests = tests("Primary"),
            labels = "Primary Power",
            par = parameters(alpha = 0.025)) +
  Criterion(id = "Mean Effect",
            method = "MeanSumm",
            statistics = statistics("Effect Size"),
            labels = "Mean Effect Size")

# Run Simulations
results <- CSE(
  data.model,
  analysis.model,
  evaluation.model,
  SimParameters(n.sims = 10000, proc.load = "full", seed = 12345)
)

# View Results
summary(results)

# Generate Report
presentation.model <- PresentationModel() +
  Project(title = "Sample Size Analysis") +
  Section(by = "outcome.parameter") +
  Table(by = "sample.size") +
  CustomLabel(param = "outcome.parameter",
              label = c("Conservative", "Expected"))

GenerateReport(presentation.model, results, "Analysis_Report.docx")

Best Practices

  1. Multiple Scenarios: Always evaluate multiple treatment effect assumptions
  2. Sample Size Range: Test a range of sample sizes to build power curves
  3. Reproducibility: Always set seed in SimParameters
  4. Parallelization: Use proc.load = "full" for large simulations
  5. Report Labels: Use CustomLabel for interpretable scenario names
  6. Validation: Compare CSE results to analytical formulas where available
  7. Multiplicity: Select appropriate procedures based on hypothesis structure

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.