跳转至

626_单细胞代谢通路评分

一句话概述: 单细胞代谢通路评分利用基因集评分方法(AUCell、GSVA、ssGSEA等)推断每个细胞的代谢活性状态,scMetabolism是专门为单细胞代谢分析设计的R包,能一步完成从Seurat对象到代谢通路评分的全流程。

核心知识点速查表

概念白话解释
Metabolic pathway scoring代谢通路评分——用基因表达推断每个细胞的代谢活跃程度
Gene set scoring基因集评分——把一组功能相关基因的表达量汇总成一个分数
AUCell基于排名的基因集评分方法(用ROC曲线下面积)
GSVA基因集变异分析——非参数的基因集富集评分
ssGSEA单样本GSEA——对每个样本/细胞独立计算富集分数
scMetabolism专门用于单细胞代谢分析的R包
KEGG京都基因与基因组百科全书——代谢通路数据库
REACTOME反应通路数据库——详细的代谢反应通路
Metabolic flux代谢通量——代谢反应的速率(基因表达是间接代理指标)

一、安装

# === scMetabolism安装 ===
devtools::install_github("wu-yc/scMetabolism")  # 从GitHub安装

# === 依赖包安装 ===
if (!require("BiocManager")) install.packages("BiocManager")
BiocManager::install(c(
    "AUCell",       # AUCell评分方法
    "GSVA",         # GSVA评分方法
    "GSEABase",     # 基因集基础设施
    "clusterProfiler"  # 通路分析
))
install.packages(c("Seurat", "ggplot2", "pheatmap"))  # 其他依赖

library(scMetabolism)    # 加载scMetabolism
library(Seurat)          # 加载Seurat
library(AUCell)          # 加载AUCell
library(GSVA)            # 加载GSVA
library(ggplot2)         # 加载ggplot2

二、scMetabolism一步分析

2.1 基本用法

# === 读取Seurat对象 ===
seurat_obj <- readRDS("seurat_processed.rds")  # 读取已处理的Seurat对象

# === 使用scMetabolism计算代谢评分 ===
# 方法1:VISION(默认推荐)
seurat_metabolism <- sc.metabolism.Seurat(
    obj = seurat_obj,                # 输入Seurat对象
    method = "VISION",               # 评分方法(推荐VISION)
    imputation = FALSE,              # 是否做插补(大数据集设FALSE)
    ncores = 8,                      # 线程数
    metabolism.type = "KEGG"         # 代谢通路数据库
)

# 方法2:AUCell
seurat_aucell <- sc.metabolism.Seurat(
    obj = seurat_obj,
    method = "AUCell",               # 用AUCell方法
    imputation = FALSE,
    ncores = 8,
    metabolism.type = "KEGG"
)

# 方法3:ssGSEA
seurat_ssgsea <- sc.metabolism.Seurat(
    obj = seurat_obj,
    method = "ssgsea",               # 用ssGSEA方法
    imputation = FALSE,
    ncores = 8,
    metabolism.type = "KEGG"
)

# metabolism.type选项:
# "KEGG"     — KEGG代谢通路(85条通路)
# "REACTOME" — REACTOME代谢通路(更细致)

2.2 可视化代谢评分

# === 提取代谢评分矩阵 ===
metabolism_scores <- seurat_metabolism@assays$METABOLISM$score  # 提取评分

# === 气泡图:按细胞类型展示代谢通路 ===
DotPlot.metabolism(
    obj = seurat_metabolism,           # 带代谢评分的Seurat对象
    pathway = c(
        "Glycolysis / Gluconeogenesis",     # 糖酵解
        "Citrate cycle (TCA cycle)",         # TCA循环
        "Oxidative phosphorylation",         # 氧化磷酸化
        "Fatty acid biosynthesis",           # 脂肪酸合成
        "Glutathione metabolism",            # 谷胱甘肽代谢
        "Purine metabolism"                  # 嘌呤代谢
    ),
    phenotype = "cell_type",           # 按细胞类型分组
    norm = "y"                         # y轴归一化
)

ggsave("metabolism_dotplot.pdf", width = 12, height = 6)

2.3 UMAP上可视化特定通路

# === 在UMAP上着色显示代谢通路活性 ===
# 将代谢评分存入meta.data
pathway_name <- "Glycolysis / Gluconeogenesis"  # 目标通路
seurat_metabolism$glycolysis_score <- metabolism_scores[pathway_name, ]

# 画UMAP
FeaturePlot(
    seurat_metabolism,
    features = "glycolysis_score",      # 糖酵解评分
    cols = c("lightgrey", "red"),       # 颜色范围
    pt.size = 0.5                       # 点大小
) +
    labs(title = "Glycolysis Activity") +
    theme_minimal()

ggsave("glycolysis_umap.pdf", width = 8, height = 7)

# === 多个通路并排显示 ===
pathways_to_plot <- c(
    "Glycolysis / Gluconeogenesis",
    "Oxidative phosphorylation",
    "Fatty acid biosynthesis"
)

for (pw in pathways_to_plot) {
    safe_name <- gsub("[/ ()]", "_", pw)  # 安全的列名
    seurat_metabolism[[safe_name]] <- metabolism_scores[pw, ]
}

