跳转至

群体遗传学分析(选择信号 / 群体结构 / Fst / PCA / ADMIXTURE)


一句话概述

群体遗传学通过分析等位基因频率的时空分布来推断群体历史、自然选择和遗传结构,本教程覆盖PCA、ADMIXTURE群体结构分析、Fst分化检测和选择信号扫描的完整实战流程。


目录


1. 核心知识点

序号步骤工具目的输入输出关键参数
1数据准备与质控PLINK2/VCFtools过滤低质量变异和样本VCF/PLINK格式质控后数据集--maf 0.05 --geno 0.1
2LD修剪PLINK2去除连锁位点质控后数据独立SNP子集--indep-pairwise 50 10 0.1
3PCA分析PLINK2/smartpca可视化群体遗传结构LD修剪后数据PC坐标PC数目
4ADMIXTURE分析ADMIXTURE推断祖先成分比例LD修剪后PLINK格式Q矩阵(祖先比例)K值选择(CV error)
5系统发育树SNPhylo/RAxML群体间进化关系SNP数据Newick树文件bootstrap次数
6Fst群体分化VCFtools/PopGenome量化群体间遗传分化分群后VCFFst值(全基因组/窗口)窗口大小
7核苷酸多态性πVCFtools/PopGenome衡量群体内遗传多样性分群后VCFπ值(窗口)窗口大小/步长
8Tajima's DVCFtools检测偏离中性模型VCFD统计量(窗口)窗口大小
9选择性扫描检测rehh/selscan检测正选择信号VCF + 遗传图谱iHS/XP-EHH分数EHH衰减阈值
10群体历史推断SMC++/PSMC推断有效群体大小变化VCF/全基因组数据Ne~t曲线突变率/世代时间

2. 各步骤详解

步骤1:数据准备与质控

白话解释:群体遗传学分析对数据质量非常敏感。低质量的SNP(如高缺失率、偏离HWE)和样本(如近亲、混血个体)会扭曲群体结构分析结果。严格的质控是第一步。

技术细节

群体遗传学特有的质控考量: - MAF过滤:群体遗传学通常使用MAF≥5%(比GWAS更严格),因为稀有变异对PCA和ADMIXTURE的贡献有限且容易受到基因分型误差影响 - 缺失率:按群体分别检查,确保某一群体中的高缺失SNP不被保留 - HWE:不要对所有群体联合检验HWE(群体分层会导致偏离),应在每个群体内分别检验 - 亲缘关系:去除近亲后才能进行PCA和ADMIXTURE - LD filtering:对于PCA和ADMIXTURE,需要LD修剪后的独立位点

# 基本质控
plink2 --vcf all_populations.vcf.gz \
  --maf 0.05 \
  --geno 0.1 \
  --mind 0.1 \
  --hwe 1e-6 \
  --max-alleles 2 \
  --make-bed \
  --out popgen_qc

# 计算样本间亲缘关系
plink2 --bfile popgen_qc \
  --king-cutoff 0.0884 \
  --out king_results

# 去除近亲
plink2 --bfile popgen_qc \
  --remove king_results.king.cutoff.out.id \
  --make-bed \
  --out popgen_unrelated

echo "质控后SNP数: $(wc -l < popgen_unrelated.bim)"
echo "质控后样本数: $(wc -l < popgen_unrelated.fam)"

步骤2:LD修剪

白话解释:PCA和ADMIXTURE假设输入的SNP之间是相互独立的。如果不去除高LD的SNP,某些基因组区域(如MHC区域)会对结果产生过大的影响。LD修剪保留一组近似独立的SNP子集。

技术细节

群体遗传学的LD修剪参数通常比GWAS更严格: - r² < 0.1(比GWAS常用的0.2更严格) - 这确保了SNP之间的独立性,使PCA和ADMIXTURE结果更可靠

还需要排除长程LD区域: - MHC区域(人类chr6:25-35Mb) - 染色体倒位区域(如人类chr8倒位) - 这些区域的高LD会形成PCA上的"假结构"

对于ADMIXTURE,LD修剪的严格程度直接影响CV error的最小值和K值的选择。过于宽松的修剪会高估K值。

