Files
RGC-ADOA/script/16_gsea_prerank.py
rain 092f39a662 chore: 初始化 RGC-ADOA 分析仓库
纳入 script/doc/ref/output 及配置;忽略 data/(26G 原始/中间数据)。
git 身份:rain <wjs_Rain@126.com>。
2026-09-18 18:21:19 +08:00

65 lines
2.7 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
16_gsea_prerank.py — 补齐 Step 6 的 GSEA preranked 富集分析(Hallmark
排序统计量:pseudobulk median-of-ratios LFC 的 S1/S2 均值(= 方向一致性 LFC)。
基因集:MSigDB Hallmark(小鼠,50 条)——作者未用 Hallmark(仅 Reactome/WikiPathways),
故本步是相对作者的增量;Reactome 富集直接用作者 S3–S12 交叉验证。
组:Muller / RGC2-like / RGC1-likeRGC2-like 标低功效)。
输出:output/16_gsea/ prerank 结果表 + NES 条形图。
"""
from pathlib import Path
import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
import gseapy as gp
OUT = Path("output/16_gsea")
OUT.mkdir(parents=True, exist_ok=True)
plt.rcParams.update({"figure.dpi": 300, "savefig.dpi": 300, "font.size": 8})
lib = gp.get_library(name="MSigDB_Hallmark_2020", organism="Mouse")
print(f"Hallmark: {len(lib)} sets")
GROUPS = ["Muller", "RGC2-like", "RGC1-like"]
all_results = {}
for grp in GROUPS:
de = pd.read_csv(f"output/11_pseudobulk_de/de_{grp}.csv")
rnk = de[["gene", "lfc_S1", "lfc_S2"]].copy()
rnk["score"] = (rnk["lfc_S1"] + rnk["lfc_S2"]) / 2
rnk = rnk[["gene", "score"]].dropna().sort_values("score", ascending=False)
print(f"== {grp}: {len(rnk)} 基因")
res = gp.prerank(rnk=rnk, gene_sets=lib, min_size=15, max_size=500,
permutation_num=1000, seed=0, threads=4, no_plot=True)
out = res.res2d.copy()
out.to_csv(OUT / f"gsea_{grp}_Hallmark.csv", index=False)
all_results[grp] = out
sig = out[out["FDR q-val"].astype(float) < 0.25]
print(f" FDR<0.25: {len(sig)} 条")
if len(sig):
print(sig[["Term", "NES", "FDR q-val"]].sort_values("NES").to_string(index=False))
# ---- NES 条形图(三组并排,取所有 Hallmark 条目的 NES ----
terms = all_results["Muller"]["Term"].tolist()
nes = pd.DataFrame({g: all_results[g].set_index("Term")["NES"].astype(float).reindex(terms)
for g in GROUPS})
nes = nes.loc[nes.abs().max(axis=1) > 0.5]
order = nes.abs().max(axis=1).sort_values().index
fig, ax = plt.subplots(figsize=(7, 9))
y = np.arange(len(order))
w = 0.28
for off, g, c in [(-w, "Muller", "#1f77b4"), (0, "RGC2-like", "#d62728"), (w, "RGC1-like", "#ff9896")]:
ax.barh(y + off, nes.loc[order, g], height=w, color=c, label=g, alpha=0.85)
ax.set_yticks(y, [t.replace("HALLMARK_", "").replace("_", " ").title() for t in order], fontsize=7)
ax.axvline(0, color="grey", lw=0.6)
ax.set_xlabel("NES")
ax.legend(fontsize=8, frameon=False)
ax.set_title("Hallmark GSEA prerank (NES, |NES|>0.5 in any group)")
fig.tight_layout()
fig.savefig(OUT / "gsea_hallmark_nes.png", bbox_inches="tight")
print("Done ->", OUT)