Skip to main content

network-meta-analysis

Network meta-analysis in R, including network setup, consistency, treatment rankings, and league tables.

Aller à l'installation

Informations de source

Dépôt
choxos/BiostatAgent
Dernière activité de la source
27 mai 2026 à 20:44
Langue détectée de SKILL.md
anglais
Étoiles
11
Forks
1

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
network-meta-analysis
description
Network meta-analysis in R, including network setup, consistency, treatment rankings, and league tables.
# Network Meta-Analysis in R ## Overview Network meta-analysis (NMA) methods for comparing multiple treatments simultaneously using direct and indirect evidence. Covers network structure assessment, frequentist and Bayesian NMA approaches, consistency evaluation, treatment rankings, and visualization techniques. ## Network Structure and Data Preparation ### Pairwise Data Format ```r library(netmeta) # Standard pairwise format for contrast-based NMA pairwise_data <- data.frame( study = c("Study1", "Study1", "Study2", "Study2", "Study3", "Study3", "Study4", "Study4", "Study5", "Study5", "Study5"), treat1 = c("A", "A", "A", "B", "B", "B", "A", "C", "A", "B", "C"), treat2 = c("B", "C", "B", "C", "C", "D", "C", "D", "B", "C", "D"), TE = c(0.5, 0.3, 0.4, -0.2, 0.1, 0.3, 0.35, 0.25, 0.45, -0.15, 0.2), seTE = c(0.1, 0.12, 0.11, 0.13, 0.15, 0.14, 0.09, 0.11, 0.10, 0.12, 0.13) ) # Create network meta-analysis object net <- netmeta( TE = TE, seTE = seTE, treat1 = treat1, treat2 = treat2, studlab = study, data = pairwise_data, sm = "MD", # Effect measure reference.group = "A", # Reference treatment all.treatments = NULL # Auto-detect ) summary(net) ``` ### Arm-Level Data Format ```r library(netmeta) # Convert arm-level to pairwise format arm_data <- data.frame( study = rep(c("S1", "S2", "S3"), c(2, 3, 2)), treatment = c("A", "B", "A", "B", "C", "B", "C"), n = c(50, 52, 48, 51, 49, 55, 53), events = c(15, 22, 12, 25, 18, 28, 20) ) # Use pairwise() to convert library(meta) pw <- pairwise( treat = treatment, event = events, n = n, studlab = study, data = arm_data, sm = "OR" ) # Create network net_from_arm <- netmeta(pw) ``` ### Network Visualization ```r library(netmeta) # Network graph netgraph(net, plastic = FALSE, thickness = "number.of.studies", multiarm = TRUE, points = TRUE, cex.points = 3, col = "darkblue") # Improved network graph netgraph(net, seq = "optimal", # Optimal node arrangement plastic = FALSE, thickness = "se.fixed", # Edge thickness by precision number.of.studies = TRUE, # Show number of studies col = "#4477AA", col.points = "#CC6677", cex.points = 4, labels = paste0(trts(net), "\n(n=", n.arms(net), ")")) ``` ## Frequentist NMA with netmeta ### Basic Network Meta-Analysis ```r library(netmeta) # Fit NMA (fixed and random effects) net <- netmeta( TE = TE, seTE = seTE, treat1 = treat1, treat2 = treat2, studlab = study, data = pairwise_data, sm = "MD", fixed = TRUE, random = TRUE, reference.group = "A" ) # Summary summary(net) # Results for specific comparison net$TE.fixed["B", "A"] # Fixed effect B vs A net$TE.random["B", "A"] # Random effects B vs A net$seTE.random["B", "A"] # SE for random effects ``` ### Forest Plot for NMA ```r library(netmeta) # Forest plot: all treatments vs reference forest(net, reference.group = "A", sortvar = TE, smlab = "Mean Difference vs A", drop.reference.group = TRUE, label.left = "Favors A", label.right = "Favors Treatment") # Forest plot with subgroup (by comparison type) forest(net, reference.group = "A", direct = TRUE) # Show direct evidence only ``` ### League Table ```r library(netmeta) # League table (all pairwise comparisons) league <- netleague( net, digits = 2, bracket = "(", separator = " to ", fixed = FALSE # Use random effects ) # Print league table print(league, common = FALSE) # As matrix league$random ``` ### Treatment Rankings ```r library(netmeta) # P-scores (frequentist ranking) netrank(net, small.values = "good") # Rankogram set.seed(123) rank <- rankogram(net, nsim = 1000) plot(rank) # SUCRA-like plot plot(rank, cumulative = TRUE) ``` ## Bayesian NMA with gemtc ### Basic Bayesian NMA ```r library(gemtc) # Prepare data for gemtc (arm-level) network_data <- list( data.ab = data.frame( study = c("S1", "S1", "S2", "S2", "S3", "S3", "S3"), treatment = c("A", "B", "A", "C", "A", "B", "C"), responders = c(15, 22, 12, 18, 20, 28, 24), sampleSize = c(50, 52, 48, 49, 55, 58, 54) ) ) # Create network object network <- mtc.network(data.ab = network_data$data.ab) # Plot network plot(network) # Consistency model model <- mtc.model( network, type = "consistency", likelihood = "binom", link = "logit", linearModel = "random" ) # Run MCMC set.seed(123) result <- mtc.run( model, n.adapt = 5000, n.iter = 20000, thin = 1 ) summary(result) ``` ### Model Diagnostics ```r library(gemtc) library(coda) # Trace plots plot(result) # Gelman-Rubin diagnostic gelman.diag(result$samples) gelman.plot(result$samples) # Effective sample size effectiveSize(result$samples) # Autocorrelation autocorr.plot(result$samples) # Density plots densplot(result$samples) ``` ### Treatment Rankings (Bayesian) ```r library(gemtc) # Rank probabilities ranks <- rank.probability(result) print(ranks) # Plot rank probabilities plot(ranks) # SUCRA sucra <- sucra(ranks) print(sucra) # Cumulative ranking plot plot(ranks, beside = TRUE) ``` ## Bayesian NMA with multinma ### Using multinma Package ```r library(multinma) # Prepare data nma_data <- set_agd_arm( data = arm_data, study = study, trt = treatment, r = events, n = n ) # Network plot plot(nma_data) # Fit Bayesian NMA nma_fit <- nma( nma_data, trt_effects = "random", prior_intercept = normal(scale = 10), prior_trt = normal(scale = 10), prior_het = half_normal(scale = 1) ) # Summary summary(nma_fit) print(nma_fit, pars = "d") # Treatment effects relative_effects(nma_fit, all_contrasts = TRUE) ``` ### Population-Adjusted NMA ```r library(multinma) # With individual patient data (IPD) and aggregate data (AgD) # IPD data ipd_data <- set_ipd( data = ipd_df, study = study, trt = treatment, y = outcome ) # AgD data agd_data <- set_agd_arm( data = agd_df, study = study, trt = treatment, r = events, n = n ) # Combine networks combined_network <- combine_network(ipd_data, agd_data) # Fit with covariate adjustment nma_cov <- nma( combined_network, trt_effects = "random", regression = ~age + sex ) ``` ## Consistency Assessment ### Global Inconsistency Tests ```r library(netmeta) # Design-by-treatment interaction model decomp <- decomp.design(net) print(decomp) # Q statistics decomp$Q.decomp # Overall Q decomposition decomp$Q.het.design # Within-design heterogeneity decomp$Q.inc.detach # Between-design inconsistency # Net heat plot (visual inconsistency) netheat(net) ``` ### Local Inconsistency (Node-Splitting) ```r library(netmeta) # Node-splitting for all comparisons with direct evidence netsplit_result <- netsplit(net) print(netsplit_result) # Forest plot of node-splitting forest(netsplit_result) # Using gemtc for Bayesian node-splitting library(gemtc) # Node-split model nodesplit <- mtc.nodesplit(network, comparisons = NULL) # All comparisons # Run each comparison ns_results <- lapply(nodesplit, function(model) { mtc.run(model, n.adapt = 5000, n.iter = 20000) }) # Summary mtc.nodesplit.comparisons(nodesplit) ``` ### Inconsistency Model ```r library(gemtc) # Unrelated mean effects (inconsistency) model model_ume <- mtc.model( network, type = "ume", likelihood = "binom", link = "logit" ) result_ume <- mtc.run(model_ume, n.adapt = 5000, n.iter = 20000) # Compare DIC summary(result)$DIC # Consistency model summary(result_ume)$DIC # Inconsistency model # Model comparison mtc.deviance(result) ``` ## Heterogeneity Assessment ```r library(netmeta) # Heterogeneity statistics net$tau # Tau (between-study SD) net$tau2 # Tau-squared net$I2 # I-squared net$Q # Q statistic net$df.Q # Degrees of freedom net$pval.Q # P-value for Q # Prediction intervals net$lower.predict # Lower prediction interval net$upper.predict # Upper prediction interval ``` ## Network Meta-Regression ```r library(netmeta) # With study-level covariate net_reg <- netmeta( TE = TE, seTE = seTE, treat1 = treat1, treat2 = treat2, studlab = study, data = pairwise_data, sm = "MD" ) # Meta-regression using netmetareg (requires netmeta >= 2.0) # net_reg <- netmetareg(net, ~year) # Alternative: Use gemtc with covariates library(gemtc) # Add study-level covariate network_cov <- mtc.network( data.ab = network_data$data.ab, studies = data.frame( study = c("S1", "S2", "S3"), year = c(2010, 2015, 2020) ) ) model_reg <- mtc.model( network_cov, type = "regression", regressor = list(coefficient = "shared", variable = "year") ) result_reg <- mtc.run(model_reg, n.adapt = 5000, n.iter = 20000) summary(result_reg) ``` ## Subgroup and Sensitivity Analysis ```r library(netmeta) # Subgroup NMA by risk of bias net_low_rob <- netmeta( TE = TE[rob == "low"], seTE = seTE[rob == "low"], treat1 = treat1[rob == "low"], treat2 = treat2[rob == "low"], studlab = study[rob == "low"], sm = "MD" ) # Compare results comparison_table <- data.frame( Model = c("All studies", "Low RoB only"), Tau = c(net$tau, net_low_rob$tau), Effect_B_vs_A = c(net$TE.random["B", "A"], net_low_rob$TE.random["B", "A"]) ) ``` ## Reporting and Visualization ### PRISMA-NMA Flow Diagram ```r # Recommended reporting items for NMA # 1. Network geometry # 2. Assessment of transitivity # 3. Presentation of results (forest, league table) # 4. Ranking with uncertainty # 5. Assessment of inconsistency # 6. Assessment of heterogeneity
Voir sur GitHub
Ce SKILL.md est tres volumineux, SkillsMP affiche donc ici seulement la premiere section. Voir sur GitHub