# 严格LD修剪(r²<0.1)
plink2 --bfile popgen_unrelated \
  --indep-pairwise 50 10 0.1 \
  --out ld_prune

# 排除长程LD区域
cat > long_range_ld_hg38.txt << 'EOF'
6 25000000 35000000 MHC
8 7000000 13000000 INV
EOF

plink2 --bfile popgen_unrelated \
  --extract ld_prune.prune.in \
  --exclude range long_range_ld_hg38.txt \
  --make-bed \
  --out popgen_pruned

echo "LD修剪后SNP数: $(wc -l < popgen_pruned.bim)"

步骤3:PCA分析

白话解释:PCA(主成分分析)将高维基因型数据投影到二维或三维空间中,让我们直观看到不同群体之间的遗传距离和聚类关系。相近的点代表遗传相似的个体。

技术细节

PCA在群体遗传学中的用途: - 识别遗传聚类(群体/亚群体) - 检测混血个体(位于两个群体之间) - 发现异常值(样本标签错误、种群混杂) - 为后续分析选择样本子集

PC的解读: - PC1通常反映最大的遗传分化方向 - 前2-3个PC往往能捕捉主要的群体结构 - 解释方差比例(eigenvalue)帮助判断群体结构的层次

注意事项: - 样本量不平衡会影响PCA:大群体的内部变异可能主导前几个PC - "projection PCA"可以将小样本量群体投影到大参考面板定义的PC空间中

# PLINK2 PCA
plink2 --bfile popgen_pruned \
  --pca 20 \
  --out pca_results

# smartPCA(更多统计选项)
# 准备par文件
cat > smartpca.par << 'EOF'
genotypename: popgen_pruned.bed
snpname: popgen_pruned.bim
indivname: popgen_pruned.fam
evecoutname: smartpca.evec
evaloutname: smartpca.eval
numoutevec: 20
numthreads: 16
EOF

smartpca -p smartpca.par
# R可视化PCA
library(ggplot2)
library(ggrepel)

# 读取PCA结果
pca <- read.table("pca_results.eigenvec", header=FALSE)
eigenval <- read.table("pca_results.eigenval", header=FALSE)

# 添加群体信息
pop_info <- read.table("population_labels.txt", header=TRUE)
pca_df <- merge(pca, pop_info, by.x="V2", by.y="IID")

# 计算方差解释比例
pct_var <- eigenval$V1 / sum(eigenval$V1) * 100

# 绘制PCA
ggplot(pca_df, aes(x=V3, y=V4, color=Population)) +
  geom_point(size=2, alpha=0.7) +
  labs(
    x = paste0("PC1 (", round(pct_var[1], 1), "%)"),
    y = paste0("PC2 (", round(pct_var[2], 1), "%)"),
    title = "Population Structure (PCA)"
  ) +
  theme_minimal(base_size=14) +
  scale_color_brewer(palette="Set2")

ggsave("pca_plot.pdf", width=9, height=7)

步骤4:ADMIXTURE分析

白话解释:ADMIXTURE估计每个个体基因组中来自不同祖先群体的比例。比如一个个体可能是60%祖先A + 30%祖先B + 10%祖先C。通过尝试不同的K值(假设的祖先群体数),找到最能解释数据的群体数目。

技术细节

ADMIXTURE使用最大似然方法估计: - Q矩阵:每个个体的祖先成分比例(N个体 × K个祖先) - F矩阵:每个祖先群体中每个SNP的等位基因频率

K值选择: - 对每个K值(如2-10)运行交叉验证(--cv) - 选择CV error最低的K值作为最优K - 但最优K不一定是唯一"正确"的K——不同K提供不同层次的群体结构信息

运行注意事项: - ADMIXTURE对初始值敏感,建议每个K运行多次(不同随机种子),选择最优结果 - 输入数据必须经过严格LD修剪 - 样本量不平衡会影响结果(过采样的群体可能被拆分为多个组分)

# 对K=2到K=10运行ADMIXTURE
for K in $(seq 2 10); do
  admixture --cv popgen_pruned.bed ${K} -j16 --seed=42 \
    | tee admixture_K${K}.log
