mcpField
P
plink2-gwas-analysis

plink2-gwas-analysis

github.com/jaechang-hits数据与数据库38443 次安装6 天前更新
代码仓库

关于 plink2-gwas-analysis

plink2-gwas-analysis 是使用 PLINK2 处理基因型数据并开展 GWAS 和群体遗传学分析的技能,面向遗传学研究者。它覆盖数据质控、亲缘关系估计、PCA、关联检验和格式转换。

主要功能

  1. 01执行样本和变异质控
  2. 02估计亲缘关系并进行 PCA
  3. 03进行线性或逻辑回归关联检验
  4. 04转换 PLINK、VCF 和 BGEN 格式
  5. 05按频率、缺失率等筛选变异

适用场景

  1. 01对病例对照或定量性状开展 GWAS
  2. 02检查样本缺失率和杂合度
  3. 03通过 PCA 评估群体分层
  4. 04整理并筛选基因型数据

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/jaechang-hits/sciagent-skills --skill plink2-gwas-analysis

安装后在 Claude Code 中输入/plink2-gwas-analysis确认已加载。

详细介绍

PLINK2 — GWAS 与群体遗传学

概述

PLINK2 是 PLINK 1.9 的高性能后继版本,专为大型队列的全基因组关联研究(GWAS)和群体遗传学分析而设计。它可处理 PLINK 二进制格式(.bed/.bim/.fam)、VCF 和 BGEN 格式的基因型数据,并执行样本和变异质控(QC)、亲缘关系估算、主成分分析(PCA)以及线性/逻辑回归关联检验。得益于多线程和优化的 I/O,PLINK2 在大多数任务上的速度比 PLINK 1.9 快 10–100 倍。其输出文件与下游可视化(Manhattan/QQ 图)和荟萃分析工具兼容。

使用场景

  • 在完成基因分型芯片质控后,对病例-对照或定量性状队列运行 GWAS
  • 执行样本质控:缺失率、杂合度异常值、性别检查、隐匿亲缘关系
  • 计算全基因组 LD 剪枝,用于 PCA 或亲缘关系估算
  • 对基因型数据运行 PCA,以识别群体分层
  • 在 PLINK 二进制、VCF 和 BGEN 格式之间进行转换
  • 在 VCF/填补数据中按 MAF、HWE、缺失率或 INFO 分数筛选变异
  • 使用 omics-plotting SKILL 根据关联结果生成 Manhattan 图和 QQ 图
  • 对于需要通过混合模型关联分析控制群体结构的生物样本库规模 GWAS(>100k 个样本),改用 regenie 或 SAIGE
  • 使用 VCFtools 作为 VCF 专用群体遗传学统计分析的替代工具

先决条件

  • 软件:PLINK2(预编译二进制文件;无 pip/conda 包)
  • 输入:来自芯片基因分型或基因型填补的 PLINK 二进制文件(.bed/.bim/.fam)或 VCF/BGEN 文件

安装前检查:该工具可能已可用(例如,在 pixi / conda 环境中)。请务必先运行 command -v plink2;如果返回路径,则跳过安装部分。在 pixi 项目中执行工具时,优先使用 pixi run <tool>,而不是直接运行 <tool>。

# Skip install if already present
if command -v plink2 >/dev/null 2>&1; then
    echo "plink2 already installed: $(plink2 --version)"
else
    # Download PLINK2 pre-compiled binary (Linux)
    wget https://s3.amazonaws.com/plink2-assets/alpha6/plink2_linux_avx2_20241112.zip
    unzip plink2_linux_avx2_20241112.zip
    chmod +x plink2
    export PATH="$PWD:$PATH"

    # macOS
    # wget https://s3.amazonaws.com/plink2-assets/alpha6/plink2_mac_20241112.zip
    # unzip plink2_mac_20241112.zip

    plink2 --version
    # PLINK v2.00a6LM
fi

