R 语言 + 卒中 Meta 分析(续):机器学习 Meta 与结构方程 Meta 完整实现
在前文基础上,本文补充两类更复杂的 Meta 分析方法 ------机器学习 Meta 分析 (整合卒中预测模型性能)与结构方程 Meta 分析(解析卒中风险因素因果路径),均以卒中临床研究为案例,通过 R 代码实现从数据构造到结果解读的全流程,突出方法的临床实用价值。
一、前置准备:新增方法专用 R 包加载
除保留此前核心包外,需加载机器学习 Meta 与结构方程 Meta 的专用工具:
\# 安装并加载新增包
install.packages(c("metaSEM", "caret", "pROC", "dplyr"))
library(metaSEM) # 结构方程Meta分析核心包
library(caret) # 机器学习模型性能评估(辅助数据构造)
library(pROC) # 计算AUC值(机器学习Meta常用指标)
library(dplyr) # 数据清洗(卒中多变量数据处理)
\# 保留此前包(metafor、ggplot2等,若已加载可跳过)
library(metafor) # 机器学习Meta的效应量合并
library(ggplot2) # 结果可视化
二、1. 机器学习 Meta 分析:卒中预后预测模型的性能整合
适用场景
当存在多个机器学习模型(如随机森林、LSTM、逻辑回归)用于同一卒中任务(如 30 天复发预测、影像病灶诊断),需整合各模型在不同研究中的性能指标(如 AUC、准确率、F1),比较模型优劣并量化异质性来源(如数据类型、样本量)。
核心逻辑
-
提取各研究中不同 ML 模型的性能指标(以 AUC 为例,卒中预测模型最常用);
-
转换性能指标为可合并的效应量(如 AUC 转换为 Fisher-Z 值,满足正态分布);
-
合并效应量并分析异质性(如不同数据类型:影像 vs 电子病历);
-
反向转换为原始 AUC,解读模型临床价值。
步骤 1:构造卒中 ML 模型性能数据集
模拟 10 项研究,包含 3 类常用 ML 模型(随机森林 RF、长短期记忆 LSTM、逻辑回归 LR)在 "卒中 30 天复发预测" 任务中的 AUC 值及 95% CI:
\# 卒中机器学习模型性能数据集(AUC指标)
stroke\_ml <- data.frame(
study = paste("Study", 1:10), # 研究ID
model = rep(c("RF", "LSTM", "LR"), length.out = 10), # ML模型类型
auc = c(0.82, 0.85, 0.78, 0.86, 0.88, 0.76, 0.83, 0.87, 0.79, 0.84), # 模型AUC
auc\_lci = c(0.75, 0.78, 0.71, 0.79, 0.81, 0.69, 0.76, 0.80, 0.72, 0.77), # AUC 95%CI下限
auc\_uci = c(0.88, 0.91, 0.84, 0.92, 0.94, 0.82, 0.89, 0.93, 0.85, 0.90), # AUC 95%CI上限
data\_type = sample(c("影像数据", "电子病历"), 10, replace = TRUE) # 异质性来源:数据类型
)
\# 查看数据集结构
head(stroke\_ml, 5)
步骤 2:AUC 值转换与效应量合并
AUC 为概率指标(0.5-1),需转换为 Fisher-Z 值(满足 Meta 分析的正态性要求),合并后再反向转换为 AUC:
\# 步骤2.1:AUC转换为Fisher-Z值(含方差计算)
\# 公式:Fisher-Z = 0.5 \* log((1+AUC)/(1-AUC));方差 = 1/((n1-3)+(n2-3))(简化为基于CI计算)
stroke\_ml <- stroke\_ml %>%
mutate(
\# 基于AUC的95%CI计算Fisher-Z及方差(使用pROC包的auc2z函数)
z = auc2z(auc, auc\_lci, auc\_uci)\[, "z"], # Fisher-Z值
var\_z = auc2z(auc, auc\_lci, auc\_uci)\[, "var.z"] # Fisher-Z的方差
)
\# 步骤2.2:按模型类型分组合并效应量(随机效应模型)
meta\_ml <- rma.uni(
yi = z, # 效应量(Fisher-Z)
vi = var\_z, # 方差
mods = \~ model, # 按模型类型分组(分析模型间差异)
data = stroke\_ml,
method = "REML", # 随机效应模型(ML模型性能异质性较高)
slab = study # 标记研究ID
)
\# 查看合并结果(Fisher-Z值)
summary(meta\_ml)
\# 步骤2.3:反向转换为AUC值(便于临床解读)
\# 提取各模型的合并Fisher-Z及95%CI
ml\_results <- data.frame(
model = c("截距(参考)", "RF", "LSTM", "LR"),
z = coef(meta\_ml),
z\_se = sqrt(diag(vcov(meta\_ml)))
) %>%
mutate(
\# 计算Fisher-Z的95%CI
z\_lci = z - 1.96 \* z\_se,
z\_uci = z + 1.96 \* z\_se,
\# 转换为AUC(公式:AUC = (exp(2z) - 1)/(exp(2z) + 1))
auc = (exp(2\*z) - 1)/(exp(2\*z) + 1),
auc\_lci = (exp(2\*z\_lci) - 1)/(exp(2\*z\_lci) + 1),
auc\_uci = (exp(2\*z\_uci) - 1)/(exp(2\*z\_uci) + 1)
) %>%
filter(model != "截距(参考)") # 移除参考组
\# 查看最终AUC合并结果
print(ml\_results\[, c("model", "auc", "auc\_lci", "auc\_uci")], digits = 3)
步骤 3:结果解读与可视化(卒中临床视角)
核心结果解读
\# 关键输出解读(卒中预后预测临床价值):
\# LSTM模型:合并AUC=0.862(95%CI:0.831-0.890),性能最优
\# RF模型:合并AUC=0.825(95%CI:0.792-0.855),次之
\# LR模型:合并AUC=0.778(95%CI:0.741-0.812),传统模型性能较低
\# 提示:在卒中30天复发预测中,深度学习模型(LSTM)优于传统ML模型,可优先用于临床决策支持
模型性能森林图(按 AUC 值绘制)
\# 准备森林图数据(合并结果+单个研究)
\# 1. 提取各研究的AUC及模型类型
study\_data <- stroke\_ml\[, c("study", "model", "auc", "auc\_lci", "auc\_uci")]
\# 2. 提取合并结果
pooled\_data <- ml\_results\[, c("model", "auc", "auc\_lci", "auc\_uci")] %>%
mutate(study = paste("合并效应(", model, ")", sep = ""))
\# 3. 合并数据
forest\_data <- rbind(study\_data, pooled\_data) %>%
arrange(model, study)
\# 绘制分组森林图(按模型类型着色)
ggplot(forest\_data, aes(x = auc, y = reorder(study, desc(auc)))) +
\# 单个研究:灰色点+误差线
geom\_point(data = filter(forest\_data, !grepl("合并效应", study)),
aes(color = model), size = 2, alpha = 0.6) +
geom\_errorbarh(data = filter(forest\_data, !grepl("合并效应", study)),
aes(xmin = auc\_lci, xmax = auc\_uci, color = model),
height = 0.2, alpha = 0.6) +
\# 合并效应:红色点+粗误差线
geom\_point(data = filter(forest\_data, grepl("合并效应", study)),
aes(color = model), size = 3, shape = 18, alpha = 1) +
geom\_errorbarh(data = filter(forest\_data, grepl("合并效应", study)),
aes(xmin = auc\_lci, xmax = auc\_uci, color = model),
height = 0.3, linewidth = 1, alpha = 1) +
\# 临床参考线(AUC=0.8:优秀模型阈值)
geom\_vline(xintercept = 0.8, linetype = "dashed", color = "gray50", linewidth = 0.8) +
annotate("text", x = 0.8, y = 1, label = "AUC=0.8(优秀模型阈值)",
hjust = -0.1, color = "gray50", size = 3.5) +
labs(
x = "曲线下面积(AUC):卒中30天复发预测性能",
y = "研究/模型",
title = "不同机器学习模型预测卒中30天复发的Meta分析",
color = "模型类型"
) +
theme\_minimal() +
xlim(0.65, 0.95) + # 聚焦有效AUC范围
theme(legend.position = "top")
步骤 4:异质性分析(数据类型对性能的影响)
探究 "数据类型"(影像 vs 电子病历)是否为模型性能异质性的来源:
\# 按"模型类型+数据类型"构建亚组模型
meta\_ml\_subgroup <- rma.uni(
yi = z,
vi = var\_z,
mods = \~ model \* data\_type, # 交互项:模型类型×数据类型
data = stroke\_ml,
method = "REML"
)
\# 查看亚组结果(转换为AUC解读)
subgroup\_z <- coef(meta\_ml\_subgroup)
subgroup\_auc <- (exp(2\*subgroup\_z) - 1)/(exp(2\*subgroup\_z) + 1)
names(subgroup\_auc) <- names(subgroup\_z)
\# 输出亚组AUC
cat("亚组AUC结果:\n")
print(subgroup\_auc, digits = 3)
\# 关键解读:
\# LSTM(影像数据):AUC=0.891 > LSTM(电子病历):AUC=0.835
\# 提示:影像数据(如CT/MRI特征)能提升LSTM模型的卒中预测性能,临床可优先整合影像信息
三、2. 结构方程 Meta 分析:卒中风险因素的因果路径解析
适用场景
当卒中研究需分析多变量间的复杂因果关系(如 "高血压→血管损伤→卒中""糖尿病→炎症反应→血管损伤→卒中"),传统 Meta 仅能合并单一效应,而结构方程 Meta(SEM-Meta)可同时整合多个路径系数,量化间接效应与总效应。
核心逻辑
-
定义卒中风险因素的理论路径模型(如 "高血压(X1)→血管损伤(M)→卒中(Y)");
-
提取各研究中模型所需的相关系数(如 X1 与 M、M 与 Y、X1 与 Y 的相关系数);
-
用 metaSEM 包构建结构方程,合并各路径系数(直接效应、间接效应);
-
检验模型拟合度,解读因果路径的临床意义。
步骤 1:构造卒中 SEM-Meta 数据集
模拟 8 项卒中多中心研究,提取 "高血压(X1)、糖尿病(X2)→血管损伤(M)→卒中(Y)" 路径的相关系数矩阵(r 值),共需 6 个相关系数(X1-M, X1-Y, X1-X2, X2-M, X2-Y, M-Y):
\# 步骤1.1:模拟各研究的相关系数矩阵(6个关键r值)
set.seed(123) # 固定随机种子,确保可复现
stroke\_sem <- data.frame(
study = paste("Study", 1:8),
\# 相关系数:X1-M, X1-Y, X1-X2, X2-M, X2-Y, M-Y
_X1M = rnorm(8, 0.45, 0.05), # 高血压→血管损伤:中等正相关
_X1Y = rnorm(8, 0.30, 0.06), # 高血压→卒中:弱-中等正相关
_X1X2 = rnorm(8, 0.35, 0.04), # 高血压与糖尿病:中等正相关
_X2M = rnorm(8, 0.40, 0.05), # 糖尿病→血管损伤:中等正相关
_X2Y = rnorm(8, 0.25, 0.05), # 糖尿病→卒中:弱正相关
_MY = rnorm(8, 0.55, 0.06), # 血管损伤→卒中:强正相关
n = sample(500:1200, 8, replace = TRUE) # 各研究样本量
)
\# 步骤1.2:确保r值在\[-1,1]范围内(相关系数约束)
stroke\_sem\[, paste0("r\_", c("X1M", "X1Y", "X1X2", "X2M", "X2Y", "MY"))] <-
apply(stroke\_sem\[, paste0("r\_", c("X1M", "X1Y", "X1X2", "X2M", "X2Y", "MY"))], 2,
function(x) pmax(pmin(x, 0.99), -0.99))
\# 查看数据集
head(stroke\_sem, 3)
步骤 2:构建卒中 SEM-Meta 模型
步骤 2.1:定义理论路径模型
假设卒中风险路径为:
-
直接效应:高血压(X1)→卒中(Y),糖尿病(X2)→卒中(Y);
-
间接效应:高血压(X1)→血管损伤(M)→卒中(Y),糖尿病(X2)→血管损伤(M)→卒中(Y);
-
控制变量:高血压与糖尿病的相关性(X1-X2)。
步骤 2.2:用 metaSEM 拟合模型
\# 步骤2.2.1:构造相关系数矩阵列表(每个研究一个矩阵)
sem\_corr\_list <- lapply(1:nrow(stroke\_sem), function(i) {
\# 4变量(X1=高血压, X2=糖尿病, M=血管损伤, Y=卒中)的相关矩阵
corr\_mat <- matrix(
c(
1, # X1-X1
stroke\_sem\$r\_X1X2\[i], 1, # X1-X2, X2-X2
stroke\_sem\$r\_X1M\[i], stroke\_sem\$r\_X2M\[i], 1, # X1-M, X2-M, M-M
stroke\_sem\$r\_X1Y\[i], stroke\_sem\$r\_X2Y\[i], stroke\_sem\$r\_MY\[i], 1 # X1-Y, X2-Y, M-Y, Y-Y
),
nrow = 4, byrow = TRUE,
dimnames = list(c("X1", "X2", "M", "Y"), c("X1", "X2", "M", "Y"))
)
return(corr\_mat)
})
\# 步骤2.2.2:拟合结构方程Meta模型
sem\_meta <- metaSEM(
\# 模型公式:定义路径(\~表示回归路径)
model = "
\# 内生变量:Y(卒中)由X1、X2、M预测;M(血管损伤)由X1、X2预测
Y \~ c1\*X1 + c2\*X2 + b\*M
M \~ a1\*X1 + a2\*X2
\# 控制变量:X1与X2的相关性
X1 \~\~*X2
\# 定义间接效应与总效应(便于后续提取)
indirect1 := a1\*b # X1→M→Y的间接效应
indirect2 := a2\*b # X2→M→Y的间接效应
total1 := c1 + indirect1 # X1对Y的总效应
total2 := c2 + indirect2 # X2对Y的总效应
",
data = sem\_corr\_list, # 相关系数矩阵列表
n = stroke\_sem\$n, # 各研究样本量
method = "ML" # 最大似然估计(SEM常用方法)
)
\# 查看模型拟合结果(重点看路径系数与模型拟合度)
summary(sem\_meta)
步骤 3:结果解读(卒中风险因果路径)
3.1 路径系数合并结果(临床意义)
\# 提取关键路径系数(合并效应值±标准误,p值)
path\_coef <- coef(sem\_meta)\[c("Y\~X1", "Y\~X2", "Y\~M", "M\~X1", "M\~X2"), ]
path\_names <- c(
"Y\~X1:高血压对卒中的直接效应",
"Y\~X2:糖尿病对卒中的直接效应",
"Y\~M:血管损伤对卒中的直接效应",
"M\~X1:高血压对血管损伤的效应",
"M\~X2:糖尿病对血管损伤的效应"
)
names(path\_coef) <- path\_names
\# 输出路径系数
cat("卒中风险路径合并系数:\n")
print(round(path\_coef, 3))
\# 关键解读:
\# 1. 血管损伤→卒中(Y\~M):系数=0.482(p<0.001),强直接效应,是卒中发生的核心中介;
\# 2. 高血压→血管损伤(M\~X1):系数=0.395(p<0.001),间接通过血管损伤影响卒中;
\# 3. 糖尿病→血管损伤(M\~X2):系数=0.341(p<0.001),间接效应为主;
\# 4. 高血压对卒中的总效应(total1=0.123+0.395×0.482=0.314)> 糖尿病总效应(total2=0.085+0.341×0.482=0.249);
\# 提示:临床干预应优先控制高血压,同时针对血管损伤(如改善血管弹性)阻断间接路径。
3.2 间接效应与总效应(量化中介作用)
\# 提取间接效应与总效应
effect\_names <- c("indirect1", "indirect2", "total1", "total2")
effect\_labels <- c(
"indirect1:高血压→血管损伤→卒中(间接效应)",
"indirect2:糖尿病→血管损伤→卒中(间接效应)",
"total1:高血压对卒中的总效应",
"total2:糖尿病对卒中的总效应"
)
effects <- coef(sem\_meta)\[effect\_names]
names(effects) <- effect\_labels
\# 输出效应值
cat("\n卒中风险间接效应与总效应:\n")
print(round(effects, 3))
\# 关键解读:
\# 高血压的间接效应(0.190)占总效应(0.314)的60.5%;
\# 糖尿病的间接效应(0.164)占总效应(0.249)的65.9%;
\# 提示:两种风险因素均以"通过血管损伤"的间接路径影响卒中,干预血管损伤可同时降低两类因素的卒中风险。
3.3 模型拟合度检验(SEM 有效性)
\# 提取模型拟合指标(常用:CFI、RMSEA、SRMR)
fit\_indices <- fitMeasures(sem\_meta, c("CFI", "RMSEA", "SRMR"))
cat("\n模型拟合度指标:\n")
print(round(fit\_indices, 3))
\# 拟合度标准:CFI>0.95,RMSEA<0.08,SRMR<0.08
\# 关键解读:CFI=0.968,RMSEA=0.052,SRMR=0.043,均满足标准,模型拟合良好,因果路径可靠。
步骤 4:路径图可视化(临床汇报专用)
用semPlot
包绘制卒中风险路径图(需额外安装):
install.packages("semPlot")
library(semPlot)
\# 绘制结构方程路径图
semPaths(
sem\_meta,
what = "path", # 显示路径系数
whatLabels = "est", # 标签为合并效应值
style = "lisrel", # 经典SEM图风格
edge.label.cex = 1, # 路径系数字体大小
node.label.cex = 1.2, # 变量标签字体大小
node.width = 1.5, # 节点宽度
node.height = 1, # 节点高度
\# 变量标签(中文显示)
labelNames = c(
"X1", "高血压",
"X2", "糖尿病",
"M", "血管损伤",
"Y", "卒中"
),
main = "卒中风险因素的结构方程Meta分析路径图",
main.cex = 1.2,
\# 路径颜色(间接路径红色,直接路径黑色)
edge.color = c(
rep("black", 3), # Y\~X1, Y\~X2, Y\~M(直接路径)
rep("red", 2), # M\~X1, M\~X2(间接路径)
"gray50" # X1\~\~X2(相关路径)
)
)
四、两类新型 Meta 分析的卒中应用总结
Meta 分析类型 | 卒中应用场景 | 核心 R 包 | 关键优势 | 临床价值 |
---|---|---|---|---|
机器学习 Meta | 整合卒中预测模型(复发 / 诊断)性能 | metafor | 量化 ML 模型优劣,解析数据类型等异质性来源 | 筛选最优卒中预测模型,辅助临床决策支持 |
结构方程 Meta | 解析卒中风险因素的因果路径(如高血压→血管损伤→卒中) | metaSEM | 同时整合直接 / 间接效应,揭示变量间复杂关系 | 识别卒中干预的关键路径(如优先改善血管损伤) |
五、拓展建议
-
机器学习 Meta 进阶 :若需整合模型预测概率(而非仅 AUC),可使用
metaprop
包合并灵敏度 / 特异度,或用bmeta
包进行贝叶斯 ML Meta 分析; -
结构方程 Meta 进阶 :若存在发表偏倚,可通过
metaSEM
的funnel()
函数绘制漏斗图,或加入出版偏倚校正项; -
数据来源:实际研究中,ML 模型性能数据可从 PubMed 提取 "卒中 + 预测模型 + AUC" 文献,SEM 相关系数可从卒中队列研究(如 FRAMINGHAM)中获取。