원클릭으로
network-meta-analysis
Network meta-analysis in R, including network setup, consistency, treatment rankings, and league tables.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Network meta-analysis in R, including network setup, consistency, treatment rankings, and league tables.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Bayesian meta-analysis models including fixed effects, random effects, and network meta-analysis with Stan and JAGS implementations.
Foundational knowledge for writing current PyMC models including syntax, distributions, sampling, and ArviZ diagnostics. Use when creating or reviewing PyMC models.
Foundational knowledge for writing modern Stan models including program structure, type system, distributions, and best practices. Use when creating or reviewing Stan models.
Group sequential design methods for interim analyses, alpha spending, and futility stopping. Use when designing trials with interim looks or implementing spending functions.
Core Mediana package functions for Clinical Scenario Evaluation (CSE). Use when designing data models, analysis models, evaluation models, and running comprehensive trial simulations.
Core simtrial package functions for time-to-event clinical trial simulation. Use when generating survival data, performing weighted logrank tests, or running TTE simulations.
| name | network-meta-analysis |
| description | Network meta-analysis in R, including network setup, consistency, treatment rankings, and league tables. |
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.
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)
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)
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), ")"))
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
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
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
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)
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)
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)
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)
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)
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
)
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)
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)
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)
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
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)
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"])
)
# 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
library(netmeta)
# Funnel plot for NMA
funnel(net,
order = c("A", "B", "C", "D"),
pooled = "random",
pch = 1:4,
legend = TRUE)
# Create summary table for publication
create_nma_summary <- function(net, ref = "A") {
treatments <- net$trts[net$trts != ref]
summary_df <- data.frame(
Comparison = paste(treatments, "vs", ref),
Effect_Fixed = sapply(treatments, function(t) net$TE.fixed[t, ref]),
CI_Lower_Fixed = sapply(treatments, function(t) net$lower.fixed[t, ref]),
CI_Upper_Fixed = sapply(treatments, function(t) net$upper.fixed[t, ref]),
Effect_Random = sapply(treatments, function(t) net$TE.random[t, ref]),
CI_Lower_Random = sapply(treatments, function(t) net$lower.random[t, ref]),
CI_Upper_Random = sapply(treatments, function(t) net$upper.random[t, ref])
)
# Format
summary_df <- summary_df |>
mutate(
Fixed = paste0(round(Effect_Fixed, 2), " (",
round(CI_Lower_Fixed, 2), ", ",
round(CI_Upper_Fixed, 2), ")"),
Random = paste0(round(Effect_Random, 2), " (",
round(CI_Lower_Random, 2), ", ",
round(CI_Upper_Random, 2), ")")
) |>
select(Comparison, Fixed, Random)
return(summary_df)
}
| Package | Purpose |
|---|---|
| netmeta | Frequentist NMA (contrast-based) |
| gemtc | Bayesian NMA with JAGS |
| multinma | Bayesian NMA with Stan |
| bnma | Bayesian NMA |
| pcnetmeta | Patient-centered NMA |
| NMAoutlier | Outlier detection in NMA |
| nmathresh | Decision thresholds for NMA |