2022-01-12 Seurat官网单个样本标准流程
一、设置Seurat对象
使用的示例数据集来自10X Genome 测序的 PBMC。
下载链接:https://s3-us-west-2.amazonaws.com/10x.files/samples/cell/pbmc3k/pbmc3k_filtered_gene_bc_matrices.tar.gz
三个文件是“barcodes.tsv","features.tsv","matrix.mtx";
barcodes.tsv就是cell id
features.tsv就是gene id
matrix.mtx就是计数counts矩阵(UMI数量)
Read10X()函数从10X读取cellranger管道的输出,返回唯一的分子识别(UMI)计数矩阵。该矩阵中的值表示在每个细胞(列)中检测到的每个特征(即基因;行)的分子数。
【每个基因的UMI种类代表基因表达绝对量】
接下来,使用计数矩阵创建一个Seurat对象。该对象充当一个容器,其中包含单个细胞数据集的数据(如计数矩阵)和分析(如PCA或聚类结果)。有关Seurat对象结构的技术讨论,请查看GitHub Wiki。例如,计数矩阵存储在PBMC[[\“RNA\”]]@Counts中。
library(dplyr)
library(Seurat)
library(patchwork)
# Load the PBMC dataset 加载PBMC数据组
pbmc.data <- Read10X(data.dir = "../data/pbmc3k/filtered_gene_bc_matrices/hg19/")
# Initialize the Seurat object with the raw (non-normalized data).
#使用原始(非标准化数据)初始化Seurat对象
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 在1次分析中对2,700个样本进行了13714项特征(基因)分析
## Active assay: RNA (13714 features, 0 variable features)
计数矩阵中的数据长什么样子?看一下某3行(3个基因)的前30行(前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数据的内存和速度。
二、标准预处理流程
1、基于质量控制指标进行细胞过滤
2、数据标准化和缩放
3、检测高度可变特征
1、QC和选择细胞进行下一步分析
使用Seurat,可以浏览QC指标,并根据定义的标准过滤细胞。常用的一些质量控制指标包括
1)每个细胞中检测到的基因数nfeature(太少和太多都不要)
*低质量细胞或空滴通常只有很少的基因
*细胞二倍体或多重体可能表现出异常高的基因计数
2)每个细胞内检测到的分子总数nCount(UMI总数):标准和上面类似
3)线粒体基因组的read比例
*低质量/濒死的细胞通常表现出广泛的线粒体污染,出现大比例线粒体基因read
*将以MT-开头的所有基因定义为线粒体基因
*PercentageFeatureSet()函数计算线粒体QC指标(计算线粒体基因的比例)
# The [[ operator can add columns to object metadata. This is a great place to stash QC stats
#[[]]运算符可以向对象元数据添加列。可以用来存放QC统计数据
#计算线粒体read百分比
pbmc[["percent.mt"]] <- PercentageFeatureSet(pbmc, pattern = "^MT-")
QC指标存储在Seurat的什么地方?
在CreateSeuratObject()过程中会自动计算独特基因的数量和分子总数。可以在对象meta.data中找到它们
# Show QC metrics for the first 5 cells 显示前5个细胞的QC指标
head(pbmc@meta.data, 5)
## orig.ident nCount_RNA nFeature_RNA percent.mt
## AAACATACAACCAC-1 pbmc3k 2419 779 3.0177759
## AAACATTGAGCTAC-1 pbmc3k 4903 1352 3.7935958
## AAACATTGATCAGC-1 pbmc3k 3147 1129 0.8897363
## AAACCGTGCTTCCG-1 pbmc3k 2639 960 1.7430845
## AAACCGTGTATGCG-1 pbmc3k 980 521 1.2244898
nCount_RNA:每个细胞的UMI总数
【关于UMI的解释,详见单细胞测序学习(二) - —小郑同学— - 博客园 (cnblogs.com)】
*1个基因有几个UMI就有几个表达量(因为PCR扩增有偏好,用UMI来表示绝对RNA表达量)
nFeature_RNA:每个细胞所检测到的基因数目
一个基因可以对应多个UMI,所以nFeature<nCount
接下来,将QC指标可视化,并使用这些指标来过滤细胞。
*过滤nfeature计数(基因)大于2500或小于200的细胞
*过滤线粒体计数大于5%的细胞
# Visualize QC metrics as a violin plot
VlnPlot(pbmc, features = c("nFeature_RNA", "nCount_RNA", "percent.mt"), ncol = 3)
ncol代表用几列来显示图像
image.png# 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.
# FeatureScatter通常用于可视化特征-特征关系,但可用于对象计算的任何内容,即对象元数据中的列、PC分数等。
plot1 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "percent.mt")
plot2 <- FeatureScatter(pbmc, feature1 = "nCount_RNA", feature2 = "nFeature_RNA")
plot1 + plot2
image.png
过滤细胞
pbmc <- subset(pbmc, subset = nFeature_RNA > 200 & nFeature_RNA < 2500 & percent.mt < 5)
2、标准化数据: NormalizeData()
【关于什么是标准化,详见数据预处理之Normalization - 知乎 (zhihu.com)
对数据集进行一些变化,把数据拉到一个特定范围里,变得更有统计意义,有的基因表达太高,会影响整体的分析】
默认情况下,使用全局缩放归一化方法“LogNormalize”,该方法用总表达式标准化每个细胞的特征表达式测量值,再乘以比例因子(默认情况下为10,000),然后对结果进行对数转换。标准化值存储在PBMC[[\“RNA\”]]@data中。【
pbmc <- NormalizeData(pbmc, normalization.method = "LogNormalize", scale.factor = 10000)
标准化的方式和比例因子的默认值可以不写,直接写这个代码也是一样的
pbmc <- NormalizeData(pbmc)
3、识别差异基因:FindVariableFeature()
接下来,计算在数据集中表现出细胞间高差异的特征(基因)子集(即,它们在某些细胞中高表达,而在其他细胞中低表达)。在下游分析中关注这些基因有助于突出单细胞数据集中的生物信号。
在Seurat中的过程在这里进行了详细描述,通过直接对单个细胞数据中固有的均值-方差关系进行建模,改进了以前的版本,并在FindVariableFeature()函数中实现。默认情况下,为每个数据集返回2,000个要素。这些将用于下游分析,如PCA。
#识别变异最大的前2000个基因
pbmc <- FindVariableFeatures(pbmc, selection.method = "vst", nfeatures = 2000)
# Identify the 10 most highly variable genes 找出10个变异最大的基因
top10 <- head(VariableFeatures(pbmc), 10)
# plot variable features with and without labels 绘制带标签和不带标签的可变基因
plot1 <- VariableFeaturePlot(pbmc)
plot2 <- LabelPoints(plot = plot1, points = top10, repel = TRUE)
plot1 + plot2
points=要标出名字的基因集
repel=true可以解决标签重叠的问题
image.png
4、缩放数据:ScaleData()
接下来,应用线性变换(“缩放”),可以理解为PCA降维之前的标准预处理步骤。ScaleData()函数的作用是:
*改变每个基因的表达,使每个细胞基因的平均表达值为0
*缩放每个基因的表达,使细胞间的方差为1:
**这一步在下游分析中给予同等的权重,这样高表达的基因就不会占据主导地位。【方差反应的不同基因表达的离散程度】
*其结果存储在PBMC[[\“RNA\”]]@scale.data中
all.genes <- rownames(pbmc)
pbmc <- ScaleData(pbmc, features = all.genes)
5、线性降维:RunPCA()
接下来,对缩放后的数据执行PCA。默认情况下,只有先前确定的可变要素用作输入,但如果想选择不同的子集,则可以使用Feature参数进行定义。
pbmc <- RunPCA(pbmc, features = VariableFeatures(object = pbmc))
3种方法来可视化PCA的细胞和基因,包括VizDimReduce()、DimPlot()和DimHeatmap()
# Examine and visualize PCA results a few different ways通过几种不同的方式检查和可视化PCA结果
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
VizDimReduce()
VizDimLoadings(pbmc, dims = 1:2, reduction = "pca")
image.png
DimPlot()
DimPlot(pbmc, reduction = "pca")
image.png
DimHeatmap()
DimHeatmap()可以查看数据中异质性的主要来源,并可以确定哪些PCA维度可以用于下一步的下游分析。细胞和特征根据PCA的分数进行排序。
DimHeatmap(pbmc, dims = 1, cells = 500, balanced = TRUE)
image.png
DimHeatmap(pbmc, dims = 1:15, cells = 500, balanced = TRUE)
image.png
6、确定数据集的维度(PC=?)
为了克服在单细胞数据中在单个特征中的技术噪音,Seurat 聚类细胞是基于PCA分数的。每个PC代表着一个‘元特征’(带有跨相关特征集的信息)。因此,最主要的主成分代表了压缩的数据集。问题是要选多少PC呢?
方法一:JackStrawPlot
作者受JackStraw procedure 启发。随机置换数据的一部分子集(默认1%)再运行PCA,构建了一个’null distribution’的特征分数,重复这一步。最终会识别出低P-value特征的显著PCs
# 注意:对于大数据集,此过程可能需要很长时间,为方便起见,请将其注释掉。
# 可以使用更多的#近似技术(如在ElBowPlot()中实现的技术)来减少#计算时间。
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)
image.png
方法二:ElbowPlot
“ElbowPlot”:基于每个分量所解释的方差百分比对主要成分进行排名。 在此示例中,我们可以在PC9-10周围观察到“elbow ”,这表明大多数真实信号是在前10台PC中捕获的。
ElbowPlot(pbmc)
image.png
为了识别出数据的真实维度,有三种方法:
1、用更加受监督的方法来确定PCs的异质性,比如可以结合GSEA来分析
2、基于随机空模型的统计测试,但是对于大型数据集来说很费时间,并且可能不会返回一个清晰的 pc 连接。
3、常用的启发式算法,可以立即计算出来。
在这个例子中三种方法均产生了相似的结果,以PC 7-12作为阈值。
这个例子中,作者选择10,但是实际过程中还要考虑:
1、树突状细胞和NK细胞可能在PCs12和13中识别,这可能定义了罕见的免疫亚群(比如,MZB1是浆细胞样DC的标记)。但是除非有一定的知识量,否则很难从背景噪音中发现。
2、用户可以选择不同的PCs再进行下游分析,比如选10,15,50等。结果常常差不多
3、建议在选择该参数时候,尽量偏高一点。如果仅仅使用5PCs会对下游分析产生不利影响
7、聚类:FindClusters()
pbmc <- FindNeighbors(pbmc, dims = 1:10) #将之前定义的数据集维度(前10个PC作为输入)
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: 95965
##
## Running Louvain algorithm...
## Maximum modularity in 10 random starts: 0.8723
## Number of communities: 9
## Elapsed time: 0 seconds
FindClusters()函数包含一个分辨率参数,该参数设置下游集群的“粒度”,值越大,集群数量越多。将此参数设置在0.4-1.2之间通常会为大约3K个细胞的数据集返回良好的结果。对于较大的数据集,最佳分辨率通常会增加。
可以使用idents()函数找到聚类亚群ID。
#查看前5个细胞的聚类亚群ID
head(Idents(pbmc), 5)
## AAACATACAACCAC-1 AAACATTGAGCTAC-1 AAACATTGATCAGC-1 AAACCGTGCTTCCG-1
## 2 3 2 1
## AAACCGTGTATGCG-1
## 6
## Levels: 0 1 2 3 4 5 6 7 8
8、非线性降维(UMAP/tSNE)
Seurat提供了几种非线性降维技术,如tSNE和UMAP,以可视化和探索这些数据集。这些算法的目标是了解数据的底层流形,以便将相似的细胞放在低维空间中。
上述基于图形的聚类中的细胞应该在这些降维图上共同定位。
作为UMAP和tSNE的输入,建议使用相同的pc作为聚类分析的输入。
umap
# 安装umap包:reticulate::py_install(packages ='umap-learn')
pbmc <- RunUMAP(pbmc, dims = 1:10)
#可以设置`LABEL=TRUE`或使用LabelClusters函数来帮助标记单个群集
DimPlot(pbmc, reduction = "umap")
image.png
保存
saveRDS(pbmc, file = "../output/pbmc_tutorial.rds")
tsne
pbmc <- RunTSNE(pbmc, dims = 1:10)
DimPlot(pbmc, reduction = "tsne")
# 显示聚类标签
DimPlot(pbmc, reduction = "tsne", label = TRUE)
image.png
9、寻找亚群间差异表达基因:FindMarkers()
FindMarkers(对象,ident.1=指定亚群,Min.pct=,Thresh.test=)
Min.pct要求在两组亚群的任一组中以最小百分比检测到特征
【两个亚群中,至少有一个亚群有至少Min.pct的细胞有这个表达特征】
Thresh.test要求在两组细胞之间以一定数量(平均)差异表达特征。
【两个亚群中,这个表达特征的平均差异要达到Thresh.test】
可以将这两个值都设置为0,但会大大增加时间-因为这将测试大量不太可能有很大差别的特性。作为加速这些计算的另一个选项,可以设置max.cells.per.ident。这将对每个身份类进行下采样,使其细胞数不超过设置的值。虽然通常会失去动力,但速度的提高可能会很显著,最具差异性的功能可能仍然会上升到顶端。
发现亚群2的所有marker
cluster2.markers <- FindMarkers(pbmc, ident.1 = 2, min.pct = 0.25)
head(cluster2.markers, n = 5)
## p_val avg_log2FC pct.1 pct.2 p_val_adj
## IL32 2.593535e-91 1.2154360 0.949 0.466 3.556774e-87
## LTB 7.994465e-87 1.2828597 0.981 0.644 1.096361e-82
## CD3D 3.922451e-70 0.9359210 0.922 0.433 5.379250e-66
## IL7R 1.130870e-66 1.1776027 0.748 0.327 1.550876e-62
## LDHB 4.082189e-65 0.8837324 0.953 0.614 5.598314e-61
发现区分亚群5和亚群0、3的marker
cluster5.markers <- FindMarkers(pbmc, ident.1 = 5, ident.2 = c(0, 3), min.pct = 0.25)
head(cluster5.markers, n = 5)
## p_val avg_log2FC pct.1 pct.2 p_val_adj
## FCGR3A 2.150929e-209 4.267579 0.975 0.039 2.949784e-205
## IFITM3 6.103366e-199 3.877105 0.975 0.048 8.370156e-195
## CFD 8.891428e-198 3.411039 0.938 0.037 1.219370e-193
## CD68 2.374425e-194 3.014535 0.926 0.035 3.256286e-190
## RP11-290F20.3 9.308287e-191 2.722684 0.840 0.016 1.276538e-186
发现每个亚群和其他所有细胞相比的阳性marker,每个亚群显示两个
# ones
pbmc.markers <- FindAllMarkers(pbmc, only.pos = TRUE, min.pct = 0.25, logfc.threshold = 0.25)
pbmc.markers %>%
group_by(cluster) %>%
slice_max(n = 2, order_by = avg_log2FC)
## # A tibble: 18 × 7
## # Groups: cluster [9]
## p_val avg_log2FC pct.1 pct.2 p_val_adj cluster gene
## <dbl> <dbl> <dbl> <dbl> <dbl> <fct> <chr>
## 1 1.17e- 83 1.33 0.435 0.108 1.60e- 79 0 CCR7
## 2 1.74e-109 1.07 0.897 0.593 2.39e-105 0 LDHB
## 3 0 5.57 0.996 0.215 0 1 S100A9
## 4 0 5.48 0.975 0.121 0 1 S100A8
## 5 7.99e- 87 1.28 0.981 0.644 1.10e- 82 2 LTB
## 6 2.61e- 59 1.24 0.424 0.111 3.58e- 55 2 AQP3
## 7 0 4.31 0.936 0.041 0 3 CD79A
## 8 9.48e-271 3.59 0.622 0.022 1.30e-266 3 TCL1A
## 9 4.93e-169 3.01 0.595 0.056 6.76e-165 4 GZMK
## 10 1.17e-178 2.97 0.957 0.241 1.60e-174 4 CCL5
## 11 3.51e-184 3.31 0.975 0.134 4.82e-180 5 FCGR3A
## 12 2.03e-125 3.09 1 0.315 2.78e-121 5 LST1
## 13 6.82e-175 4.92 0.958 0.135 9.36e-171 6 GNLY
## 14 1.05e-265 4.89 0.986 0.071 1.44e-261 6 GZMB
## 15 1.48e-220 3.87 0.812 0.011 2.03e-216 7 FCER1A
## 16 1.67e- 21 2.87 1 0.513 2.28e- 17 7 HLA-DPB1
## 17 3.68e-110 8.58 1 0.024 5.05e-106 8 PPBP
## 18 7.73e-200 7.24 1 0.01 1.06e-195 8 PF4
Seurat有几个差异表达测试,可以使用test.use参数进行设置(有关详细信息,请参阅我们的DE Vignette)。例如,ROC测试返回任何单个标记的“分类能力”(范围从0-随机到1-完美)。
cluster0.markers <- FindMarkers(pbmc, ident.1 = 0, logfc.threshold = 0.25, test.use = "roc", only.pos = TRUE)
可视化marker表达的工具
VlnPlot()显示亚群间的某基因表达分布
FeaturePlot()在tSNE或PCA图上可视化某基因表达分布
这两个是最常用的可视化工具。还建议研究RidgePlot()、CellScatter()和DotPlot()作为查看数据集的其他方法。
VlnPlot()显示亚群间的某基因表达分布
VlnPlot(pbmc, features = c("MS4A1", "CD79A"))
image.png
可视化原始的count
VlnPlot(pbmc, features = c("NKG7", "PF4"), slot = "counts", log = TRUE)
image.png
FeaturePlot()在tSNE或PCA图上可视化某基因表达分布
FeaturePlot(pbmc, features = c("MS4A1", "GNLY", "CD3E", "CD14", "FCER1A", "FCGR3A", "LYZ", "PPBP",
"CD8A"))
image.png
DoHeatmap()为给定的细胞和基因生成表达式热图。在本例中,绘制每个群集的前10个标记(如果少于10个,则绘制所有标记)。
pbmc.markers %>%
group_by(cluster) %>%
top_n(n = 10, wt = avg_log2FC) -> top10
DoHeatmap(pbmc, features = top10$gene) + NoLegend()
image.png
10、注释
使用规范标记将无偏聚类与已知细胞类型相匹配:
image.png
new.cluster.ids <- c("Naive CD4 T", "CD14+ Mono", "Memory CD4 T", "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()
pt.size(字号)
image.png保存
saveRDS(pbmc, file = "../output/pbmc3k_final.rds")