scRNA-Seq | 多样本Seurat+CCA整合

一、前言

左边的图简单地把多个单细胞的数据合并在一起,不考虑去除批次效应,样本之间有明显的分离现象。右边的图是使用算法校正批次效应,不同的样本基本融和在一起了。scRNA数据校正批次效应的算法有很多:MNN, CCA+MNN, Harmony, Scanorama, scMerge等,本文推荐发表在Cell上的CCA+MNN方法,通过Seurat包就可以实现。

1. Seurat数据整合功能简介

Seurat早期版本整合数据的核心算法是CCA,文章发表在2018年的nature biotechnology,作者是Seurat的开发者Andrew Butler。同年Haghverdi等人开发了MNN算法校正批次效应,文章也发表在了nature biotechnology。2019年Andrew等人将CCA与MNN算法结合起来,并参考SNN算法的理念设计了“锚点”评分体系,使Seurat整合数据更强大更稳健。它不仅可以校正实验的批次效应,还能跨平台整合数据,例如将10x单细胞数据、BD单细胞数据和SMART单细胞数据整合在一起;也能整合单细胞多组学数据,例如将单细胞ATAC、空间转录组与单细胞转录组数据整合在一起。本文只讨论多样本数据的合并与校正批次效应,多组学数据的整合以后专门写篇文章介绍。

2. Seurat整合流程与原理

(1)使用CCA分析将两个数据集降维到同一个低维空间,因为CCA降维之后的空间距离不是相似性而是相关性,所以相同类型与状态的细胞可以克服技术偏倚重叠在一起。CCA分析效果见下图:

左图使用PCA降维,细胞之间的距离体现的是转录特征相似性,批次效应引入的系统误差会使样本分离。右图使用CCA降维,细胞之间的距离体现的是转录特征相关性,因此同类型且同状态的细胞可以跨越技术差异重叠在一起。

(2)CCA降维之后细胞在低维空间有了可以度量的“距离”,MNN(mutual nearest neighbor)算法以此找到两个数据集之间互相“距离”最近的细胞,Seurat将这些相互最近邻细胞称为“锚点细胞”。我们用两个数据集A和B来说明锚点,假设:

  • A样本中的细胞A3与B样本中距离最近的细胞有3个(B1,B2,B3)
  • B样本中的细胞B1与A样本中距离最近的细胞有4个(A1,A2,A3,A4)
  • B样本中的细胞B2与A样本中距离最近的细胞有2个(A5,A6)
  • B样本中的细胞B3与A样本中距离最近的细胞有3个(A1,A2,A7)

那么A3与B1是相互最近邻细胞,A3与B2、B3不是相互最近邻细胞,A3+B1就是A、B两个数据集中的锚点之一。实际数据中,两个数据集之间的锚点可能有几百上千个,如下图所示:

图中每条线段连接的都是相互最近邻细胞

(3)理想情况下相同类型和状态的细胞才能构成配对锚点细胞,但是异常的情况也会出现,如上图中query数据集中黑色的细胞团。它在reference数据集没有相同类型的细胞,但是它也找到了锚点配对细胞(红色连线)。Seurat会通过两步过滤这些不正确的锚点:

  1. 在CCA低维空间找到的锚点,返回到基因表达数据构建的高维空间中验证,如果它们的转录特征相似性高则保留,否则过滤此锚点。

  2. 检查锚点细胞所在数据集最邻近的30个细胞,查看它们重叠的锚点配对细胞的数量,重叠越多分值越高,代表锚点可靠性更高。原理见下图:

左边query数据集的一个锚点细胞能在reference数据集邻近区域找到多个配对锚点细胞,可以得到更高的锚点可靠性评分;右边一个锚点细胞只能在reference数据集邻近区域找到一个配对锚点细胞,锚点可靠性评分则较低。

4、经过层层过滤剩下的锚点细胞对,可以认为它们是相同类型和状态的细胞,它们之间的基因表达差异是技术偏倚引起的。Seurat计算它们的差异向量,然后用此向量校正这个锚点锚定的细胞子集的基因表达值。校正后的基因表达值即消除了技术偏倚,实现了两个单细胞数据集的整合。

深究技术细节的朋友可以参阅原文:Tim S, Andrew Butler, Paul Hoffman , et al. Comprehensive integration of single cell data[J].Cell,2019.

二、整合

1. 读入数据

GSE162631,4个胶质瘤样本,总计5万多个细胞。

library(dplyr)
library(Seurat)
library(patchwork)



dirs = dir(pattern = "^R")
f = "dat.Rdata"
if(!file.exists(f)){
  scelist = list()
}

2. 读取样本,创建 Seurat 对象

在读取样本的同时直接设置样本的筛选条件,如RNA,UMI,线粒体等。

for(i in 1:length(dirs)){
  x = Read10X(data.dir = dirs[[i]])
  scelist[[i]] <- CreateSeuratObject(counts = x, project = paste0("R",i))
  scelist[[i]][["percent.mt"]] <- PercentageFeatureSet(scelist[[i]], pattern = "^MT-")
  scelist[[i]] <- subset(scelist[[i]], subset = percent.mt < 10)
}
names(scelist)  = paste0("R",1:4)
sum(sapply(scelist, function(x)ncol(x@assays$RNA@counts)))