# Python for downstream analysis
pip install pandas numpy matplotlib scipy

预先访谈

编写任何分析代码前,请先与用户确认以下事项。

decisions:
  - id: D1
    param: phenotype
    kind: required
    source: data
    ask: "Which column holds the trait being tested, and is it a measurement or a case/control status?"
    default: null

  - id: D2
    param: regressionMode
    kind: derived
    source: data
    depends_on: [D1]
    ask: "Should the association test be linear or logistic?"
    default: "linear for a quantitative trait, logistic for case/control"

  - id: D3
    param: qcThresholds
    kind: required
    source: user
    ask: "Where should variants and samples be cut for allele frequency, missingness, and Hardy-Weinberg departure?"
    default: "MAF 0.01, variant missingness 0.05, sample missingness 0.02, HWE 1e-6"

  - id: D4
    param: covariates
    kind: required
    source: data
    ask: "Which covariates belong in the model - age, sex, batch, study site?"
    default: null

  - id: D5
    param: populationStructure
    kind: required
    source: user
    ask: "How many principal components should be included to absorb ancestry differences?"
    default: "10, computed from LD-pruned variants"

  - id: D6
    param: ldPruning
    kind: optional
    source: user
    depends_on: [D5]
    ask: "Which window and correlation threshold should thin variants before computing the components?"
    default: "50 variant window, step 5, r-squared 0.2"

  - id: D7
    param: threads
    kind: never_ask
    source: data
    reason: "Affects runtime only, not the association statistics"
    default: "min(8, available_cores)"

D5 取决于 D4,因为这些成分本身就是协变量——应纳入多少个成分,取决于协变量集合,而不是一个独立的参数。完全省略它们,是产生全基因组显著结果、但实际反映的是祖源而非性状的典型原因。

快速开始

# Run GWAS: linear regression for quantitative trait
plink2 \
    --bfile cohort_qc \
    --pheno phenotypes.txt \
    --covar covariates.txt \
    --linear hide-covar \
    --out results/gwas_result \
    --threads 8

# View top hits
head results/gwas_result.*.glm.linear | sort -k12,12g | head -20

工作流

步骤 1:将 VCF/填补数据转换为 PLINK 二进制格式

将输入的基因型数据转换为 PLINK 二进制格式,以便快速处理。

# Convert VCF to PLINK binary
plink2 \
    --vcf cohort_genotyped.vcf.gz \
    --make-bed \
    --out cohort_plink \
    --threads 8

# Convert BGEN (imputed data from Michigan/TopMed imputation server)
plink2 \
    --bgen cohort_imputed.bgen ref-first \
    --sample cohort_imputed.sample \
    --make-bed \
    --out cohort_imputed_plink \
    --threads 8

echo "Files created:"
ls -lh cohort_plink.{bed,bim,fam}
echo "Samples: $(wc -l < cohort_plink.fam)"
echo "Variants: $(wc -l < cohort_plink.bim)"
步骤 2:样本质控 — 缺失率和杂合度

移除缺失率较高或杂合度异常的样本。

# Compute per-sample and per-variant missingness
plink2 \
    --bfile cohort_plink \
    --missing \
    --out qc/sample_missingness \
    --threads 8

# Remove samples with > 2% missingness and variants with > 5% missing
plink2 \
    --bfile cohort_plink \
    --mind 0.02 \
    --geno 0.05 \
    --make-bed \
    --out cohort_sample_qc \
    --threads 8

echo "After sample QC:"
echo "Samples: $(wc -l < cohort_sample_qc.fam)"
echo "Variants: $(wc -l < cohort_sample_qc.bim)"
步骤 3:变异质控 — MAF、HWE 和 INFO 分数筛选

按次要等位基因频率、Hardy-Weinberg 平衡和基因型填补质量筛选变异。

