当前位置: 首页 > article >正文

单细胞学习(14)—— Seurat → Scanpy 多个样本的分析流程

Scanpy 处理多个样本的分析流程(对比 Seurat)

本学习笔记整理了在 Scanpy 处理多个样本的完整分析流程,并对比 Seurat 的对应功能,包括 数据读取、批次整合、降维聚类、UMAP 参数调整、可重复性保证 等关键环节。


1. 读取多个样本并合并

在 Seurat 中,我们可以用 Read10X() 读取多个样本,并用 merge()IntegrateData() 进行合并。

Seurat:

# 读取多个样本数据
sample1 <- Read10X("path/to/sample1/filtered_feature_bc_matrix")
sample2 <- Read10X("path/to/sample2/filtered_feature_bc_matrix")
seurat_obj1 <- CreateSeuratObject(counts = sample1, project = "sample1")
seurat_obj2 <- CreateSeuratObject(counts = sample2, project = "sample2")

# 合并对象
seurat_obj <- merge(seurat_obj1, y = seurat_obj2, add.cell.ids = c("sample1", "sample2"))

Scanpy,可以使用 sc.read_10x_mtx() 逐个读取样本,并用 sc.concat() 进行合并。

Scanpy(推荐方式):

import scanpy as sc
import os

sample_dirs = ["sample1", "sample2", "sample3", "sample4", "sample5", "sample6", "sample7", "sample8"]
adatas = []

for sd in sample_dirs:
    path = os.path.join("/data", sd, "filtered_feature_bc_matrix")
    ad = sc.read_10x_mtx(path, var_names='gene_symbols')
    ad.obs["sample"] = sd  # 添加样本名
    adatas.append(ad)

# 合并样本
adata = sc.concat(adatas, label='sample', keys=sample_dirs, index_unique='-')

Scanpy(另一种方法 concatenate()):

adata = adatas[0].concatenate(adatas[1:], join='outer') 

🔹 sc.concat() vs. concatenate() 对比

方法sc.concat()(推荐)concatenate()(旧方法)
批量合并多个对象✅ 支持 sc.concat(adatas)❌ 必须 adatas[0].concatenate(adatas[1:])
自动添加样本名label='sample'❌ 只会创建 batch(默认 0,1,2…)
**支持 **index_unique✅ 可以设置 index_unique='-'❌ 无法控制索引格式
基因合并策略join='outer'join='inner'join='outer'join='inner'
推荐使用适用于大规模数据,更加灵活❌ 适用于简单拼接(不推荐)

对比: Seurat 使用 merge(),而 Scanpy 推荐使用 sc.concat() 进行样本合并。 concatenate() 是较旧的方法,不建议用于多个样本的批量整合。

1. 读取多个样本并合并

在 Seurat 中,我们可以用 Read10X() 读取多个样本,并用 merge()IntegrateData() 进行合并。

Seurat:

# 读取多个样本数据
sample1 <- Read10X("path/to/sample1/filtered_feature_bc_matrix")
sample2 <- Read10X("path/to/sample1/filtered_feature_bc_matrix")
seurat_obj1 <- CreateSeuratObject(counts = sample1, project = "sample1")
seurat_obj2 <- CreateSeuratObject(counts = sample2, project = "sample1")

# 合并对象
seurat_obj <- merge(seurat_obj1, y = seurat_obj2, add.cell.ids = c("sample1", "sample1"))

Scanpy,可以使用 sc.read_10x_mtx() 逐个读取样本,并用 sc.concat() 进行合并。

Scanpy:

import scanpy as sc
import os

ssample_dirs = ["sample1", "sample2", "sample3", "sample4", "sample5", "sample6", "sample7", "sample8"]adatas = []

for sd in sample_dirs:
    path = os.path.join("/data", sd, "filtered_feature_bc_matrix")
    ad = sc.read_10x_mtx(path, var_names='gene_symbols')
    ad.obs["sample"] = sd  # 添加样本名
    adatas.append(ad)

# 合并样本
adata = sc.concat(adatas, label='sample', keys=sample_dirs, index_unique='-')

对比: Seurat 使用 merge(),而 Scanpy 推荐使用 sc.concat() 进行样本合并。


2. 质量控制(QC)

Seurat:

