DNA 甲基化与基因表达关联¶
一句话说明¶
DNA 甲基化就像基因的"静音开关"——启动子区域甲基化通常让基因沉默,但基因体甲基化反而与活跃表达相关,分析两者的关联是表观遗传研究的核心问题。
核心知识点¶
要点1:甲基化对表达的经典调控¶
- 启动子甲基化 → 基因沉默(最经典的规律)
- 甲基化阻止转录因子结合
- 招募 MeCP2 等甲基化结合蛋白 → 招募 HDAC → 染色质关闭
- 基因体甲基化 → 基因活跃(看似矛盾的规律)
- 可能防止基因内部的假启动子激活
- 与转录延伸效率相关
- 白话类比:启动子是"门口",甲基化等于上锁;基因体是"走廊",甲基化是铺好路让人走得顺畅
要点2:不同基因组区域的甲基化意义¶
| 区域 | 高甲基化 | 低甲基化 |
|---|---|---|
| CpG 岛启动子 | 基因沉默 | 基因可表达 |
| CpG 岛岸(shore) | 组织特异性调控 | — |
| 增强子 | 增强子失活 | 增强子活跃 |
| 基因体 | 活跃转录 | 低表达 |
| 重复元件 | 转座子沉默 | 基因组不稳定 |
要点3:整合分析方法¶
- 位点级关联:每个 CpG 与最近基因的表达做相关性分析
- 区域级关联:用差异甲基化区域(DMR)关联差异表达基因(DEG)
- 因果推断:用 Mendelian randomization 等方法推断甲基化是否驱动表达变化
- 调控网络:结合 ATAC-seq、组蛋白修饰等多层数据建立调控网络
实战代码¶
# ===== R: DNA 甲基化与基因表达关联分析 =====
library(methylKit)
library(DESeq2)
library(GenomicRanges)
# --- 1. 差异甲基化分析 ---
# 读取甲基化数据(Bismark 输出)
methyl_data <- methRead(
list("ctrl1.cov", "ctrl2.cov", "treat1.cov", "treat2.cov"),
sample.id = list("C1", "C2", "T1", "T2"),
treatment = c(0, 0, 1, 1),
assembly = "hg38", context = "CpG", mincov = 10)
# 合并 + 差异分析
meth_united <- unite(methyl_data)
diff_meth <- calculateDiffMeth(meth_united)
# 获取差异甲基化位点(差异>25%,q<0.01)
dmcs <- getMethylDiff(diff_meth, difference = 25, qvalue = 0.01)
# --- 2. 差异表达分析 ---
# RNA-seq 计数矩阵
rna_counts <- read.csv("gene_counts.csv", row.names = 1)
col_data <- data.frame(
condition = c("ctrl", "ctrl", "treat", "treat"),
row.names = colnames(rna_counts))
dds <- DESeqDataSetFromMatrix(rna_counts, col_data, ~condition)
dds <- DESeq(dds)
degs <- results(dds, contrast = c("condition", "treat", "ctrl"))
# 显著差异基因
sig_degs <- subset(degs, padj < 0.05 & abs(log2FoldChange) > 1)
# --- 3. 启动子甲基化与基因表达关联 ---
library(TxDb.Hsapiens.UCSC.hg38.knownGene)
library(org.Hs.eg.db)
# 获取启动子区域(TSS ±2kb)
txdb <- TxDb.Hsapiens.UCSC.hg38.knownGene
promoters_gr <- promoters(txdb, upstream = 2000, downstream = 200)
# 将差异甲基化位点注释到启动子
dmcs_gr <- GRanges(seqnames = dmcs$chr,
ranges = IRanges(start = dmcs$start, end = dmcs$end))
# 找启动子内的差异甲基化位点
overlaps <- findOverlaps(dmcs_gr, promoters_gr)
promoter_dmcs <- dmcs[queryHits(overlaps), ] # 位于启动子内的 DMC
# --- 4. 关联分析:甲基化 vs 表达 ---
# 期望:启动子高甲基化 → 基因低表达(负相关)
# 将 DMC 注释到最近基因
library(ChIPpeakAnno)
anno <- annotatePeakInBatch(dmcs_gr,
AnnotationData = TSS.human.GRCh38,
output = "nearestStart")
# 提取基因名和甲基化变化方向
anno_df <- as.data.frame(anno)
# 合并甲基化变化和表达变化
merged <- merge(
data.frame(gene = anno_df$feature, meth_diff = dmcs$meth.diff),
data.frame(gene = rownames(sig_degs),
expr_fc = sig_degs$log2FoldChange),
by = "gene")
# 相关性分析
cor_test <- cor.test(merged$meth_diff, merged$expr_fc,
method = "spearman")
cat("甲基化变化 vs 表达变化相关系数:",
round(cor_test$estimate, 3), "\n")
cat("p 值:", cor_test$p.value, "\n")
# 启动子甲基化通常与表达负相关(r < 0)
# 可视化
library(ggplot2)
ggplot(merged, aes(x = meth_diff, y = expr_fc)) +
geom_point(alpha = 0.5) + # 散点
geom_smooth(method = "lm", color = "red") + # 拟合线
geom_hline(yintercept = 0, linetype = "dashed") +
geom_vline(xintercept = 0, linetype = "dashed") +
labs(x = "启动子甲基化变化(%)",
y = "基因表达变化(log2FC)",
title = "甲基化-表达负相关") +
theme_minimal()
面试常问点¶
★ 启动子甲基化一定导致基因沉默吗?¶
参考答案:大部分情况是的,但不是绝对的。首先,不同密度的 CpG 岛行为不同——高密度 CpG 岛启动子的甲基化确实与沉默强相关,但低 CpG 密度启动子的关系不那么明确。其次,有些基因的表达由远端增强子调控,启动子甲基化的影响被增强子信号覆盖。第三,基因体的甲基化反而与活跃表达正相关。所以分析时要区分基因组区域。
★ 怎么证明甲基化变化是基因沉默的原因而非结果?¶
参考答案:三种策略——第一,时间序列分析,如果甲基化变化先于表达变化,说明可能是因果关系;第二,用去甲基化药物(如 5-azacytidine)处理,如果基因重新激活,说明甲基化确实抑制了表达;第三,用 dCas9-DNMT3A 等工具在目标位点定向引入甲基化,观察基因是否沉默。
速查卡片¶
| 问题 | 一句话答案 |
|---|---|
| 启动子甲基化 | 通常与基因沉默相关 |
| 基因体甲基化 | 与活跃转录正相关 |
| 增强子甲基化 | 增强子失活 |
| 关联分析工具 | methylKit + DESeq2 + ChIPpeakAnno |
| 经典负相关区域 | CpG 岛启动子(TSS ±2kb) |
| 验证因果关系的方法 | 去甲基化药物、dCas9-DNMT3A 定向编辑 |
| CpG 岛岸(shore)特点 | 组织特异性甲基化差异区 |