本文参考Satija Lab的seurat 包,网址 https://satijalab.org/seurat
设置Seurat对象
在本教程中,我们将分析10X Genomics免费提供的外周血单核细胞(PBMC)数据集。在Illumina NextSeq 500上对2,700个单细胞进行了测序。原始数据可以在这里找到。
我们首先阅读数据。该Read10X函数从10X 读取cellranger管道的输出,返回唯一分子识别(UMI)计数矩阵。该矩阵中的值表示在每个细胞(列)中检测到的每个特征(即基因;行)的分子数。
接下来我们使用计数矩阵来创建一个Seurat对象。该对象充当容器,其包含单细胞数据集的数据(如计数矩阵)和分析(如PCA或聚类结果)。有关Seurat对象结构的技术讨论,请查看我们的GitHub Wiki。例如,计数矩阵存储在pbmc[["RNA"]]@counts。
library(dplyr)library(Seurat)
# Load the PBMC dataset
pbmc.data <- Read10X(data.dir ="../data/pbmc3k/filtered_gene_bc_matrices/hg19/")(路径为下载的矩阵数据所在的位置,视各自下载路径而定)
# Initialize the Seurat object with the raw (non-normalized data).
pbmc <- CreateSeuratObject(counts = pbmc.data, project ="pbmc3k", min.cells =3, min.features =200)
pbmc
## An object of class Seurat
## 13714 features across 2700 samples within 1 assay
## Active assay: RNA (13714 features)
计数矩阵中的数据是什么样的?
# 让我们检查前30个细胞中的一些基因
pbmc.data[c("CD3D","TCL1A","MS4A1"),1:30]
## 3 x 30 sparse Matrix of class "dgCMatrix"
#### CD3D 4 . 10 . . 1 2 3 1 . . 2 7 1 . . 1 3 . 2 3 . . . . . 3 4 1 5
## TCL1A . . . . . . . . 1 . . . . . . . . . . . . 1 . . . . . . . .
## MS4A1 . 6 . . . . . . 1 1 1 . . . . . . . . . 36 1 2 . . 2 . . . .
矩阵中的值表示0(未检测到分子)。由于scRNA-seq矩阵中的大多数值都是0,因此Seurat尽可能使用稀疏矩阵表示。这为Drop-seq / inDrop / 10x数据带来了显着的内存和速度节省。
dense.size <- object.size(as.matrix(pbmc.data))dense.size
## 709548272 bytes
sparse.size <- object.size(pbmc.data)sparse.size
## 29861992 bytes
dense.size/sparse.size
## 23.8 bytes
标准的预处理工作流程
以下步骤包括Seurat中scRNA-seq数据的标准预处理工作流程。这些代表了基于QC指标,数据标准化和缩放以及高度可变特征的检测的细胞选择和过滤。
QC并选择细胞进行进一步分析
Seurat允许您根据任何用户定义的标准轻松探索QC指标和过滤单元格。社区常用的一些QC指标包括
在每个细胞中检测到的独特基因的数量。
低质量细胞或空液滴通常只有很少的基因
细胞双峰或多重峰可能表现出异常高的基因计数
同样,细胞内检测到的分子总数(与独特基因强烈相关)
映射到线粒体基因组的读数百分比
低质量/垂死细胞通常表现出广泛的线粒体污染
我们使用PercentageFeatureSet函数计算线粒体QC指标,该函数计算源自一组特征的计数百分比
我们使用所有基因MT-集作为一组线粒体基因
# The [[ operator can add columns to object metadata. This is a great place to stash QC stats
pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern ="^MT-"
在下面的示例中,我们可视化QC指标,并使用它们来过滤单元格。
我们过滤具有超过2,500或小于200的独特特征计数的细胞
我们过滤线粒体计数> 5%的细胞
# Visualize QC metrics as a violin plot
VlnPlot(pbmc, features =c("nFeature_RNA","nCount_RNA","percent.mt"), ncol =3)
# FeatureScatter is typically used to visualize feature-feature relationships, but can be used# for anything calculated by the object, i.e. columns in object metadata, PC scores etc.
plot1 <- FeatureScatter(pbmc, feature1 ="nCount_RNA", feature2 ="percent.mt")
plot2 <- FeatureScatter(pbmc, feature1 ="nCount_RNA", feature2 ="nFeature_RNA")
CombinePlots(plots = list(plot1, plot2))
pbmc <- subset(pbmc, subset = nFeature_RNA >200& nFeature_RNA <2500& percent.mt <5)
规范化数据
从数据集中删除不需要的单元格后,下一步是规范化数据。默认情况下,我们采用全局缩放规范化方法“LogNormalize”,通过总表达式对每个单元格的要素表达式度量进行标准化,将其乘以比例因子(默认为10,000),并对结果进行对数转换。归一化值存储在pbmc[["RNA"]]@data。
pbmc <- NormalizeData(pbmc, normalization.method ="LogNormalize", scale.factor =10000)
为清楚起见,在前一行代码(以及将来的命令)中,我们为函数调用中的某些参数提供默认值。但是,这不是必需的,可以通过以下方式实现相同的行为:
pbmc <- NormalizeData(pbmc)
识别高度可变的 features ( FindVariableFeatures )
接下来,我们计算在数据集中表现出高细胞间差异的特征子集(即,它们在一些细胞中高度表达,而在其他细胞中低表达)。我们和其他人已经发现,在下游分析中关注这些基因有助于突出单细胞数据集中的生物信号。
我们在这里详细描述了Seurat3中的程序,并通过直接建模单细胞数据中固有的均值 - 方差关系对先前版本进行了改进,并在FindVariableFeatures函数中实现。默认情况下,我们为每个数据集返回2,000个要素。这些将用于下游分析,如PCA。
pbmc <- FindVariableFeatures(pbmc, selection.method ="vst", nfeatures =2000)
# Identify the 10 most highly variable genestop10 <- head(VariableFeatures(pbmc),10)
# plot variable features with and without labels
plot1 <- VariableFeaturePlot(pbmc)
plot2 <- LabelPoints(plot = plot1, points = top10, repel =TRUE)
CombinePlots(plots = list(plot1, plot2))
缩放数据
接下来,我们应用线性变换('缩放'),这是在PCA等降维技术之前的标准预处理步骤。该ScaleData函数可以:
1.改变每个基因的表达,使得跨细胞的平均表达为0
2.缩放每个基因的表达,以便跨细胞的方差为1
3.该步骤在下游分析中给予相同的权重,因此高表达的基因不占优势
4.结果存储在 pbmc[["RNA"]]@scale.data
all.genes <- rownames(pbmc)
pbmc <- ScaleData(pbmc, features = all.genes)
这个步骤需要太长时间!我可以加快速度吗?
缩放是Seurat工作流程中必不可少的一步,但仅限于将用作PCA输入的基因。因此,默认值ScaleData仅为对先前标识的变量要素执行缩放(默认为2,000)。为此,省略features上一个函数调用中的参数,即
pbmc <- ScaleData(pbmc)
您的PCA和群集结果将不受影响。然而,Seurat热图(如下图所示产生DoHeatmap)需要对热图中的基因进行缩放,以确保高表达的基因不会影响热图。为了确保我们以后不将任何基因遗留在热图之外,我们正在扩展本教程中的所有基因。
如何在Seurat v2中删除不需要的变化来源?
在Seurat v2我们还利用ScaleData函数从单细胞集删除变化的干扰源。例如,我们可以“消退”与(例如)细胞周期阶段或线粒体污染相关的异质性。这些功能仍然支持ScaleData中Seurat v3,即:
pbmc <- ScaleData(pbmc, vars.to.regress ="percent.mt")
但是,特别是对于想要使用此功能的高级用户,我们强烈建议使用新的规范化工作流程sctransform。该方法在我们最近的预印本中进行了描述,这里使用Seurat v3单独设置了一个小插图。与此同时ScaleData,该功能SCTransform还包括一个vars.to.regress参数。
执行线性尺寸缩减
接下来,我们对缩放数据执行PCA。默认情况下,只有先前确定的变量要素用作输入,但features如果要选择其他子集,则可以使用参数定义。
pbmc <- RunPCA(pbmc, features = VariableFeatures(object = pbmc))
提供定义可视化细胞和功能的几种有用的方式PCA,包括VizDimReduction,DimPlot,和DimHeatmap
# Examine and visualize PCA results a few different ways
print(pbmc[["pca"]], dims =1:5, nfeatures =5)
## PC_ 1
## Positive: CST3, TYROBP, LST1, AIF1, FTL
## Negative: MALAT1, LTB, IL32, IL7R, CD2
## PC_ 2
## Positive: CD79A, MS4A1, TCL1A, HLA-DQA1, HLA-DQB1
## Negative: NKG7, PRF1, CST7, GZMB, GZMA
## PC_ 3
## Positive: HLA-DQA1, CD79A, CD79B, HLA-DQB1, HLA-DPB1## Negative: PPBP, PF4, SDPR, SPARC, GNG11
## PC_ 4
## Positive: HLA-DQA1, CD79B, CD79A, MS4A1, HLA-DQB1
## Negative: VIM, IL7R, S100A6, IL32, S100A8
## PC_ 5
## Positive: GZMB, NKG7, S100A8, FGFBP2, GNLY
## Negative: LTB, IL7R, CKB, VIM, MS4A7
VizDimLoadings(pbmc, dims =1:2, reduction ="pca")
DimPlot(pbmc, reduction ="pca")
特别是DimHeatmap允许容易地探索数据集中的异质性的主要来源,并且在试图决定包括哪些PC以用于进一步的下游分析时可以是有用的。细胞和特征都根据其PCA分数排序。设置cells为数字可以绘制光谱两端的“极端”单元格,从而大大加快了大型数据集的绘图速度。虽然显然是一种监督分析,但我们发现这是探索相关特征集的有用工具。
DimHeatmap(pbmc, dims =1, cells =500, balanced =TRUE)
DimHeatmap(pbmc, dims =1:15, cells =500, balanced =TRUE)
确定数据集的“维度”
为了克服scRNA-seq数据的任何单一特征中的广泛技术噪声,Seurat基于其PCA分数对细胞进行聚类,每个PC基本上代表在相关特征集中组合信息的“元特征”。因此,顶部主要组件表示数据集的强大压缩。但是,我们应该选择包含多少个组件?10?20?100?
在Macosko 等人中,我们实施了一项受JackStraw程序启发的重采样测试。我们随机置换数据的子集(默认为1%)并重新运行PCA,构建特征分数的“空分布”,并重复此过程。我们将“重要”PC识别为具有低p值特征的强大丰富的PC。
#NOTE:This process can take a long time for big datasets, comment out for expediency. More approximate techniques such as those implemented in ElbowPlot() can be used to reduce computation time
pbmc <- JackStraw(pbmc, num.replicate =100)
pbmc <- ScoreJackStraw(pbmc, dims =1:20)
该JackStrawPlot功能提供了一种可视化工具,用于比较每个PC的p值分布和均匀分布(虚线)。“重要的”PC将显示具有低p值的特征的强烈丰富(虚线上方的实线)。在这种情况下,看起来在前10-12个PC之后,重要性急剧下降。
JackStrawPlot(pbmc, dims =1:15)
另一种启发式方法生成“肘图”:基于每个(ElbowPlot函数)解释的方差百分比对主成分进行排序。在这个例子中,我们可以观察PC9-10周围的“肘部”,这表明大多数真实信号都是在前10PC中捕获的。
ElbowPlot(pbmc)
识别数据集的真实维度 - 对用户来说可能具有挑战性/不确定性。因此,我们建议考虑这三种方法。第一个是更多的监督,探索PC以确定异质性的相关来源,并且可以与GSEA一起使用。第二个实现基于随机空模型的统计测试,但对于大型数据集来说是耗时的,并且可能不会返回明确的PC截止。第三种是常用的启发式算法,可以立即计算。在这个例子中,所有三种方法产生了类似的结果,但我们可能有理由在PC 7-12之间选择任何作为截止值的东西。
我们在这里选择了10,但鼓励用户考虑以下内容:
1.树突细胞和NK研究者可以认识到与PC12和13强烈相关的基因定义了罕见的免疫亚群(即MZB1是浆细胞样DC的标记)。然而,这些组是如此罕见,如果没有先验知识,很难将这种大小的数据集与背景噪声区分开来。
2.我们鼓励用户使用不同数量的PC(10,15甚至50!)重复下游分析。正如您将观察到的,结果通常没有显着差异。
3.在选择此参数时,我们建议用户在较高的一侧犯错。例如,仅使用5台PC进行下游分析确实会对结果造成严重影响。
聚类细胞
Seurat v3采用基于图形的聚类方法,建立在(Macosko 等人)的初始策略之上。重要的是,驱动聚类分析的距离度量(基于先前识别的PC)保持不变。然而,我们将细胞距离矩阵分成簇的方法已经大大改进。我们的方法受到最近手稿的启发,这些手稿将基于图形的聚类方法应用于scRNA-seq数据[SNN-Cliq,Xu和Su,Bioinformatics,2015]和CyTOF数据[PhenoGraph,Levine 等,Cell,2015]。简而言之,这些方法将单元格嵌入图形结构中 - 例如K-最近邻(KNN)图形,在具有相似特征表达模式的单元格之间绘制边缘,然后尝试将此图形划分为高度互连的“准集团”或“社区”。
与PhenoGraph一样,我们首先根据PCA空间中的欧氏距离构建KNN图,并根据其局部邻域中的共享重叠(Jaccard相似性)细化任意两个单元之间的边权重。使用该FindNeighbors函数执行该步骤,并将先前定义的数据集维度(前10个PC)作为输入。
为了聚类细胞,我们接下来应用模块化优化技术,例如Louvain算法(默认)或SLM [SLM,Blondel 等,Journal of Statistical Mechanics],将细胞迭代分组在一起,目的是优化标准模块化功能。该FindClusters函数实现此过程,并包含一个分辨率参数,用于设置下游群集的“粒度”,增加的值会导致更多的群集。我们发现将此参数设置在0.4-1.2之间通常会返回大约3K单元格的单细胞数据集的良好结果。较大的数据集通常会增加最佳分辨率。可以使用该Idents功能找到群集。
pbmc <- FindNeighbors(pbmc, dims =1:10)
pbmc <- FindClusters(pbmc, resolution =0.5)
## Modularity Optimizer version 1.3.0 by Ludo Waltman and Nees Jan van Eck
#### Number of nodes: 2638
## Number of edges: 96033
#### Running Louvain algorithm...
## Maximum modularity in 10 random starts: 0.8720
## Number of communities: 9
## Elapsed time: 0 seconds
# Look at cluster IDs of the first 5 cellshead(Idents(pbmc),5)
## AAACATACAACCAC AAACATTGAGCTAC AAACATTGATCAGC AAACCGTGCTTCCG AAACCGTGTATGCG
## 1 3 1 2 6
## Levels: 0 1 2 3 4 5 6 7 8
运行非线性降维(UMAP / tSNE)
Seurat提供了几种非线性降维技术,如tSNE和UMAP,可视化和探索这些数据集。这些算法的目标是学习数据的基础流形,以便在低维空间中将相似的单元放在一起。上面确定的基于图的聚类内的单元应该共同定位这些降维图。作为UMAP和tSNE的输入,我们建议使用相同的PC作为聚类分析的输入。
# If you haven't installed UMAP, you can do so via reticulate::py_install(packages =# 'umap-learn')
(V3 版本这里有一个bug,装了umap-learn以后还是会报错 cant find umap,解决方法为:
1.restart R
2.重新run一次或两次下面的代码)
pbmc <- RunUMAP(pbmc, dims =1:10)
# note that you can set `label = TRUE` or use the LabelClusters function to help label individual clusters
DimPlot(pbmc, reduction ="umap")
您可以在此时保存对象,以便可以轻松地将其加载回来,而无需重新运行上面执行的计算密集型步骤,或者可以轻松地与协作者共享。
saveRDS(pbmc, file ="../output/pbmc_tutorial.rds")
寻找差异表达的特征(聚类生物标志物)
Seurat可以帮助您找到通过差异表达定义聚类的标记。默认情况下,它标识单个群集(指定ident.1)的正负标记,与所有其他单元格进行比较。FindAllMarkers为所有群集自动执行此过程,但您也可以测试群集彼此之间或所有单元格。
该min.pct论证要求在两组单元中的任一组中以最小百分比检测特征,并且thresh.test参数要求在两组之间以一定量差异地表示(平均)特征。您可以将这两个设置为0,但时间会急剧增加 - 因为这将测试大量不太可能具有高度不同的功能。作为加速这些计算的另一种选择,max.cells.per.ident可以设置。这将对每个标识类进行下采样,使其不再具有比设置的更多的单元格。虽然通常会出现功率损失,但速度增加可能是显着的,并且最高度差异表达的功能可能仍然会升至顶部。
# find all markers of cluster 1
cluster1.markers <- FindMarkers(pbmc, ident.1 =1, min.pct =0.25)
head(cluster1.markers, n =5)
# find all markers distinguishing cluster 5 from clusters 0 and 3
cluster5.markers <- FindMarkers(pbmc, ident.1 =5, ident.2 = c(0,3), min.pct =0.25)
head(cluster5.markers, n =5)
# find markers for every cluster compared to all remaining cells, report only the positive ones
pbmc.markers <- FindAllMarkers(pbmc, only.pos =TRUE, min.pct =0.25, logfc.threshold =0.25)
pbmc.markers %>% group_by(cluster) %>% top_n(n =2, wt = avg_logFC)
Seurat有几个差分表达式测试,可以使用test.use参数设置(有关详细信息,请参阅我们的DE插图)。例如,ROC测试返回任何单个标记的“分类能力”(范围从0 - 随机,到1 - 完美)。
cluster1.markers <- FindMarkers(pbmc, ident.1 =0, logfc.threshold =0.25, test.use ="roc", only.pos =TRUE)
我们提供了几种用于可视化标记表达的工具。VlnPlot(显示跨群集的表达概率分布),以及FeaturePlot(在tSNE或PCA图上可视化特征表达)是我们最常用的可视化。我们还建议您探索RidgePlot,CellScatter以及DotPlot查看数据集的其他方法。
VlnPlot(pbmc, features = c("MS4A1","CD79A"))
# you can plot raw counts as well
VlnPlot(pbmc, features = c("NKG7","PF4"), slot ="counts", log =TRUE)
FeaturePlot(pbmc, features = c("MS4A1","GNLY","CD3E","CD14","FCER1A","FCGR3A","LYZ","PPBP","CD8A"))
DoHeatmap为给定的单元格和要素生成表达式热图。在这种情况下,我们正在为每个群集绘制前20个标记(或所有标记,如果小于20)。
top10 <- pbmc.markers %>% group_by(cluster) %>% top_n(n =10, wt = avg_logFC)
DoHeatmap(pbmc, features = top10$gene) + NoLegend()
将单元类型标识分配给集群
幸运的是,在这个数据集的情况下,我们可以使用规范标记轻松地将无偏的聚类与已知的细胞类型相匹配:
new.cluster.ids <- c("Naive CD4 T","Memory CD4 T","CD14+ Mono","B","CD8 T","FCGR3A+ Mono","NK","DC","Platelet")
names(new.cluster.ids) <- levels(pbmc)pbmc <- RenameIdents(pbmc, new.cluster.ids)
DimPlot(pbmc, reduction ="umap", label =TRUE, pt.size =0.5) + NoLegend()
saveRDS(pbmc, file ="../output/pbmc3k_final.rds")