done

# 提取CV error
grep "CV error" admixture_K*.log | \
  awk '{print NR+1, $NF}' > cv_errors.txt

# 可视化CV error选择最优K
# ADMIXTURE结果可视化
library(ggplot2)
library(tidyr)
library(dplyr)

# 读取最优K的Q矩阵(假设K=4最优)
K <- 4
q_matrix <- read.table(paste0("popgen_pruned.", K, ".Q"))
fam <- read.table("popgen_pruned.fam")
pop_info <- read.table("population_labels.txt", header=TRUE)

# 整理数据
q_df <- cbind(IID=fam$V2, q_matrix)
q_df <- merge(q_df, pop_info, by="IID")
colnames(q_df)[2:(K+1)] <- paste0("Ancestry_", 1:K)

# 转为长格式
q_long <- q_df %>%
  pivot_longer(cols=starts_with("Ancestry_"), 
               names_to="Ancestry", values_to="Proportion") %>%
  arrange(Population, Ancestry)

# 结构图
ggplot(q_long, aes(x=IID, y=Proportion, fill=Ancestry)) +
  geom_bar(stat="identity", width=1) +
  facet_grid(~Population, scales="free_x", space="free_x") +
  scale_fill_brewer(palette="Set2") +
  labs(y="Ancestry Proportion", title=paste0("ADMIXTURE K=", K)) +
  theme_minimal() +
  theme(
    axis.text.x = element_blank(),
    axis.ticks.x = element_blank(),
    panel.spacing = unit(0.1, "lines")
  )

ggsave("admixture_barplot.pdf", width=12, height=4)

# CV error图
cv <- read.table("cv_errors.txt")
ggplot(cv, aes(x=V1, y=V2)) +
  geom_line() + geom_point() +
  labs(x="K", y="Cross-validation error", title="ADMIXTURE CV Error") +
  scale_x_continuous(breaks=2:10) +
  theme_minimal()

步骤5:系统发育树

白话解释:用SNP数据构建群体之间的进化关系树,直观展示哪些群体亲缘关系更近。可以构建个体水平的树或群体水平的NJ树/ML树。

技术细节

SNP数据构建系统发育树的方法: - 距离法(NJ树):计算个体/群体间的遗传距离矩阵,用邻接法建树。快速但可能丢失信息。 - 最大似然法(RAxML/IQ-TREE):更准确但计算量大,适合SNP concatenation数据 - SNPhylo:专为全基因组SNP数据设计的流水线,自动做LD修剪和建树

注意:SNP系统发育树假设所有位点独立进化且无重组,这对于连锁的基因组数据是近似。对于群体水平推断,网状进化(admixture graph, TreeMix)可能比严格的树形更合适。

# SNPhylo流水线
snphylo.sh -v filtered.vcf \
  -l 0.1 \
  -m 0.1 \
  -M 0.05 \
  -b 1000 \
  -t 16

# 或手动方式:PLINK距离矩阵 → NJ树
plink2 --bfile popgen_pruned \
  --distance square 1-ibs \
  --out dist_matrix

# 用R构建NJ树
library(ape)
library(ggtree)

# 读取距离矩阵
dist_mat <- read.table("dist_matrix.dist", header=FALSE, skip=1)
ids <- read.table("dist_matrix.dist.id")
rownames(dist_mat) <- ids$V2
colnames(dist_mat) <- ids$V2

# NJ树
nj_tree <- nj(as.dist(dist_mat))
nj_tree <- root(nj_tree, outgroup="outgroup_sample", resolve.root=TRUE)

# 可视化
ggtree(nj_tree, layout="rectangular") +
  geom_tiplab(size=2) +
  theme_tree2()

步骤6:Fst群体分化

白话解释:Fst(固定指数)量化两个群体之间的遗传分化程度。Fst=0表示完全没有分化(随机交配),Fst=1表示完全固定(两群体没有共享等位基因)。全基因组滑窗Fst可以找到高度分化的区域(可能受到定向选择)。

技术细节

Fst的计算方法: - Weir & Cockerham (1984):最广泛使用,考虑了样本量偏差 - Hudson估计:对小样本量更鲁棒 - Reynolds距离:适合近缘群体