3. 对数据先进行标准化,并识别 variable feature

# normalize and identify variable features for each dataset independently
scelist <- lapply(X = scelist, FUN = function(x) {
    x <- NormalizeData(x)
    x <- FindVariableFeatures(x, selection.method = "vst", nfeatures = 3000)
  })

4. 整合数据

Seurat提供了一组Integration方法来去除批次效应,这些方法首先识别处于匹配生物学状态(anchors)的跨数据集细胞对,然后基于这些anchors校正数据集之间的批次效应


首先提取用来进行Integration的基因,然后找到anchors,基于anchors进行批次效应矫正

使用FindIntegrationAnchors函数识别锚点。参数默认。

然后我们将这些锚点传递给IntegrateData函数,该函数返回一个Seurat对象。

features <- SelectIntegrationFeatures(object.list = scelist)
immune.anchors <- FindIntegrationAnchors(object.list = scelist, anchor.features = features)
immune.combined <- IntegrateData(anchorset = immune.anchors)
DefaultAssay(immune.combined) <- "integrated"

immune.combined 是两个样品经过批次效应矫正后合并的Seurat 对象,对这个对象进行分群分析

然后我们可以使用这个新的表达矩阵进行下游分析和可视化。

5. 下游分析

按照单样本的流程继续分析,包括进行标准化,运行PCA,并使用UMAP可视化结果。

# Run the standard workflow for visualization and clustering
immune.combined <- ScaleData(immune.combined, verbose = FALSE)
immune.combined <- RunPCA(immune.combined, npcs = 30, verbose = FALSE)
immune.combined <- RunUMAP(immune.combined, reduction = "pca", dims = 1:30)
immune.combined <- FindNeighbors(immune.combined, reduction = "pca", dims = 1:30)
immune.combined <- FindClusters(immune.combined, resolution = 0.5)
save(immune.combined,file = f)


load(f)
p1 <- DimPlot(immune.combined, reduction = "umap", group.by = "orig.ident")
p2 <- DimPlot(immune.combined, reduction = "umap", label = TRUE, repel = TRUE)
p1 + p2

可以看到经过批次矫正后,4个样品的大部分细胞在UMAP上都是重叠的。

6. 注释

测试样品经过批次矫正后,相同类型的细胞都聚到了一起,这样更有利于对细胞类型进行鉴定。实际分析时,我们可以对自己的样品同时做这两种分析,根据结果来判断是否需要进行批次矫正。

library(celldex)
library(SingleR)
#ref <- celldex::HumanPrimaryCellAtlasData()
ref <- get(load("../single_ref/ref_Human_all.RData"))
library(BiocParallel)
pred.scRNA <- SingleR(test = immune.combined@assays$integrated@data, 
                      ref = ref,
                      labels = ref$label.main, 
                      clusters = immune.combined@active.ident)
pred.scRNA$pruned.labels
##  [1] "Macrophage"        "Macrophage"        "Monocyte"         
##  [4] "Macrophage"        "Macrophage"        "Macrophage"       
##  [7] "Macrophage"        "Monocyte"          "Neutrophils"      
## [10] "Neutrophils"       "Endothelial_cells" "Monocyte"         
## [13] "Macrophage"        "Macrophage"        "Tissue_stem_cells"
## [16] "NK_cell"           "Monocyte"          "B_cell"
plotScoreHeatmap(pred.scRNA, clusters=pred.scRNA@rownames, fontsize.row = 9,show_colnames = T)

image
new.cluster.ids <- pred.scRNA$pruned.labels
names(new.cluster.ids) <- levels(immune.combined)
levels(immune.combined)
##  [1] "0"  "1"  "2"  "3"  "4"  "5"  "6"  "7"  "8"  "9"  "10" "11" "12" "13" "14"
## [16] "15" "16" "17"
immune.combined <- RenameIdents(immune.combined,new.cluster.ids)
levels(immune.combined)
## [1] "Macrophage"        "Monocyte"          "Neutrophils"      
## [4] "Endothelial_cells" "Tissue_stem_cells" "NK_cell"          
## [7] "B_cell"
UMAPPlot(object = immune.combined, pt.size = 0.5, label = TRUE)

代码主要来自:https://satijalab.org/seurat/articles/integration_introduction.html

参考:
https://www.jianshu.com/p/9d798e95fb65
https://www.bilibili.com/read/cv15514134
https://www.jianshu.com/p/d323d0291dd4
https://baijiahao.baidu.com/s?id=1707789923750679171&wfr=spider&for=pc
https://mp.weixin.qq.com/s/PA_xTrqVYiZCOscP43CgUw
https://mp.weixin.qq.com/s/FWvOEJSNb9epNZmxwFkhkg
https://www.genenergy.cn/news/156/2379.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349