Stc Methodology
by choxos
Deep methodology knowledge for STC including outcome regression approach, effect modifier selection, covariate centering, and comparison with MAIC. Use when conducting or reviewing STC analyses.
Skill Details
Repository Files
1 file in this skill directory
name: stc-methodology description: Deep methodology knowledge for STC including outcome regression approach, effect modifier selection, covariate centering, and comparison with MAIC. Use when conducting or reviewing STC analyses.
STC Methodology
Comprehensive methodological guidance for conducting rigorous Simulated Treatment Comparisons following NICE DSU TSD 18.
When to Use This Skill
- Deciding between STC and MAIC
- Selecting effect modifiers for STC model
- Understanding the covariate centering approach
- Implementing Bayesian STC
- Reviewing STC code or results
Fundamental Concept
Outcome Regression vs Propensity Weighting
STC Approach:
- Fit outcome regression model in IPD
- Include treatment and treatment-covariate interactions
- Predict treatment effect at external population covariate values
- Model-based adjustment for population differences
MAIC Approach:
- Reweight IPD to match external population
- Analyze weighted data as if from external population
- Design-based adjustment
Key Equation (Binary Outcome)
logit(P(Y=1)) = β₀ + β_trt × Treatment + β_X × X + β_trt:X × Treatment × X
Where:
- β_trt: Treatment effect when X = 0
- β_X: Effect of covariate X on outcome
- β_trt:X: Treatment-covariate interaction (effect modification)
For anchored STC:
1. Center X on external population mean: X_centered = X - X_external
2. Fit model with centered X
3. β_trt now represents treatment effect at external population values
Assumptions
Conditional Constancy of Relative Effects
Same as MAIC:
- Relative treatment effect is constant across populations after adjusting for effect modifiers
- Requires all effect modifiers included in model
Model Specification
Additional assumption vs MAIC:
- Outcome model must be correctly specified
- Includes functional form of covariate effects
- Includes correct interactions
Trade-off:
├── If model correct → STC more efficient than MAIC
├── If model wrong → STC may be biased
└── MAIC doesn't require outcome model specification
Effect Modifier Selection
What is an Effect Modifier?
A covariate that interacts with treatment effect:
- Treatment effect differs at different covariate values
- Shows significant treatment × covariate interaction
- Has biological plausibility for interaction
Selection Strategy
Effect Modifier Identification:
├── 1. Clinical/Biological Rationale
│ - Published literature on effect modification
│ - Mechanism of action considerations
│ - Expert clinical input
│
├── 2. Statistical Evidence (from IPD)
│ - Interaction terms in regression
│ - Subgroup analyses
│ - Use α = 0.10 (underpowered for interactions)
│
├── 3. Availability in AgD
│ - Must have summary statistics
│ - Means for continuous, proportions for binary
│
└── 4. Imbalance Between Populations
- Focus on covariates that differ
- Balanced covariates less important
Using identify_effect_modifiers()
em_result <- identify_effect_modifiers(
data = ipd_data,
outcome_var = "response",
treatment_var = "treatment",
candidate_covariates = c("age", "sex", "biomarker", "stage"),
alpha = 0.10
)
# Returns:
# - Interaction p-values
# - Interaction coefficients
# - Recommended effect modifiers
Covariate Centering
Why Center Covariates?
Without centering (X = raw values):
- β_trt = treatment effect when ALL covariates = 0
- This may be meaningless (e.g., age = 0)
With centering (X_centered = X - X_external):
- β_trt = treatment effect when X = X_external
- This is the effect in external trial population
- Exactly what we need for ITC
Centering Process
# For continuous covariate
age_centered <- age - agd_mean_age
# For binary covariate
male_centered <- male - agd_prop_male
# Result: mean of centered covariate = (IPD mean - AgD mean)
# When evaluated at X_centered = 0, we get AgD population
Including vs Excluding Main Effects
With interactions:
# Model: Y ~ treatment + X_centered + treatment:X_centered
# β_trt: effect at X = X_external
# β_trt:X: how effect changes with X
Main effects typically included even if not "significant":
- Required for proper interpretation of interactions
- Follows statistical best practice
- Model hierarchically well-formulated
Anchored vs Unanchored STC
Anchored STC
Setup:
- IPD trial: A vs Common (C)
- AgD trial: B vs Common (C)
Steps:
1. Center covariates on AgD population
2. Fit: logit(Y) ~ Treatment + X_centered + Treatment:X_centered
3. Extract β_A (A vs C at AgD population)
4. Calculate d_BC from AgD (B vs C)
5. Indirect: d_AB = β_A - d_BC
Unanchored STC
Setup:
- IPD trial: Treatment A only (or A vs something)
- AgD: Single-arm Treatment B
Caution: Same issues as unanchored MAIC
- Must adjust for ALL prognostic factors
- Assumes absolute effects transportable
- Strong assumptions - use as sensitivity only
STC vs MAIC Comparison
Theoretical Comparison
| Aspect | STC | MAIC |
|---|---|---|
| Method | Outcome regression | Propensity weighting |
| Efficiency | Higher (if model correct) | Lower (ESS reduction) |
| Model dependence | Higher | Lower |
| Continuous covariates | Natural | May need categorization |
| Extrapolation | Possible (with caution) | Limited to overlap |
| Diagnostic | Model fit, residuals | ESS, weight distribution |
When to Prefer STC
- Model specification confidence is high
- Continuous covariates to adjust for
- Want to leverage regression framework
- MAIC gives very low ESS
- Interested in Bayesian framework
When to Prefer MAIC
- Uncertain about outcome model
- Want design-based approach
- Good overlap in covariate distributions
- Acceptable ESS achieved
Best Practice: Both as Sensitivity
# Run both methods
stc_result <- anchored_stc_binary(...)
maic_result <- maic_anchored(...)
# Compare results
# If similar: increased confidence
# If different: investigate why
Bayesian STC
Advantages
- Natural uncertainty quantification
- Prior information incorporation
- Posterior predictive checks
- Sensitivity to prior specification
Prior Selection
# Treatment effect prior
prior_normal(0, 10) # Weakly informative
# Covariate effects
prior_normal(0, 5)
# Interactions (typically smaller)
prior_normal(0, 2)
# Sensitivity analysis with different priors
Implementation
bayes_result <- bayesian_anchored_stc_binary(
ipd_data = ipd,
agd_data = agd,
outcome_var = "response",
treatment_var = "treatment",
covariates = c("age", "sex"),
priors = list(
treatment = prior_normal(0, 10),
covariates = prior_normal(0, 5),
interactions = prior_normal(0, 2)
),
n_iter = 10000,
n_warmup = 2000,
seed = 12345
)
Reporting Requirements
Methods
- Justification for STC (vs MAIC, vs nothing)
- Effect modifier selection process
- Covariates included with rationale
- Model specification (link function, interactions)
- Centering approach explained
- Frequentist vs Bayesian justification
- Prior specification (if Bayesian)
Results
- Model coefficients with CIs
- Treatment effect at external population
- Comparison with unadjusted estimate
- Model diagnostics
- Sensitivity analyses (including vs MAIC)
Common Pitfalls
1. Forgetting to Center Covariates
- Treatment coefficient won't have correct interpretation
- Will estimate effect at covariate = 0, not external population
2. Omitting Interactions
- Defeats purpose of STC
- Must include treatment × covariate interactions
3. Including Too Many Covariates
- Model overfitting
- Unstable estimates
- Focus on effect modifiers only
4. Ignoring Model Diagnostics
- Check residuals
- Assess model fit
- Validate assumptions (linearity, etc.)
5. Not Comparing to MAIC
- Both methods should give similar answers
- Differences indicate model issues
- Always run as sensitivity
Quick Reference Code
library(stc)
# 1. Identify effect modifiers
em <- identify_effect_modifiers(
data = ipd,
outcome_var = "response",
treatment_var = "treatment",
candidate_covariates = c("age", "sex", "biomarker"),
alpha = 0.10
)
# 2. Run anchored STC (frequentist)
result <- anchored_stc_binary(
ipd_data = ipd,
agd_data = list(
n_total_A = 150, n_total_C = 150,
n_events_A = 45, n_events_C = 60,
covariates = list(
age = list(mean = 62),
sex = list(prop = 0.55)
)
),
outcome_var = "response",
treatment_var = "treatment",
covariates = c("age", "sex"),
reference_arm = "A",
include_interactions = TRUE,
robust_se = TRUE
)
# 3. View results
print(result)
summary(result)
# 4. Access specific effects
result$treatment_effect_BC # Indirect comparison
result$treatment_effect_AB # Direct from IPD
result$treatment_effect_AC # From AgD
# 5. Bayesian sensitivity
bayes_result <- bayesian_anchored_stc_binary(
...,
priors = list(
treatment = prior_normal(0, 10)
)
)
Resources
- NICE DSU TSD 18: Population-adjusted indirect comparisons
- Phillippo et al. (2018): Methods for STC
- Ishak et al. (2015): Simulation studies
- stc package documentation
Related Skills
Attack Tree Construction
Build comprehensive attack trees to visualize threat paths. Use when mapping attack scenarios, identifying defense gaps, or communicating security risks to stakeholders.
Grafana Dashboards
Create and manage production Grafana dashboards for real-time visualization of system and application metrics. Use when building monitoring dashboards, visualizing metrics, or creating operational observability interfaces.
Matplotlib
Foundational plotting library. Create line plots, scatter, bar, histograms, heatmaps, 3D, subplots, export PNG/PDF/SVG, for scientific visualization and publication figures.
Scientific Visualization
Create publication figures with matplotlib/seaborn/plotly. Multi-panel layouts, error bars, significance markers, colorblind-safe, export PDF/EPS/TIFF, for journal-ready scientific plots.
Seaborn
Statistical visualization. Scatter, box, violin, heatmaps, pair plots, regression, correlation matrices, KDE, faceted plots, for exploratory analysis and publication figures.
Shap
Model interpretability and explainability using SHAP (SHapley Additive exPlanations). Use this skill when explaining machine learning model predictions, computing feature importance, generating SHAP plots (waterfall, beeswarm, bar, scatter, force, heatmap), debugging models, analyzing model bias or fairness, comparing models, or implementing explainable AI. Works with tree-based models (XGBoost, LightGBM, Random Forest), deep learning (TensorFlow, PyTorch), linear models, and any black-box model
Pydeseq2
Differential gene expression analysis (Python DESeq2). Identify DE genes from bulk RNA-seq counts, Wald tests, FDR correction, volcano/MA plots, for RNA-seq analysis.
Query Writing
For writing and executing SQL queries - from simple single-table queries to complex multi-table JOINs and aggregations
Pydeseq2
Differential gene expression analysis (Python DESeq2). Identify DE genes from bulk RNA-seq counts, Wald tests, FDR correction, volcano/MA plots, for RNA-seq analysis.
Scientific Visualization
Meta-skill for publication-ready figures. Use when creating journal submission figures requiring multi-panel layouts, significance annotations, error bars, colorblind-safe palettes, and specific journal formatting (Nature, Science, Cell). Orchestrates matplotlib/seaborn/plotly with publication styles. For quick exploration use seaborn or plotly directly.