全基因组Fst分析策略: - 全局Fst:整体群体分化程度 - 逐位点Fst:每个SNP的分化值 - 滑窗Fst:常用10-100kb窗口,5-50kb步长 - 离群值检测:寻找Fst显著高于基因组平均水平的区域

注意:Fst受样本量、MAF和遗传漂变的影响。小群体即使没有选择也可能有高Fst区域(漂变效应)。

# VCFtools计算全局Fst
vcftools --vcf filtered.vcf \
  --weir-fst-pop population_A.txt \
  --weir-fst-pop population_B.txt \
  --out fst_A_vs_B

# 滑窗Fst
vcftools --vcf filtered.vcf \
  --weir-fst-pop population_A.txt \
  --weir-fst-pop population_B.txt \
  --fst-window-size 50000 \
  --fst-window-step 25000 \
  --out fst_windowed_A_vs_B

# 多群体Fst(PLINK2)
plink2 --bfile popgen_qc \
  --fst POP \
  --pheno population_assignment.txt \
  --out pairwise_fst

步骤7:核苷酸多态性π

白话解释:π(nucleotide diversity)衡量一个群体内的遗传多样性——随机取两条序列,它们在一个位点上不同的概率有多大?π高说明群体多样性高;某个区域π特别低可能意味着那里经历了选择性清除。

技术细节

π的计算:对所有SNP位点,计算每对个体之间的碱基差异数,除以可比较的位点总数。

应用: - 全基因组π:比较不同群体的遗传多样性水平 - 滑窗π:检测局部多样性变化(低π谷可能是选择清除信号) - π比值(πA/πB):两群体多样性比较,偏离1.0的区域可能受到差异选择

与Tajima's D结合: - 低π + 负Tajima's D → 近期选择性清除(正选择) - 高π + 正Tajima's D → 平衡选择

# 计算滑窗π
vcftools --vcf pop_A.vcf \
  --window-pi 50000 \
  --window-pi-step 25000 \
  --out pi_pop_A

vcftools --vcf pop_B.vcf \
  --window-pi 50000 \
  --window-pi-step 25000 \
  --out pi_pop_B

步骤8:Tajima's D

白话解释:Tajima's D检验一个区域的等位基因频率谱是否偏离中性进化的期望。中性条件下D≈0;正选择(选择性清除)使D<0;平衡选择使D>0。

技术细节

Tajima's D的原理: - 比较两种多态性估计:θ_π(基于配对差异)和θ_W(基于分离位点数) - 中性条件下两者相等(D=0) - 选择性清除后:大量低频变异(多分离位点,少配对差异),D<0 - 平衡选择:中频变异增多,D>0 - 群体瓶颈也会导致D<0(需要区分)

显著性判断: - |D| > 2 通常被认为偏离中性 - 但需要考虑人口统计学历史的影响(如瓶颈、扩张) - 建议与中性模拟比较,或使用基因组分布的离群值

# VCFtools计算Tajima's D
vcftools --vcf pop_A.vcf \
  --TajimaD 50000 \
  --out tajima_pop_A

步骤9:选择性扫描检测

白话解释:当正选择驱动一个有利突变快速增频时,它会"拖着"周围的变异一起增频(搭便车效应),形成一个长的低多样性区域。iHS和XP-EHH通过检测异常长的单倍型来发现这些信号。

技术细节

iHS(integrated Haplotype Score): - 比较一个SNP两个等位基因的EHH(Extended Haplotype Homozygosity)衰减速率 - 如果一个等位基因的EHH衰减很慢(单倍型很长),说明它可能最近才被选择增频 - 适合检测不完全选择性清除(选择仍在进行中)

XP-EHH(Cross-Population Extended Haplotype Homozygosity): - 比较两个群体中同一位点的EHH - 适合检测一个群体中已经完成的选择性清除(等位基因已固定) - 能检测到iHS遗漏的古老的完全清除

nSL:iHS的改进版本,对重组率变异更鲁棒。

输入要求: - 分相的单倍型数据(phased haplotypes) - 遗传图谱(genetic map,将物理距离转换为遗传距离)

