孟德尔随机化(Mendelian Randomization, MR)作为一种利用基因数据推断因果关系的强大工具,在流行病学研究中应用广泛。本文将详细讲解MR的核心原理、完整分析流程,并附上关键代码实现,帮助你从零开始完成一次MR分析。
在这里插入图片描述

1. 什么是孟德尔随机化?

孟德尔随机化是一种基于全基因组关联研究(GWAS)数据,利用单核苷酸多态性(SNP)作为工具变量(IV) 来揭示暴露与结局间因果关系的方法。

其核心逻辑类似“自然随机对照试验”:

  • 随机对照试验(RCT):人为将研究对象随机分配到实验组/对照组
  • 孟德尔随机化:通过基因变异的自然随机分配(减数分裂时的随机分离),将携带特定等位基因的个体视为“暴露组”,非携带者视为“对照组”

2. 为什么选择MR?

相比队列研究等观察性研究,MR的优势在于:

  • 避免反向因果:基因在出生前已确定,暴露状态(由基因影响)早于结局发生
  • 减少混杂偏倚:基因与后天环境、行为等混杂因素通常无关
  • 低成本验证:可直接免费利用公开GWAS数据

MR的三大核心假设(必须满足!)

MR结果的可靠性完全依赖以下三个假设,需严格验证:

假设名称核心内容验证方法
关联性假设工具变量(SNP)与暴露因素显著相关计算p值(通常p<5e-8)、F统计量(建议F>10,避免弱工具变量偏倚)、R²
独立性假设SNP与结局之间不存在通过混杂因素的关联(SNP仅通过暴露影响结局)确保SNP与已知混杂因素无关联,通过敏感性分析验证
排他性假设SNP不直接影响结局,仅通过暴露间接影响计算SNP与结局的独立关联性(p>0.05),MR-Egger回归可弱化此假设要求

关键提示:若假设不成立,因果推断结果可能完全错误。例如,若某SNP既影响BMI(暴露),又直接影响心脏病(结局),则违反排他性假设,不能用于推断BMI与心脏病的因果关系。

MR分析完整流程与代码实现

1. 环境配置(R语言)

MR分析涉及到的R包可以一次性安装

MRCIEU/TwoSampleMR
VariantAnnotation
mrcieu/gwasglue
VariantAnnotation
mrcieu/gwasglue 
CMplot
MendelianRandomization
LDlinkR
ggplot2
ggfunnel
cowplot
plinkbinr
FastDownloader
FastTraitR
MRPRESSO
SNPlocs.Hsapiens.dbSNP155.GRCh37
SNPlocs.Hsapiens.dbSNP155.GRCh38
tidyverse
MungeSumstats
GenomicFiles
explodecomputer/plinkbinr
MRPRESSO
pedropark99/ggfunnel
xiechengyong123/friendly2MR
NightingaleHealth/ggforestplot
BSgenome.Hsapiens.1000genomes.hs37d5
BSgenome.Hsapiens.NCBI.GRCh38
glmnet
meta
psych

2. 数据来源