seurat_obj <- subset(seurat_obj, subset = nFeature_RNA > 200 & nFeature_RNA < 6000 & percent.mt < 10)

Scanpy:

sc.pp.filter_cells(adata, min_genes=200)
sc.pp.filter_genes(adata, min_cells=3)

adata.var['mt'] = adata.var_names.str.startswith('MT-')
adata.obs['percent_mt'] = (
    adata[:, adata.var['mt']].X.sum(1) / adata.X.sum(1)
) * 100
adata = adata[adata.obs['percent_mt'] < 10, :]

对比: Seurat 的 subset() 直接筛选,而 Scanpy 需要手动计算线粒体基因比例。


3. 归一化与高变基因选择

Seurat:

seurat_obj <- NormalizeData(seurat_obj)
seurat_obj <- FindVariableFeatures(seurat_obj, selection.method="vst", nfeatures=2000)

Scanpy:

sc.pp.normalize_total(adata, target_sum=1e4)
sc.pp.log1p(adata)
sc.pp.highly_variable_genes(adata, flavor='seurat_v3', batch_key='sample', n_top_genes=2000)
adata = adata[:, adata.var['highly_variable']]

对比: Seurat 使用 FindVariableFeatures(),Scanpy 则使用 sc.pp.highly_variable_genes() 进行变量基因筛选。


4. 去批次整合(Batch Correction)

在 Seurat 中,通常使用 IntegrateData() 进行批次校正。

Seurat:

seurat_obj <- FindIntegrationAnchors(object.list = list(seurat_obj1, seurat_obj2))
seurat_obj <- IntegrateData(anchorset = seurat_obj)

在 Scanpy,可以使用 BBKNN 进行批次校正。

Scanpy:

import scanpy.external as sce
sce.pp.bbknn(adata, batch_key='sample')

对比: Seurat 使用 IntegrateData(),而 Scanpy 推荐使用 BBKNN 进行批次整合。


5. 确保分析结果可重复

在 Seurat,我们可以使用 set.seed() 以保证可复现性。

Seurat:

set.seed(42)

在 Scanpy,等效的方法是:

import numpy as np
import random

np.random.seed(42)
random.seed(42)
sc.settings.n_jobs = 1  # 限制多线程计算,以避免并行计算的随机性

此外,为了确保 UMAP 结果可重复,应在 sc.tl.umap() 中设置 random_state

sc.tl.umap(adata, min_dist=0.3, spread=1.0, random_state=42)

对比: Scanpy 需要设置 random_state=42 并使用 np.random.seed(42) 以确保 UMAP 结果可重复。


6. 总结

本笔记对比了 SeuratScanpy 在多样本分析中的核心操作,涵盖 数据读入、批次整合、降维、UMAP 参数优化、可重复性控制 等内容。希望能帮助你在两者之间快速切换!


http://www.kler.cn/a/551360.html

相关文章:

  • el-table的hasChildren不生效?子级没数据还显示箭头号?树形数据无法展开和收缩
  • SQL 注入攻击详解[基础篇]:Web 应用程序安全漏洞与防御策略
  • 【系列专栏】银行IT的云原生架构-存储架构-数据安全 11
  • 【怎么使用Redis实现一个延时队列?】
  • 最新Apache Hudi 1.0.1源码编译详细教程以及常见问题处理
  • RAC 主动关闭数据库及直接关闭集群之间的关闭区别
  • Ubuntu22.04配置cuda/cudnn/pytorch
  • 鸡兔同笼问题
  • 【nvidia】NCCL禁用P2P后果权衡
  • 软件测试技术之跨平台的移动端UI自动化测试(上)
  • 毕业设计—基于Spring Boot的社区居民健康管理平台的设计与实现
  • ubuntu 22.04 安装vsftpd服务
  • HarmonyOS组件之Tabs
  • Kafka偏移量管理全攻略:从基础概念到高级操作实战
  • uniapp PDF 预览和下载
  • 一.AI大模型开发-初识机器学习
  • vm vitualbox和主机ssh连接,使用net 和仅主机网卡连接
  • HarmonyOS开发 - 记事本实例二(关系型数据库数据存储)
  • Kubernetes实战教程:基于Vue前端与Java后端的应用部署
  • 数据结构:Map Set(一)