# Variant QC: MAF, HWE, missingness
plink2 \
    --bfile cohort_sample_qc \
    --maf 0.01 \
    --hwe 1e-6 \
    --geno 0.05 \
    --make-bed \
    --out cohort_variantqc \
    --threads 8

echo "After variant QC:"
echo "Variants remaining: $(wc -l < cohort_variantqc.bim)"

# For imputed data: also filter by INFO score (using VCF INFO field)
# plink2 --bfile cohort_variantqc --var-min-qual 0.8 --make-bed --out cohort_info_qc
步骤 4:LD 剪枝和群体分层 PCA

根据经过 LD 剪枝的变异计算主成分。

# LD pruning: remove one variant from each pair with r² > 0.2
plink2 \
    --bfile cohort_variantqc \
    --indep-pairwise 50 5 0.2 \
    --out qc/ld_pruned \
    --threads 8

# Compute PCA on LD-pruned variants (top 20 PCs)
plink2 \
    --bfile cohort_variantqc \
    --extract qc/ld_pruned.prune.in \
    --pca 20 \
    --out pca/cohort_pca \
    --threads 8

echo "PCA files: pca/cohort_pca.eigenvec (PCs) and pca/cohort_pca.eigenval (variance)"
head pca/cohort_pca.eigenvec
步骤 5:运行 GWAS 关联分析

执行逻辑回归(病例-对照)或线性回归(定量性状)。

# Case-control GWAS: logistic regression with covariates
plink2 \
    --bfile cohort_variantqc \
    --pheno phenotypes.txt \
    --1 \
    --covar covariates.txt \
    --covar-variance-standardize \
    --logistic hide-covar \
    --ci 0.95 \
    --out results/gwas_cc \
    --threads 8

# Quantitative trait GWAS: linear regression
plink2 \
    --bfile cohort_variantqc \
    --pheno phenotypes.txt \
    --covar covariates.txt \
    --covar-variance-standardize \
    --linear hide-covar \
    --ci 0.95 \
    --out results/gwas_qt \
    --threads 8

echo "GWAS complete. Files: results/gwas_*.glm.*"
wc -l results/gwas_qt.*.glm.linear
步骤 6:绘制 Manhattan 图和 QQ 图

将关联结果整理为 CHR/BP/P 表,然后阅读 skills/data-visualization/omics-plotting/SKILL.md,并按照其中的 “Manhattan” 和 “QQ plot” 配方处理导出的 CSV(→ figures/manhattan.png、figures/qq.png)。

import pandas as pd

# Load GWAS results (PLINK2 linear output) as a CHR/BP/P table for plotting
df = pd.read_csv("results/gwas_qt.PHENO1.glm.linear", sep="\t",
                 usecols=["#CHROM", "POS", "ID", "P"])
df.columns = ["CHR", "BP", "SNP", "P"]
df = df.dropna(subset=["P"])
df["P"] = pd.to_numeric(df["P"], errors="coerce")
df = df[df["P"] > 0].copy()
df.to_csv("gwas.csv", index=False)

print(f"Variants: {len(df)}")
print(f"Genome-wide significant (p<5e-8): {(df['P'] < 5e-8).sum()}")
# Render with the omics-plotting SKILL (`skills/data-visualization/omics-plotting/SKILL.md`) "Manhattan" and "QQ plot" recipes (input columns CHR, BP, P).

关键参数

参数默认值范围/选项作用
--maf—0–0.5次要等位基因频率阈值;0.01 会移除单例变异
--hwe—0–1Hardy-Weinberg 平衡检验 p 值阈值;通常使用 1e-6
--geno—0–1变异缺失率上限;0.05 = 5%
--mind—0–1样本缺失率上限;0.02 = 2%
--linear / --logistic—标志回归模式:定量性状使用线性回归,病例-对照研究使用逻辑回归
--covar—文件路径协变量文件(FID IID COV1 COV2...);在此添加主成分
--pca—整数从 LD 剪枝后的数据中计算的主成分数量
--indep-pairwise—窗口 步长 r²LD 剪枝:窗口大小(变异数)、步长、r² 阈值
--threads11–64CPU 线程数;集群上通常使用 8–16
--ci—0–1效应大小输出的置信区间(95% 置信区间使用 0.95)
--1关闭标志重编码表型:1=对照,2=病例 → 0=对照,1=病例(逻辑回归)

