生信学习笔记:ArchR 处理小麦单细胞 ATAC-seq 中的细胞数差异与 Embedding 报错调试

1. 问题描述

在利用 ArchR 处理小麦(Wheat)单细胞 ATAC-seq 数据时,于"降维-聚类-可视化"环节观察到两个异常现象:

  1. 细胞数量的"迷之减少" :在分析流程的不同阶段,细胞总数经历了从 105,317 →\rightarrow→ 101,385 →\rightarrow→ 100,423 的梯度下降。
  2. Embedding 提取报错:在尝试提取 UMAP 坐标进行绘图时,系统提示找不到对应的 Embedding 对象,导致可视化中断。

2. 源码逻辑与代码对比

源码逻辑(ArchR 标准流程)

ArchR 的设计初衷是先构建一个稳定的低维空间(Reduced Dimensions) ,再基于此空间生成流形投影(Embedding),最后进行聚类分析。

  • addIterativeLSI():构建降维特征矩阵。
  • addUMAP():基于 LSI 结果生成二维投影。
  • addClusters():基于 LSI 结果进行聚类。

我的错误代码段(循环嵌套逻辑)

R 复制代码
# 错误示范:在循环中多次尝试生成 UMAP 并动态命名
for(res in c(0.4, 0.6, 0.8)){
  proj <- addClusters(input = proj, reducedDims = "IterativeLSI", resolution = res, name = paste0("Cluster_", res))
  # 报错诱因:在这里重复运行 addUMAP 并赋予了非标准名称
  proj <- addUMAP(ArchRProj = proj, reducedDims = "IterativeLSI", name = paste0("UMAP_", res), force = TRUE)
}
plotEmbedding(ArchRProj = proj, embedding = "UMAP", colorBy = "cellColData", name = "Cluster_0.6")

报错信息

Error: Embedding 'UMAP' does not exist in ArchRProject!

或在某些文件操作时出现:
Permission Error: Cannot write to ArrowFile...


3. 原因深度分析

3.1 细胞数量减少的"三部曲"

细胞数的变动并非数据丢失,而是经过了物理过滤数学算法排除的双重筛选:

  • Step 1 (105,317): 原始 QC(TSS 分数和片段数)达标后的细胞基数。
  • Step 2 (101,385): 运行 filterDoublets 后,物理剔除了 3,932 个统计学意义上的双细胞(Doublets)。这是为了防止伪影细胞干扰下游分析。
  • Step 3 (100,423): 运行 addIterativeLSI 时,剩余的 962 个细胞被排除。通过数据回溯发现,这 962 个细胞恰好构成了整个样本 C_Z8_2d_3
    • 数学原因addIterativeLSI 默认开启了 outlierQuantiles = c(0.02, 0.98),会自动过滤掉特征极其稀疏或偏倚严重的细胞。当整个样本的测序质量或复杂度处于极端分位数时,会被识别为"离群值"而无法投影到高维空间。

3.2 找不到 Embedding 的逻辑陷阱

在 ArchR 对象中,plotEmbedding 默认寻找名为 "UMAP" 的槽位。

  • 在上述循环代码中,用户将 Embedding 命名为 UMAP_0.6 等自定义名称。
  • 随后调用 plotEmbedding(embedding = "UMAP") 时,系统无法在 @embeddings 槽位中找到该名称,从而报错。
  • 此外,在循环中反复对同一个 LSI 空间运行 addUMAP 并多次读写 Arrow 文件,极易触发底层 HDF5 文件的权限冲突。

4. 解决方案与优化建议

纠正后的标准代码

原则:先统一构建空间,后并行探索分辨率。

R 复制代码
# 1. 降维(一次性完成)
proj <- addIterativeLSI(ArchRProj = proj, useMatrix = "TileMatrix", name = "IterativeLSI")

# 2. 生成全局 UMAP 投影(一次性完成,默认名称为 "UMAP")
proj <- addUMAP(ArchRProj = proj, reducedDims = "IterativeLSI", name = "UMAP")

# 3. 循环探索聚类分辨率(仅更新 cellColData,不改动降维和投影)
for(res in c(0.4, 0.6, 0.8)){
  proj <- addClusters(input = proj, reducedDims = "IterativeLSI", resolution = res, name = paste0("Cluster_", res), force = TRUE)
}

# 4. 绘图(此时 Embedding 槽位存在 "UMAP")
p <- plotEmbedding(ArchRProj = proj, embedding = "UMAP", colorBy = "cellColData", name = "Cluster_0.6")

为什么"先 UMAP 再循环聚类"更好?

  • 计算效率:UMAP 投影非常耗时,且它不依赖于聚类标签,只需运行一次即可。
  • 逻辑清晰 :聚类只是给细胞贴标签(存储在 cellColData),而 UMAP 是坐标映射。保持投影稳定,才能客观观察不同分辨率下聚类边界的变化。

5. 核心知识点总结

  1. IterativeLSI 原理 :采用 TF-IDF 归一化和迭代聚类的方法处理稀疏的 ATAC-seq 数据,通过 outlierQuantiles 自动过滤极端偏倚细胞以确保降维空间的鲁棒性。
  2. 双细胞过滤的影响filterDoublets 通过模拟异质性双细胞并计算富集分数来剔除物理上的重叠细胞。
  3. ArchR 槽位逻辑
    • @reducedDims:存储高维特征(如 LSI 矩阵)。
    • @embeddings:存储二维坐标(如 UMAP 结果)。
    • cellColData:存储细胞属性(如样本来源、聚类标签、TSS 分数)。

小结:在处理单细胞数据时,细胞数量的变动往往意味着算法在自动维护数据的"纯净度"。面对报错,理解 ArchR 对象的底层存储逻辑比盲目修改参数更为高效。

相关推荐
jinanwuhuaguo2 小时前
OpenClaw、飞书、Claude Code、Codex:四维AI生态体系的深度解构与颗粒化对比分析
大数据·人工智能·学习·飞书·openclaw
萨文 摩尔杰2 小时前
GPS原理学习
学习·fpga开发
fengci.3 小时前
ctfshow(web入门)295-300
java·开发语言·学习
renhongxia15 小时前
多模态融合驱动下的具身学习机制研究
运维·学习·机器人·自动化·知识图谱
今儿敲了吗5 小时前
46| FBI树
数据结构·c++·笔记·学习·算法
疯狂成瘾者5 小时前
git学习目录
git·学习
jinanwuhuaguo5 小时前
AI工具终极解构:OpenClaw、Coze、Dify、FastGPT、n8n、LangChain、RagFlow、GPTBots.ai 的万言深度剖析
人工智能·学习·重构·新人首发·openclaw
observe1017 小时前
51单片机学习
嵌入式硬件·学习·51单片机
leaves falling7 小时前
数据结构-堆学习
java·数据结构·学习