MR分析依赖GWAS汇总数据,常用公开数据库包括:

  • IEU汇总数据库(MRCIEU):全球最大的GWAS数据平台(https://gwas.mrcieu.ac.uk/)
  • 精神病学基因组联盟(PGC):专注精神疾病GWAS数据
  • 社会科学遗传学联盟(SSGAC):包含教育、收入等社会表型数据
  • UK Biobank:包含超50万样本的多表型数据
  • 自建数据:自己开展的GWAS分析结果

3. 暴露数据处理(关键步骤)

暴露数据即与“暴露因素”相关的GWAS数据,需筛选符合“关联性假设”的SNP。

3.1 从VCF文件获取暴露数据
# 读取VCF格式的GWAS数据
VCF_dat <- VariantAnnotation::readVcf('ieu-a-2.vcf.gz')
# 转换为TwoSampleMR所需格式
exp_dat <- gwasglue::gwasvcf_to_TwoSampleMR(vcf = VCF_dat)# 筛选符合关联性假设的SNP(p<5e-8)
exp_dat <- subset(exp_dat, pval.exposure < 5e-08)
3.2 处理连锁不平衡(LD)

SNP间的连锁不平衡会导致工具变量相关性过高,需通过“聚类”去除:

# 自定义本地LD聚类函数(避免调用云端API)
fix_ld_clump_local <- function (dat, tempfile, clump_kb, clump_r2, clump_p, bfile, plink_bin) {shell <- ifelse(Sys.info()["sysname"] == "Windows", "cmd", "sh")# 输出SNP和p值到临时文件write.table(data.frame(SNP = dat[["rsid"]], P = dat[["pval"]]),file = tempfile, row.names = F, col.names = T, quote = F)# 调用PLINK进行LD聚类fun2 <- paste0(shQuote(plink_bin, type = shell), " --bfile ",shQuote(bfile, type = shell), " --clump ", shQuote(tempfile,type = shell), " --clump-p1 ", clump_p, " --clump-r2 ",clump_r2, " --clump-kb ", clump_kb, " --out ", shQuote(tempfile,type = shell))print(fun2)system(fun2)# 读取聚类结果res <- read.table(paste(tempfile, ".clumped", sep = ""), header = T)unlink(paste(tempfile, "*", sep = ""))# 输出去LD后的SNPreturn(subset(dat, dat[["rsid"]] %in% res[["SNP"]]))}# 运行LD聚类(以欧洲人群为例)
fuck <- fix_ld_clump_local(dat = dplyr::tibble(rsid=exp_dat$SNP, pval=exp_dat$pval.exposure),tempfile = file.path(getwd(),'tmp.ld_clump.exp_dat'),clump_kb = 10000,  # 10kb内的SNP进行聚类clump_r2 = 0.001,  # 剔除r²>0.001的SNPclump_p = 1,plink_bin = 'path/to/plink',  # PLINK路径bfile = "1kg/EUR"  # 1000G欧洲人群参考面板
)# 提取去LD后的暴露数据
exp_dat_clumped <- exp_dat[exp_dat$SNP %in% fuck$rsid,]
saveRDS(file = 'ieu-a-2.exp_gwas', exp_dat_clumped)
3.3 从其他来源获取暴露数据
# 从GWAS目录获取(例如BMI数据)
df_gwas <- subset(MRInstruments::gwas_catalog,grepl("Speliotes", Author) & Phenotype == "Body mass index")exp_dat <- TwoSampleMR::format_data(df_gwas)# 从GTEx获取eQTL数据(例如特定基因在脂肪组织的表达)
df_gwas <- subset(MRInstruments::gtex_eqtl, gene_name == "IRAK1BP1" & tissue == "Adipose Subcutaneous")exp_dat <- TwoSampleMR::format_gtex_eqtl(df_gwas)# 从IEU数据库直接提取(通过ID)
exp_gwas <- TwoSampleMR::extract_instruments(outcomes = 'ieu-a-2')  # 'ieu-a-2'为某表型ID
3.4 评估工具变量强度(计算F统计量)

F统计量用于判断是否为“弱工具变量”(F<10提示可能存在偏倚):

MR_calc_r2_F <- function(beta, eaf, N, se){# 计算R²和F统计量r2 <- (2 * (beta^2) * eaf * (1 - eaf)) /(2 * (beta^2) * eaf * (1 - eaf) + 2 * N * eaf * (1 - eaf) * se^2)F <- r2 * (N - 2) / (1 - r2)print(paste("平均F值:", mean(F)))return(dplyr::tibble(r2=r2, F=F))
}# 计算并筛选F>10的SNPf_stats <- MR_calc_r2_F(beta = exp_dat_clumped$beta.exposure,  # 暴露的beta值(log(OR))eaf = exp_dat_clumped$eaf.exposure,    # 等位基因频率N = exp_dat_clumped$samplesize.exposure,  # 样本量se = exp_dat_clumped$se.exposure       # 标准误)exp_dat_final <- exp_dat_clumped[f_stats$F > 10, ]  # 保留强工具变量

4. 结局数据处理

结局数据即与“结局变量”相关的GWAS数据,需满足“排他性假设”。

4.1 从PGC数据库获取结局数据(以ADHD为例)

# 读取ADHD的GWAS汇总数据(meta分析结果)df_gwas =read.table(gzfile('ADHD2022_iPSYCH_deCODE_PGC.meta.gz'), header = T)# 仅保留与暴露SNP重叠的数据
df_gwas <- df_gwas[df_gwas$SNP %in% exp_gwas$SNP,]# 转换为TwoSampleMR格式
out_gwas <- data.frame(SNP = df_gwas$SNP,chr = as.character(df_gwas$CHR),pos = df_gwas$BP,beta.outcome = log(df_gwas$OR),  # 将OR转换为log(OR)se.outcome = df_gwas$SE,samplesize.outcome = df_gwas$Nca + df_gwas$Nco,  # 总样本量(病例+对照)pval.outcome = df_gwas$P,eaf.outcome = with(df_gwas, (FRQ_A_38691*Nca + FRQ_U_186843*Nco)/(Nca + Nco)),  # 计算整体等位基因频率effect_allele.outcome = df_gwas$A1,other_allele.outcome = df_gwas$A2,outcome = 'ADHD',id.outcome = 'ADHD2022_iPSYCH_deCODE_PGC'
)# 筛选符合排他性假设的SNP(p>0.05,与结局无直接关联)
out_gwas <- subset(out_gwas, pval.outcome > 0.05)
4.2 从其他来源获取结局数据

opengwas_jwt需要注册ieu并申请token后才可以从网站下载数据

# 从IEU数据库提取
out_gwas <- TwoSampleMR::extract_outcome_data(snps = exp_gwas$SNP, outcomes = 'ieu-a-7',opengwas_jwt = opengwas_jwt)  # 'ieu-a-7'为结局ID# 从UK Biobank提取
anxiety_outcome <- TwoSampleMR::extract_outcome_data(snps = exp_dat_clumped$SNP, outcomes = "ukb-b-11311")

5. 数据协调(Harmonization)

确保暴露和结局数据中SNP的等位基因方向一致(关键步骤,否则结果完全错误):

# 协调暴露和结局数据
dat <- TwoSampleMR::harmonise_data(exposure_dat = exp_gwas,  # 处理后的暴露数据outcome_dat = out_gwas    # 处理后的结局数据
)
# 查看协调结果(检查是否有方向冲突的SNP被剔除)
head(dat)

关键说明:协调过程会自动处理:

  • 等位基因方向不一致的SNP(如暴露中A为效应等位基因,结局中a为效应等位基因,会自动转换)
  • 回文SNP(如A/T和T/A,无法判断方向时会被剔除)
  • 完全不匹配的SNP(直接剔除)

6. 因果效应估计

使用多种方法计算暴露对结局的因果效应,结果一致更可信:

# 查看所有可用的MR方法
TwoSampleMR::mr_method_list()# 选择常用方法进行分析(IVW、Egger、加权中位数)
mr_regression <- TwoSampleMR::mr(dat,method_list = c('mr_ivw', 'mr_egger_regression', 'mr_weighted_median')
)
print(mr_regression)# 若结局为分类变量(如疾病),转换为OR值(方便解读)
mr_regression_or <- TwoSampleMR::generate_odds_ratios(mr_res = mr_regression)
print(mr_regression_or)# 绘制散点图(直观展示各SNP的效应及整体趋势)
pdf(file = 'MR散点图.pdf', width = 6, height = 6)
print(TwoSampleMR::mr_scatter_plot(mr_results = mr_regression, dat = dat))
dev.off()

7. 假设验证与敏感性分析

7.1 异质性检验(判断工具变量效应是否一致)
# IVW方法的Q统计量检验
heterogeneity_ivw <- TwoSampleMR::mr_heterogeneity(dat)
print(heterogeneity_ivw)  # Q_pval < 0.05提示存在异质性# MR-PRESSO检验(检测离群值导致的异质性)
heterogeneity_presso <- TwoSampleMR::run_mr_presso(dat, NbDistribution = 3000)  # 3000次模拟# 全局检验(是否存在异质性)
print(heterogeneity_presso[[1]]$`MR-PRESSO results`$`Global Test`$Pvalue)# 离群值检测(若存在,需剔除后重新分析)
print(heterogeneity_presso[[1]]$`MR-PRESSO results`$`Distortion Test`$`Outliers Indices`)
  • 若存在异质性:使用随机效应IVW模型,或剔除离群值后重新分析
  • 若无异质性:固定效应IVW模型更可靠
7.2 水平多效性检验(验证独立性假设)
# MR-Egger截距检验
pleiotropy_test <- TwoSampleMR::mr_pleiotropy_test(dat)
print(pleiotropy_test)
# 若p < 0.05:拒绝截距为0的假设,提示存在水平多效性(结果不可靠)
7.3 Leave-one-out分析(敏感性检验)
# 逐一剔除每个SNP后重新分析,判断结果是否依赖某个SNP
mr_loo <- TwoSampleMR::mr_leaveoneout(dat)# 绘制leave-one-out图
TwoSampleMR::mr_leaveoneout_plot(leaveoneout_results = mr_loo)
# 若剔除某SNP后结果显著变化(如效应值跨过0),提示结果不稳定
7.4 单SNP分析(查看个体工具变量效应)
# 每个SNP单独进行MR分析
mr_res_single <- TwoSampleMR::mr_singlesnp(dat)# 绘制漏斗图(判断是否存在小研究效应)
TwoSampleMR::mr_funnel_plot(mr_res_single)# 绘制森林图(展示每个SNP的效应)
TwoSampleMR::mr_forest_plot(mr_res_single)
7.5 方向性检验(判断因果方向)
TwoSampleMR::directionality_test(dat) # TRUE表示暴露→结局的方向更可能成立

8. 一键生成报告(可选)

# 生成Markdown格式的完整报告
TwoSampleMR::mr_report(dat, output_type = "md")

四、MR的局限性与注意事项

  1. 依赖GWAS数据质量:样本量过小、人群分层会导致结果偏倚
  2. 工具变量选择至关重要:弱工具变量(F<10)会导致效应估计偏差
  3. 无法完全避免多效性:即使通过检验,仍可能存在未识别的水平多效性
  4. 仅反映平均效应:无法推断个体水平的因果关系
  5. 数据重叠问题:暴露和结局数据若来自同一人群,需控制样本重叠比例(建议<10%)

参考

https://mrcieu.github.io/TwoSampleMR/articles/perform_mr.html
https://hexo.limour.top/Mendelian-Randomization

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/93952.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/93952.shtml
英文地址,请注明出处:http://en.pswp.cn/web/93952.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

记一次:postman请求下载文件的使用方法

前言&#xff1a;笔者的后端接口是swagger&#xff0c;遇到像文件导出下载的功能就实现不了。然后使用postman工具就可以了。注&#xff1a;postman工具使用send下拉选项中有请求下载&#xff0c;如图完美解决。后续有其它方法在补充。

快速搭建项目(若依)

RuoYi-Vue 是一个 Java EE 企业级快速开发平台&#xff0c;低代码的框架。 1.环境要求&#xff1a; 其中MySQL和Redis放在服务器上或者本机上。 2.代码搭建&#xff1a; 代码下载地址&#xff1a;https://gitee.com/y_project/RuoYi-Vue&#xff0c;在官方文档里面可下载若依…

iOS开发之UICollectionView为什么需要配合UICollectionViewFlowLayout使用

1. UICollectionView 的职责分离UICollectionView 本质上只是一个容器&#xff0c;用来展示一系列的 cell&#xff08;单元格&#xff09;。 它本身 不关心 cell 的摆放方式&#xff0c;只负责&#xff1a;Cell 的复用&#xff08;避免性能浪费&#xff09;Cell 的增删改查滚动…

一、部署LNMP

一、准备环境操作系统&#xff1a;CentOS 7.x&#xff08;最少 2 核 CPU 2GB 内存 20GB 磁盘&#xff09;网络&#xff1a;能访问公网&#xff08;用于下载包&#xff09;软件版本&#xff1a;Nginx 1.20MySQL 5.7/8.0PHP 7.4WordPress 6.x&#xff08;商城插件 WooCommerce&…

【时时三省】vectorCAST 便捷使用技巧

山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 目录 1,工程的共享 2,工程的关键文件保存 2,工作环境目录下,各个文件夹的作用 1,build 和 environment 的区别 2,vcm的作用 3,tst 文件的妙用 4,配置文件的妙用 5,复制测试环境 6,vectorCAST…

TOPSIS 优劣解距离法总结

TOPSIS 优劣解距离法总结 1. 基本思想 TOPSIS&#xff08;Technique for Order Preference by Similarity to Ideal Solution&#xff09;方法通过计算方案与正理想解&#xff08;最优值&#xff09;和负理想解&#xff08;最劣值&#xff09;的距离&#xff0c;来评价方案的优…

机器学习笔试题

人工智能与机器学习单选题&#xff08;50道&#xff09;1. 机器学习的核心目标是&#xff1a;A. 通过硬编码规则解决问题 B. 从数据中自动学习模式 C. 提高计算机硬件性能 D. 优化数据库查询速度2. 以下属于监督学习任务的是&#xff1a;A. 聚类分析 B. 图像分类 C. 异常检测 D…

CISP-PTE之路--10文

1.TCP/UDP 工作在 OSI 哪个层? 应用层 传输层 数据链路层 表示层 答案:传输层 解析:TCP(传输控制协议)和 UDP(用户数据报协议)是 OSI 模型中传输层的核心协议,负责端到端的数据传输管理,如可靠性(TCP)、实时性(UDP)等。 2.下列哪种设备可以隔离 ARP 广播帧? …

接口性能测试工具 - JMeter

1. 下载和运行JMeter 是由 Java 语言编写的, 因此 JMeter 的使用依赖于 Java 环境 - JRE.前往 oracle 官网下载 JMeter 压缩包.Mac 用户解压完成后, 在包内的 bin 目录下运行 sh jmeter:Windows 用户直接运行 bin 目录下的 jmeter.bat:即可进入 JMeter 主页面:1.1 添加环境变量…

Go语言实战案例-数据库事务处理

在实际业务中&#xff0c;很多操作需要保证 要么全部成功&#xff0c;要么全部失败&#xff0c;否则可能造成数据不一致。比如&#xff1a;• 用户转账&#xff08;A 账户扣款&#xff0c;B 账户加款&#xff09;• 下单支付&#xff08;生成订单、扣减库存、记录支付&#xff…

为何vivo做了头显,小米却选择AI眼镜

在押注下一代智能终端这件事上&#xff0c;手机厂商为何步调不一致&#xff1f;文&#xff5c;游勇编&#xff5c;周路平在手机销量和创新都陷入停滞的背景下&#xff0c;主流手机厂商正在探索下一代交互终端&#xff0c;试图寻找新的增长点。今年6月&#xff0c;小米发布了AI眼…

Day24 目录遍历、双向链表、栈

day24 目录遍历、双向链表、栈显示指定目录下的所有 .h 文件 功能描述 遍历指定目录&#xff08;递归进入子目录&#xff09;&#xff0c;查找所有以 .h 为后缀的头文件&#xff0c;将其完整路径&#xff08;路径 文件名&#xff09;存储到双向链表中&#xff0c;并正向或反向…

JupyterLab 安装(python3.10)

目录 一、环境 二、安装 三、启动Jupyterlab 四、通过chrome浏览器进行访问 五、打开Jupyter Notebook 六、pandas验证 JupyterLab 是一个基于 Web 的交互式开发环境&#xff0c;是经典 Jupyter Notebook 的下一代版本。它支持多种编程语言&#xff08;如 Python、R、Juli…

【neo4j】安装使用教程

一、安装 1.0 前置条件 安装配置好jdk17及以上 注意我使用的是neo4j 5.26.10版本&#xff0c;匹配java17刚好 Java Archive Downloads - Java SE 17.0.12 and earlier 无脑安装即可 配置以下环境变量 1.1 安装程序 Neo4j Deployment Center - Graph Database & Anal…

AECS(国标ECALL GB 45672-2025)

车载紧急呼叫功能作为车辆遇险时的响应机制&#xff0c;为司机和乘客的安全营救提供通信支持。为了能够降低通信延迟&#xff0c;提高响应速度&#xff0c;基于4G/5G的下一代紧急呼叫技术&#xff08;NG eCall&#xff09;将在欧盟于2027年起成为强制标准&#xff0c;中国也已经…

week3-[循环嵌套]好数

week3-[循环嵌套]好数 题目描述 如果一个正整数 xxx 只有最左边一位不是 000&#xff0c;其余都是 000&#xff0c;那么称其为好数。例如 400040004000 和 222 都是好数&#xff0c;但是 120120120 不是。 给定正整数 nnn&#xff0c;在 111 到 nnn 间有多少个数是好数&#xf…

智能制造加速器:某新能源车智慧工厂无线网络优化提升方案

随着工业4.0和智能制造的快速发展&#xff0c;传统制造工厂的网络架构正面临前所未有的挑战。为了满足柔性生产、实时数据驱动以及高可靠运营的需求&#xff0c;某新能源车智慧工厂启动了一项无线网络优化提升项目。本项目通过部署智能组网设备&#xff0c;构建高效、稳定、智能…

nginx-自制证书实现

nginx-自制证书实现一、 确认nginx是支持https功能的二、生成私钥三、 根据ca.key生成nginx web服务器使用的证书签名请求文件nginx.csr四、使用ca.key给nginx.csr进行签名&#xff0c;生成公钥证书nginx.crt五、将证书与域名绑定六、添加域名解析并访问一、 确认nginx是支持ht…

FreeRTOS,事件标注组创建,xEventGroupCreate、xEventGroupCreateStatic

1. xEventGroupCreate ()&#xff1a;动态创建&#xff08;临时借内存&#xff09; 作用&#xff1a; 向系统&#xff08;FreeRTOS 的堆内存&#xff09;“临时申请” 一块内存来存放事件组&#xff0c;不需要我们自己提前准备内存。 例子&#xff08;基于你的代码修改&#xf…

Linux网络socket套接字(上)

目录 前言 1.Socket编程准备 1.理解源IP地址和目的IP地址 2.认识端口号 3.socket源来 4.传输层的典型代表 5.网络字节序 6.socket编程接口 2.Socket编程UDP 1.服务端创建套接字 2.服务端绑定 3.运行服务器 4.客户端访问服务器 5.测试 6.补充参考内容 总结 前言…