常用操作示例

操作示例 1:亲缘关系 QC,并从每对亲缘样本中移除一个
# Compute kinship coefficients (King-robust estimator)
plink2 \
    --bfile cohort_variantqc \
    --extract qc/ld_pruned.prune.in \
    --king-cutoff 0.0625 \
    --out qc/kinship \
    --threads 8

# Remove related individuals (king-cutoff auto-generates exclusion list)
plink2 \
    --bfile cohort_variantqc \
    --remove qc/kinship.king.cutoff.out.id \
    --make-bed \
    --out cohort_unrelated \
    --threads 8

echo "After relatedness QC: $(wc -l < cohort_unrelated.fam) samples"
操作示例 2:解析 GWAS 结果并报告显著位点
import pandas as pd
import numpy as np

def load_gwas_results(filepath: str, p_threshold: float = 5e-8) -> pd.DataFrame:
    """Load PLINK2 GWAS linear/logistic output and return genome-wide significant hits."""
    df = pd.read_csv(filepath, sep="\t",
                     usecols=["#CHROM", "POS", "ID", "REF", "ALT", "A1", "BETA", "SE", "P"])
    df.columns = ["CHR", "POS", "SNP", "REF", "ALT", "A1", "BETA", "SE", "P"]
    df = df.dropna(subset=["P"])
    df["P"] = pd.to_numeric(df["P"], errors="coerce")
    sig = df[df["P"] < p_threshold].sort_values("P")
    return sig

# Load results for one phenotype
hits = load_gwas_results("results/gwas_qt.PHENO1.glm.linear")
print(f"Genome-wide significant loci: {len(hits)}")
print(hits.head(10)[["CHR", "POS", "SNP", "BETA", "SE", "P"]])
hits.to_csv("gwas_top_hits.tsv", sep="\t", index=False)

预期输出

输出格式描述
*.glm.linearTSV线性 GWAS 结果:每个变异包含 CHR、POS、ID、BETA、SE、P
*.glm.logistic.hybridTSV逻辑回归 GWAS 结果:每个变异包含 OR、95% CI、P
*.eigenvecTSVPCA 载荷:FID IID PC1 PC2 ... PC20
*.eigenval文本用于解释 PCA 方差的特征值
*.king.cutoff.out.idTSV因亲缘关系 QC 而需移除的样本 ID
*.bed/.bim/.fam二进制QC 过滤后的 PLINK 二进制格式

故障排除

问题原因解决方案
Error: No samples left after --mind filter缺失率阈值过严放宽至 --mind 0.05;检查输入数据质量
逻辑回归未能收敛变异罕见、病例数量少或协变量共线使用 --logistic firth 进行 Firth 回归;移除相关协变量
PCA 显示明显的离群群组混合祖源群体或样本污染使用 PC 截止值移除离群值;使用 1000 Genomes 参考面板检查祖源
--hwe 移除了过多变异群体结构导致 HWE 检验结果偏高仅对对照组应用 HWE 过滤:--hwe 1e-6 ctrl-only
BGEN 导入失败ref-first/ref-last 标志设置错误查看填补服务文档;尝试 --bgen file.bgen ref-last
关联检验速度很慢协变量过多或文件过大预先筛选到 GWAS 显著区域;使用 --threads 16
性别不匹配警告X 染色体杂合度超出性别特异性阈值运行 --check-sex 并移除 F 统计量离群值
大型数据集出现内存错误RAM 不足以处理 500k+ 个变异使用 --memory 32000 限制 RAM;按染色体拆分

参考资料

评论

支持 Markdown