1. Seurat 大热,但 SingleCellExperiment对象 更基础
Seurat 是当前最常用的单细胞转录组分析工具之一,从原始数据到聚类注释再到可视化,是一个高度封装、一站式的解决方案。Seurat 的普及度、社区支持和功能丰富性都让它成为入门和实战的首选。然而,Seurat 背后的数据结构却往往被初学者忽略。而SingleCellExperiment(SCE) 这一数据框架是最早的单细胞标准!
很多人把 Seurat 当作“终点”,殊不知它只是一个应用层的封装。我们应该真正学习的是“对象核心”SCE。SCE的学习也有利于我们从R转向Python的单细胞分析。
SingleCellExperiment 是 Bioconductor 项目设计的基础类,继承自 SummarizedExperiment
,专为单细胞数据存储与分析而优化。SCE 可以统一存储表达矩阵、细胞/基因元数据、降维结果等信息,并被上百个 Bioconductor 单细胞工具所支持。此外,通过 Seurat v5 中的 as.SingleCellExperiment()
与 as.Seurat()
函数,可以在两个体系之间自由转换。
“如果我们从底层数据结构入手,搭建自己的分析流程,是否比依赖封装更稳、更灵活、更高效?”
SingleCellExperiment(简称 SCE)是 Bioconductor 所设计的用于单细胞转录组数据的 基础数据结构,扩展自 SummarizedExperiment。它专为单细胞实验量身打磨,能统一储存表达矩阵、细胞 / 基因metadata、降维坐标等信息,是跨 Bioconductor 工具生态系统的数据“交换货币”。
正因如此,即使你使用 Seurat 框架进行分析,也常常会在幕后频繁转换为 SCE 对象(as.SingleCellExperiment),并依赖这个结构用于下游分析与兼容其他包。
🛳️ 数据结构组成
图:SingleCellExperiment 对象的结构示意图,左侧为表达矩阵(assays),中间为 feature/gene 与 cell 注释(rowData / colData),右侧为降维结果(reducedDims),顶部或底部另设 metadata 模块。
这张图直观体现每个 slot 的布局与对应关系(见上方插图)
“想象 SCE 对象是一艘货轮,每个 slot 就是一个专用货箱,分别存储不同类型的数据,整船出发就是一次完整的数据分析旅程。”
SCE 不仅可以存储表达数据与 metadata,还支持存储 sizeFactors、altExps(替代实验数据)、colLabels 等信息,是 SummarizedExperiment 之上的专属扩展。
assays(sce) 会列出所有表达矩阵;colData(sce) 返回一个列对应细胞的 DataFrame。
3. 如何构建一个 SingleCellExperiment 对象?
创建对象最简单的方式,是利用 count 矩阵:
# 安装和加载所需包(如果尚未安装)
if (!requireNamespace("BiocManager", quietly = TRUE)) install.packages("BiocManager")
BiocManager::install(c("SingleCellExperiment", "scater"), ask = FALSE)
library(SingleCellExperiment)
library(scater)
# 1. 模拟表达 count 矩阵
set.seed(123)
num_genes <- 12
num_cells <- 8
counts_mat <- matrix(
as.integer(rpois(num_genes * num_cells, lambda = 5)),
nrow = num_genes, ncol = num_cells
)
rownames(counts_mat) <- paste0("Gene_", seq_len(num_genes))
colnames(counts_mat) <- paste0("Cell_", seq_len(num_cells))
# 2. 构造 rowData(基因注释)和 colData(细胞注释)
gene_metadata <- DataFrame(
gene_name = paste("G", seq_len(num_genes), sep = "_"),
gene_length = as.integer(rnorm(num_genes, mean = 10000, sd = 500))
)
cell_metadata <- DataFrame(
cell_id = colnames(counts_mat),
batch = rep(c("A", "B"), each = num_cells / 2),
cell_type = rep(c("Type1", "Type2"), times = num_cells / 2)
)
# 3. 构建 SCE 对象
sce <- SingleCellExperiment(
assays = list(counts = counts_mat),
rowData = gene_metadata,
colData = cell_metadata,
metadata = list(study = "DemoStudy")
)
sce # 打印对象摘要
class: SingleCellExperiment
dim: 12 8
metadata(1): study
assays(1): counts
rownames(12): Gene_1 Gene_2 ... Gene_11 Gene_12
rowData names(2): gene_name gene_length
colnames(8): Cell_1 Cell_2 ... Cell_7 Cell_8
colData names(3): cell_id batch cell_type
reducedDimNames(0):
mainExpName: NULL
altExpNames(0):
添加进一步内容:
# 4. 添加标准化表达(logcounts)
sce$sizeFactor <- colSums(counts_mat) / mean(colSums(counts_mat))
logcounts(sce) <- log2(counts(sce) / sce$sizeFactor + 1)
# 5. 添加降维坐标(PCA 或 UMAP)
pca_mat <- prcomp(t(logcounts(sce)))$x[, 1:2]
reducedDim(sce, "PCA") <- pca_mat
# 6. 查看对象内部结构
assayNames(sce) # count 和 logcounts
colnames(colData(sce)) # cell metadata 名称
rownames(rowData(sce)) # gene annotation
reducedDimNames(sce) # PCA
class: SingleCellExperiment
表示这个对象是 SingleCellExperiment
类,继承自 SummarizedExperiment
,专为单细胞设计的数据结构。
dim: 12 8
对象的维度是 12 行(基因)× 8 列(细胞)。
等同于:
nrow(sce) # 基因数
ncol(sce) # 细胞数
metadata(1): study
说明 metadata()
这个 slot 中包含一个元素,名字是 "study"
。
metadata(sce)
返回一个 list,可以记录整体数据集的注释、项目说明、分析参数等。metadata = list(study = "DemoStudy")
assays(2): counts logcounts
这个对象包含两个表达矩阵:
"counts"
:原始 UMI count 数(整数矩阵),未归一化"logcounts"
:log2 转换后的表达矩阵,用于可视化和降维可以通过:
assayNames(sce) # 查看所有 assays 名称
counts(sce) # 提取原始表达矩阵
logcounts(sce) # 提取标准化后表达矩阵
rownames(12): Gene_1 Gene_2 ... Gene_11 Gene_12
对象中有 12 个 feature(基因),名字是 Gene_1
到 Gene_12
。
rownames(sce)
查看所有基因名rowData names(2): gene_name gene_length
rowData(sce)
包含两个注释列:
"gene_name"
:人为命名的基因名称(如 G_1)"gene_length"
:基因长度(可用于 TPM 归一化或 GO 分析)你可以通过:
rowData(sce)$gene_name
colnames(8): Cell_1 Cell_2 ... Cell_7 Cell_8
有 8 个细胞,列名为 Cell_1
到 Cell_8
。
每一列是一个细胞/样本。通过 colnames(sce)
提取。
colData names(4): cell_id batch cell_type sizeFactor
colData(sce)
中有 4 个变量,分别是:
cell_id
:细胞名称(列名)batch
:批次信息,用于批次矫正cell_type
:细胞类型注释(如 Type1 / Type2)sizeFactor
:归一化因子(用于计算 logcounts)这些 metadata 可用于分群、颜色映射、差异分析等。
reducedDimNames(1): PCA
reducedDims(sce)
slot 中包含 1 个降维结果:
"PCA"
:主成分分析的前两个维度(由 prcomp()
得到)可通过:
reducedDim(sce, "PCA")
查看降维坐标矩阵(每行对应一个细胞,每列是主成分)。
mainExpName: NULL
mainExpName
是用于标记主实验的名称,在多模态数据中可设置主实验(如 RNA、ADT 等)。默认 NULL
即可。
altExpNames(0):
altExp()
是 “替代实验”模块(alternative experiments),用于存放额外的数据类型,如:
当前为 0
,即没有添加替代实验。
这期推文有个图上传不了,下一期补上,并且加上后续更多的使用案例!敬请谅解 https://bioconductor.org/books/3.12/OSCA/data-infrastructure.html?utm_source=chatgpt.com