# 使用selscan计算iHS
selscan --ihs \
  --vcf pop_A_phased.vcf.gz \
  --map genetic_map.map \
  --out ihs_pop_A \
  --threads 16

# 标准化iHS
norm --ihs --files ihs_pop_A.ihs.out --bins 100

# 计算XP-EHH
selscan --xpehh \
  --vcf pop_A_phased.vcf.gz \
  --vcf-ref pop_B_phased.vcf.gz \
  --map genetic_map.map \
  --out xpehh_A_vs_B \
  --threads 16

norm --xpehh --files xpehh_A_vs_B.xpehh.out --bins 100

步骤10:群体历史推断

白话解释:有效群体大小(Ne)反映了一个群体在进化历史中的规模变化。通过分析基因组中的变异模式,可以反推出过去数万到数百万年间群体大小如何变化——如扩张、瓶颈、分裂等事件。

技术细节

PSMC(Pairwise Sequentially Markovian Coalescent): - 适用于单个个体的高覆盖度全基因组数据(≥20×) - 分析基因组上异合子位点的分布模式 - 推断10万-数千万年前的Ne变化 - 分辨率在近期(<1万年)较差

SMC++: - 可使用多个未分相的全基因组序列 - 整合了样本频率谱(SFS)信息 - 对近期历史(<1000代)有更好的分辨率 - 不需要分相数据

MSMC2: - 需要分相的单倍型数据 - 可推断多群体的分离时间 - 对2-8个单倍型效果最佳

# PSMC分析流程
# 1. 生成diploid consensus序列
samtools mpileup -C50 -uf ref.fa sample.bam | \
  bcftools call -c | \
  vcfutils.pl vcf2fq -d 10 -D 100 | \
  gzip > diploid.fq.gz

# 2. 创建PSMC输入
fq2psmcfa -q20 diploid.fq.gz > diploid.psmcfa

# 3. 运行PSMC
psmc -N25 -t15 -r5 -p "4+25*2+4+6" -o output.psmc diploid.psmcfa

# 4. Bootstrap(100次)
seq 100 | xargs -I {} -P 16 \
  psmc -N25 -t15 -r5 -b -p "4+25*2+4+6" \
  -o round-{}.psmc diploid.psmcfa

# 5. 绘图(需要指定突变率和世代时间)
psmc_plot.pl -u 1.4e-08 -g 25 -p output output.psmc

# SMC++分析
# 1. 转换VCF为SMC格式
smc++ vcf2smc filtered.vcf.gz smc_data/chr1.smc.gz chr1 Pop1:sample1,sample2,sample3