FeaturePlot(
    seurat_metabolism,
    features = gsub("[/ ()]", "_", pathways_to_plot),
    cols = c("lightgrey", "red"),
    ncol = 3,                            # 3列排列
    pt.size = 0.3
)

ggsave("metabolism_umap_multi.pdf", width = 18, height = 6)

三、手动实现AUCell评分

3.1 AUCell详细流程

# === 手动使用AUCell(更灵活)===
library(AUCell)  # 加载AUCell

# 第1步:构建排名矩阵
# AUCell的核心思想:对每个细胞的基因按表达量排名
# 然后看目标基因集中的基因是否排在前面
expr_matrix <- GetAssayData(seurat_obj, slot = "counts")  # 获取表达矩阵
cells_rankings <- AUCell_buildRankings(
    expr_matrix,                     # 表达矩阵
    nCores = 8,                      # 线程数
    plotStats = TRUE                 # 画排名统计图
)

# 第2步:准备基因集
# 从KEGG获取代谢通路基因集
library(clusterProfiler)  # 加载clusterProfiler
library(org.Hs.eg.db)     # 人类基因注释

# 获取KEGG通路的基因列表
kegg_pathways <- download_KEGG("hsa")  # 下载人类KEGG通路
pathway_genes <- kegg_pathways$KEGGPATHID2EXTID  # 通路-基因映射

# 转换基因ID格式(KEGG用Entrez ID,需转为Symbol)
# 构建GeneSet列表
gene_sets <- list()
for (pw_id in unique(pathway_genes$from)) {
    entrez_ids <- pathway_genes$to[pathway_genes$from == pw_id]
    symbols <- mapIds(org.Hs.eg.db, 
                      keys = entrez_ids, 
                      column = "SYMBOL",
                      keytype = "ENTREZID",
                      multiVals = "first")
    symbols <- symbols[!is.na(symbols)]  # 移除NA
    if (length(symbols) >= 5) {  # 至少5个基因
        gene_sets[[pw_id]] <- symbols
    }
}

# 第3步:计算AUC分数
cells_AUC <- AUCell_calcAUC(
    gene_sets,                       # 基因集列表
    cells_rankings,                  # 排名矩阵
    nCores = 8                       # 线程数
)

# 第4步:提取评分矩阵
auc_matrix <- getAUC(cells_AUC)      # 提取AUC矩阵
dim(auc_matrix)                       # 通路数 x 细胞数

3.2 GSVA评分

# === 使用GSVA方法 ===
library(GSVA)  # 加载GSVA

# 准备表达矩阵(用归一化后的数据)
expr_for_gsva <- as.matrix(
    GetAssayData(seurat_obj, slot = "data")  # 归一化数据
)

# 运行GSVA
gsva_scores <- gsva(
    expr_for_gsva,                   # 表达矩阵
    gene_sets,                       # 基因集列表
    method = "gsva",                 # GSVA方法
    kcdf = "Poisson",                # 适合计数数据的核密度
    parallel.sz = 8,                 # 8线程
    verbose = TRUE                   # 显示进度
)

# GSVA vs AUCell比较:
# GSVA:对整体分布更敏感,适合样本间比较
# AUCell:对稀疏数据更鲁棒,适合单细胞
# ssGSEA:每个细胞独立计算,中间方案

四、差异代谢分析

4.1 细胞类型间的代谢差异

# === 比较不同细胞类型的代谢活性 ===
# 将AUCell评分添加到Seurat对象
for (pw in rownames(auc_matrix)) {
    safe_name <- gsub("[^a-zA-Z0-9]", "_", pw)  # 安全列名
    seurat_obj[[safe_name]] <- auc_matrix[pw, colnames(seurat_obj)]
}

# 小提琴图比较代谢通路
VlnPlot(
    seurat_obj,
    features = c("hsa00010", "hsa00020", "hsa00190"),  # 糖酵解/TCA/氧磷
    group.by = "cell_type",            # 按细胞类型分组
    pt.size = 0,                       # 不显示散点
    ncol = 3                           # 3列
) & 
    theme(axis.text.x = element_text(angle = 45, hjust = 1))

4.2 条件间的代谢差异

# === 疾病vs对照的代谢差异 ===
# 使用Wilcoxon检验比较每个通路的评分
library(dplyr)  # 数据处理
library(tidyr)  # 数据整理

# 提取元数据和代谢评分
meta <- seurat_obj@meta.data  # 元数据
auc_df <- as.data.frame(t(auc_matrix))  # 转置AUC矩阵
auc_df$condition <- meta$condition  # 添加条件列
auc_df$cell_type <- meta$cell_type  # 添加细胞类型列

