R 语言 + 卒中 Meta 分析(续):机器学习 Meta 与结构方程 Meta 完整实现
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), # 研究IDmodel = 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), # 模型AUCauc\_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%CIml\_results <- data.frame(model = c("截距(参考)", "RF", "LSTM", "LR"),z = coef(meta\_ml),z\_se = sqrt(diag(vcov(meta\_ml)))) %>%mutate(\# 计算Fisher-Z的95%CIz\_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)\# 输出亚组AUCcat("亚组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-X1stroke\_sem\$r\_X1X2\[i], 1, # X1-X2, X2-X2stroke\_sem\$r\_X1M\[i], stroke\_sem\$r\_X2M\[i], 1, # X1-M, X2-M, M-Mstroke\_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\*MM \~ 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)中获取。