# 2. 估计群体历史
smc++ estimate -o smc_output/ 1.4e-8 smc_data/*.smc.gz

# 3. 绘图
smc++ plot smc_plot.pdf smc_output/model.final.json

3. 实战命令/代码(完整流程)

#!/bin/bash
# ====================================================
# 群体遗传学分析完整流程
# ====================================================

set -euo pipefail
THREADS=16
VCF="all_populations.vcf.gz"
POP_FILE="population_info.txt"  # IID Population
OUTDIR="popgen_results"
mkdir -p ${OUTDIR}/{qc,pca,admixture,fst,selection,history}

# ---- Step 1-2: 质控+LD修剪 ----
echo "=== 数据质控 ==="
plink2 --vcf ${VCF} --maf 0.05 --geno 0.1 --mind 0.1 --hwe 1e-6 \
  --max-alleles 2 --make-bed --out ${OUTDIR}/qc/popgen_qc

plink2 --bfile ${OUTDIR}/qc/popgen_qc --king-cutoff 0.0884 --out ${OUTDIR}/qc/king
plink2 --bfile ${OUTDIR}/qc/popgen_qc \
  --remove ${OUTDIR}/qc/king.king.cutoff.out.id \
  --make-bed --out ${OUTDIR}/qc/popgen_unrel

plink2 --bfile ${OUTDIR}/qc/popgen_unrel --indep-pairwise 50 10 0.1 --out ${OUTDIR}/qc/ld
plink2 --bfile ${OUTDIR}/qc/popgen_unrel \
  --extract ${OUTDIR}/qc/ld.prune.in \
  --make-bed --out ${OUTDIR}/qc/popgen_pruned

echo "QC后: $(wc -l < ${OUTDIR}/qc/popgen_unrel.bim) SNPs, $(wc -l < ${OUTDIR}/qc/popgen_unrel.fam) samples"
echo "LD修剪后: $(wc -l < ${OUTDIR}/qc/popgen_pruned.bim) 独立SNPs"

# ---- Step 3: PCA ----
echo "=== PCA ==="
plink2 --bfile ${OUTDIR}/qc/popgen_pruned --pca 20 --out ${OUTDIR}/pca/pca

# ---- Step 4: ADMIXTURE ----
echo "=== ADMIXTURE ==="
for K in $(seq 2 8); do
  admixture --cv ${OUTDIR}/qc/popgen_pruned.bed ${K} -j${THREADS} --seed=42 2>&1 \
    | tee ${OUTDIR}/admixture/log_K${K}.txt
  mv popgen_pruned.${K}.Q ${OUTDIR}/admixture/
  mv popgen_pruned.${K}.P ${OUTDIR}/admixture/
done
grep "CV error" ${OUTDIR}/admixture/log_K*.txt > ${OUTDIR}/admixture/cv_summary.txt

# ---- Step 5: Fst ----
echo "=== Fst ==="
# 提取各群体样本列表
awk '$2=="PopA" {print $1}' ${POP_FILE} > ${OUTDIR}/fst/pop_A.txt
awk '$2=="PopB" {print $1}' ${POP_FILE} > ${OUTDIR}/fst/pop_B.txt

vcftools --gzvcf ${VCF} \
  --weir-fst-pop ${OUTDIR}/fst/pop_A.txt \
  --weir-fst-pop ${OUTDIR}/fst/pop_B.txt \
  --fst-window-size 50000 --fst-window-step 25000 \
  --out ${OUTDIR}/fst/fst_A_vs_B

# ---- Step 6: π和Tajima's D ----
echo "=== π和Tajima's D ==="
vcftools --gzvcf ${VCF} --keep ${OUTDIR}/fst/pop_A.txt \
  --window-pi 50000 --window-pi-step 25000 \
  --out ${OUTDIR}/selection/pi_A

vcftools --gzvcf ${VCF} --keep ${OUTDIR}/fst/pop_A.txt \
  --TajimaD 50000 \
  --out ${OUTDIR}/selection/tajD_A

# ---- Step 7: iHS ----
echo "=== 选择性扫描 ==="
selscan --ihs --vcf pop_A_phased.vcf.gz \
  --map genetic_map.map --out ${OUTDIR}/selection/ihs_A --threads ${THREADS}
norm --ihs --files ${OUTDIR}/selection/ihs_A.ihs.out --bins 100

echo "=== 分析完成 ==="

4. 面试常问点

Q1:什么是Fst?如何解读不同的Fst值?

Fst(固定指数)衡量群体间遗传分化程度,代表总遗传变异中由群体间差异贡献的比例。Fst=0:无分化(一个随机交配群体);Fst=0.05-0.15:中等分化;Fst=0.15-0.25:显著分化;Fst>0.25:高度分化。例如人类大陆间Fst约0.12,狗品种间Fst约0.3。全基因组高Fst窗口可能指示定向选择区域。

Q2:PCA和ADMIXTURE分析有什么区别和联系?

PCA是无参数方法,将遗传变异投影到低维空间,不假设群体数目。ADMIXTURE是模型化方法,假设K个祖先群体,估计每个体的祖先比例。联系:两者都揭示群体结构,结果通常一致——PCA中处于两群体之间的个体在ADMIXTURE中显示混合祖先。区别:PCA更适合数据探索和异常值检测;ADMIXTURE提供定量的祖先比例估计,但需要选择K值。

Q3:如何检测正选择?不同方法各适用什么场景?

常用方法:(1)基于群体分化:Fst离群值(比较群体间分化的极端区域);(2)基于频率谱:Tajima's D<0,过量低频等位基因;(3)基于单倍型:iHS(进行中的选择)、XP-EHH(完成的选择);(4)基于多样性:低π区域。适用场景:Fst适合比较两个群体受到不同选择压力的区域;iHS/XP-EHH适合近期选择(<30,000年);Tajima's D对选择清除敏感但也受人口统计学影响。

Q4:ADMIXTURE的K值如何选择?最优K一定是"真实"的祖先群体数吗?

K值选择主要通过交叉验证(CV error):对每个K计算CV error,选择最低值对应的K。但最优K不一定代表"真实"的祖先群体数,原因:(1)群体结构是连续的,离散K是近似;(2)CV error差异可能很小,多个K同样合理;(3)样本量和SNP数影响K选择。建议展示多个K的结果,结合生物学背景解读。

Q5:为什么群体遗传学分析前需要LD修剪?

PCA和ADMIXTURE假设SNP间独立。高LD区域(如MHC)如果不修剪,会在PCA中形成虚假的聚类轴,在ADMIXTURE中高估K值。LD修剪确保每个SNP提供独立的遗传信息,使结果反映真实的群体结构而非基因组局部特征。注意:Fst和选择信号分析通常不需要LD修剪(需要保留局部LD信息)。

Q6:PSMC和SMC++各有什么优缺点?

PSMC:只需1个高覆盖度个体,推断范围10^4-10^7年,但近期分辨率差、需要≥20×覆盖度。SMC++:可使用多个低覆盖度样本,近期分辨率好(<1000代),不需要分相,但需要更多计算资源。选择建议:如果只有一个高覆盖度基因组用PSMC;如果有多个样本且关心近期历史用SMC++。


5. 易错/易混淆点

  1. PCA/ADMIXTURE前忘记LD修剪:未修剪的数据会让PCA被高LD区域(如MHC)主导,ADMIXTURE会高估K值。这是最常见的新手错误。

  2. 混淆样本量不平衡对PCA的影响:如果一个群体有100个样本,另一个只有10个,PCA前几个PC可能主要反映大群体的内部变异。可以通过下采样或使用projection解决。

  3. 将Fst离群值直接等同于选择:高Fst可能由遗传漂变(小群体)、瓶颈效应或背景选择导致,不一定是定向选择。需要结合多种证据(π、Tajima's D、iHS)综合判断。

  4. iHS/XP-EHH使用未分相数据:基于单倍型的选择检测方法需要高质量的分相(phasing)。使用未分相或质量差的分相数据会严重影响结果准确性。

  5. PSMC的突变率和世代时间设置错误:PSMC的时间轴缩放完全依赖于突变率(μ)和世代时间(g)的假设。不同假设会给出完全不同的时间范围。务必明确说明使用的参数。

  6. 对小群体过度解读选择信号:有效群体大小很小的群体(如岛屿种群),遗传漂变的影响很强,很多看似"选择"的信号可能只是漂变。需要中性模拟来建立null分布。

  7. 忽略批次效应对群体结构的影响:如果不同群体在不同批次基因分型,技术差异可能被误判为群体结构。应在质控阶段检查批次与群体的混杂关系。


6. 补充知识

经典群体遗传学指标

  • θ_W(Watterson's theta):基于分离位点数估计的群体突变率
  • θ_π(核苷酸多样性π):基于配对差异估计的突变率
  • Tajima's D:θ_π - θ_W的标准化值
  • Fu's Fs:检测群体扩张的另一统计量
  • Dxy:群体间绝对分歧度

推荐软件和资源

  • PLINK2: https://www.cog-genomics.org/plink/2.0/
  • ADMIXTURE: https://dalexander.github.io/admixture/
  • selscan: https://github.com/szpiech/selscan
  • SMC++: https://github.com/popgenmethods/smcpp
  • PSMC: https://github.com/lh3/psmc
  • PopGenome (R): 一站式R包
  • scikit-allel (Python): Python群体遗传学工具库

推荐学习资源

  • Gillespie (2004) "Population Genetics: A Concise Guide" — 入门教材
  • Nielsen & Slatkin (2013) "An Introduction to Population Genetics" — 经典教材
  • 1000 Genomes Project数据 — 练习数据集
  • Graham Coop群体遗传学笔记 — 优秀免费资源