# 对每个通路做统计检验
results <- data.frame()  # 存储结果
for (pw in rownames(auc_matrix)) {
    for (ct in unique(meta$cell_type)) {
        subset_data <- auc_df[auc_df$cell_type == ct, ]  # 子集
        if (nrow(subset_data) > 10) {  # 至少10个细胞
            test <- wilcox.test(
                subset_data[[pw]][subset_data$condition == "disease"],
                subset_data[[pw]][subset_data$condition == "control"]
            )
            results <- rbind(results, data.frame(
                pathway = pw,
                cell_type = ct,
                p_value = test$p.value,
                mean_disease = mean(subset_data[[pw]][subset_data$condition == "disease"]),
                mean_control = mean(subset_data[[pw]][subset_data$condition == "control"])
            ))
        }
    }
}

# FDR校正
results$fdr <- p.adjust(results$p_value, method = "BH")  # BH校正
results$log2fc <- log2(results$mean_disease / results$mean_control)  # 效应量

# 显著的代谢差异
sig_results <- results[results$fdr < 0.05, ]  # FDR < 0.05
sig_results <- sig_results[order(sig_results$fdr), ]  # 按FDR排序
head(sig_results, 20)  # 前20个

# === 热图可视化 ===
library(pheatmap)  # 加载pheatmap

# 准备热图数据
heatmap_data <- results %>%
    dplyr::filter(fdr < 0.05) %>%               # 只保留显著的
    dplyr::select(pathway, cell_type, log2fc) %>%
    tidyr::pivot_wider(names_from = cell_type,   # 宽格式
                       values_from = log2fc,
                       values_fill = 0) %>%
    tibble::column_to_rownames("pathway")

pheatmap(
    as.matrix(heatmap_data),
    color = colorRampPalette(c("blue", "white", "red"))(100),
    cluster_rows = TRUE,             # 行聚类
    cluster_cols = TRUE,             # 列聚类
    fontsize_row = 8,                # 行标签大小
    main = "Metabolic Pathway Changes (Disease vs Control)"
)

五、方法对比

特性AUCellGSVAssGSEAVISION
原理排名+AUC非参数核密度排名富集签名分数
稀疏数据鲁棒一般一般鲁棒
速度中等
结果范围0-1无界无界无界
适用场景单细胞首选Bulk/伪Bulk通用单细胞
对零值敏感不敏感敏感中等不敏感
推荐程度单细胞首选Bulk首选通用scMetabolism默认

六、常见报错与解决

报错信息原因解决方案
Gene set too small基因集中的基因在数据中太少降低最小基因数阈值
No genes in common基因ID格式不匹配确认基因名格式(Symbol vs Entrez)
Memory error in GSVA细胞数太多降采样或用AUCell替代
NaN in scores某些细胞表达基因太少过滤掉低质量细胞
KEGG download failed网络问题使用离线基因集或设置代理
Pathway not found通路名称不精确匹配用grep模糊搜索通路名

七、面试高频题

Q1:为什么要做单细胞代谢通路评分?

答: 传统代谢组学测的是组织整体的代谢物浓度,无法区分不同细胞类型的代谢状态。但在肿瘤微环境中,T细胞和肿瘤细胞的代谢模式截然不同——肿瘤细胞大量消耗葡萄糖(Warburg效应),导致T细胞能量不足、功能耗竭。单细胞代谢评分通过基因表达间接推断每个细胞的代谢活性,可以:(1) 发现不同细胞类型的代谢特征;(2) 找到代谢重编程的细胞亚群;(3) 为代谢干预治疗提供靶点。局限性是基因表达≠代谢通量,需要实验验证。

Q2:AUCell方法的原理是什么?

答: AUCell的核心思想是"排名+面积":(1) 对每个细胞,按基因表达量从高到低排名;(2) 对目标基因集(如糖酵解基因),看这些基因是否排在前面;(3) 用ROC曲线的AUC量化——AUC越大说明基因集中的基因表达越高。AUCell对单细胞数据特别合适,因为它只看排名不看绝对值,对dropout(零值过多)不敏感。分数范围0-1,0.2以上通常算有活性。

Q3:KEGG和REACTOME代谢通路有什么区别?

答: KEGG按传统代谢路线组织通路(如糖酵解、TCA循环),覆盖面广但粒度较粗——一条通路可能包含几十个基因。REACTOME更细致,按反应步骤组织,一条通路可能只包含几个基因,层级结构更清晰。选择建议:初筛用KEGG(通路数少,结果更容易解读),深入分析用REACTOME(能精确定位到具体反应步骤)。注意:KEGG有商业授权问题,学术可免费用。

Q4:单细胞代谢评分有什么局限性?

答: 主要四个局限:(1) 基因表达≠蛋白活性≠代谢通量——mRNA水平高不代表酶活性高,代谢受翻译后修饰和代谢物浓度调控;(2) dropout问题——单细胞RNA-seq中大量基因检测不到(零值),可能低估代谢活性;(3) 基因集定义不一致——不同数据库对同一通路的基因列表不同;(4) 方法选择影响结果——AUCell、GSVA、ssGSEA对同一数据可能给出不同结论。最佳实践是:用多种方法交叉验证,对关键发现做实验验证(代谢组学或功能实验)。


参考资料:scMetabolism: Wu et al., Nucleic Acids Research 2022 | AUCell: Aibar et al., Nat Methods 2017 | GSVA: Hänzelmann et al., BMC Bioinformatics 2013 | VISION: DeTomaso et al., Nat Commun 2019