| 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
library(netmeta)
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)
)
net <- netmeta(
TE = TE,
seTE = seTE,
treat1 = treat1,
treat2 = treat2,
studlab = study,
data = pairwise_data,
sm = "MD",
reference.group = "A",
all.treatments = NULL
)
summary(net)
Arm-Level Data Format
library(netmeta)
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)
)
library(meta)
pw <- pairwise(
treat = treatment,
event = events,
n = n,
studlab = study,
data = arm_data,
sm = "OR"
)
net_from_arm <- netmeta(pw)
Network Visualization
library(netmeta)
netgraph(net,
plastic = FALSE,
thickness = "number.of.studies",
multiarm = TRUE,
points = TRUE,
cex.points = 3,
col = "darkblue")
netgraph(net,
seq = "optimal",
plastic = FALSE,
thickness = "se.fixed",
number.of.studies = TRUE,
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
library(netmeta)
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(net)
net$TE.fixed["B", "A"]
net$TE.random["B", "A"]
net$seTE.random["B", "A"]
Forest Plot for NMA
library(netmeta)
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(net,
reference.group = "A",
direct = TRUE)
League Table
library(netmeta)
league <- netleague(
net,
digits = 2,
bracket = "(",
separator = " to ",
fixed = FALSE
)
print(league, common = FALSE)
league$random
Treatment Rankings
library(netmeta)
netrank(net, small.values = "good")
set.seed(123)
rank <- rankogram(net, nsim = 1000)
plot(rank)
plot(rank, cumulative = TRUE)
Bayesian NMA with gemtc
Basic Bayesian NMA
library(gemtc)
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)
)
)
network <- mtc.network(data.ab = network_data$data.ab)
plot(network)
model <- mtc.model(
network,
type = "consistency",
likelihood = "binom",
link = "logit",
linearModel = "random"
)
set.seed(123)
result <- mtc.run(
model,
n.adapt = 5000,
n.iter = 20000,
thin = 1
)
summary(result)
Model Diagnostics
library(gemtc)
library(coda)
plot(result)
gelman.diag(result$samples)
gelman.plot(result$samples)
effectiveSize(result$samples)
autocorr.plot(result$samples)
densplot(result$samples)
Treatment Rankings (Bayesian)
library(gemtc)
ranks <- rank.probability(result)
print(ranks)
plot(ranks)
sucra <- sucra(ranks)
print(sucra)
plot(ranks, beside = TRUE)
Bayesian NMA with multinma
Using multinma Package
library(multinma)
nma_data <- set_agd_arm(
data = arm_data,
study = study,
trt = treatment,
r = events,
n = n
)
plot(nma_data)
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(nma_fit)
print(nma_fit, pars = "d")
relative_effects(nma_fit, all_contrasts = TRUE)
Population-Adjusted NMA
library(multinma)
ipd_data <- set_ipd(
data = ipd_df,
study = study,
trt = treatment,
y = outcome
)
agd_data <- set_agd_arm(
data = agd_df,
study = study,
trt = treatment,
r = events,
n = n
)
combined_network <- combine_network(ipd_data, agd_data)
nma_cov <- nma(
combined_network,
trt_effects = "random",
regression = ~age + sex
)
Consistency Assessment
Global Inconsistency Tests
library(netmeta)
decomp <- decomp.design(net)
print(decomp)
decomp$Q.decomp
decomp$Q.het.design
decomp$Q.inc.detach
netheat(net)
Local Inconsistency (Node-Splitting)
library(netmeta)
netsplit_result <- netsplit(net)
print(netsplit_result)
forest(netsplit_result)
library(gemtc)
nodesplit <- mtc.nodesplit(network, comparisons = NULL)
ns_results <- lapply(nodesplit, function(model) {
mtc.run(model, n.adapt = 5000, n.iter = 20000)
})
mtc.nodesplit.comparisons(nodesplit)
Inconsistency Model
library(gemtc)
model_ume <- mtc.model(
network,
type = "ume",
likelihood = "binom",
link = "logit"
)
result_ume <- mtc.run(model_ume, n.adapt = 5000, n.iter = 20000)
summary(result)$DIC
summary(result_ume)$DIC
mtc.deviance(result)
Heterogeneity Assessment
library(netmeta)
net$tau
net$tau2
net$I2
net$Q
net$df.Q
net$pval.Q
net$lower.predict
net$upper.predict
Network Meta-Regression
library(netmeta)
net_reg <- netmeta(
TE = TE,
seTE = seTE,
treat1 = treat1,
treat2 = treat2,
studlab = study,
data = pairwise_data,
sm = "MD"
)
library(gemtc)
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
library(netmeta)
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"
)
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