clustree—聚类可视化利器
男,
一个长大了才会遇到的帅哥,
稳健,潇洒,大方,靠谱。
一段生信缘,一棵技能树。
生信技能树核心成员,单细胞天地特约撰稿人,简书创作者,单细胞数据科学家。
我们知道在研究问题时,分组是很重要的,有分组才有故事可讲。比如,两块田一块施肥一块不施肥,可以做比较嘛。在单细胞数据分析中用到较多的数据分组技术是聚类(clustering),这里面有很多的喜怒哀乐,因为聚类是无监督的,而且可以聚成不同的层次,在第一次聚类后,又可以对亚群聚类,真是子子孙孙无穷匮也。这也是单细胞数据分析的魅力所在:不同层次的聚类就像剥洋葱,剥着剥着,说不定就泪流满脸了呢?
如:
这T细胞分的好细致啊。
探索性数据分析
从目前大部分的单细胞分析流程来看,单细胞数据分析属于探索性数据分析。因为他用的主要分析方法,降维和聚类,都属于探索性数据分析方法。这也解释了为什么目前大部分的单细胞文章都是描述性质的了。就是把我们所能看到的东西报告给国际同行。一群细胞,有的人能看出十个类(找不同),有的人只能看出两点不同。这里的十个和两点就相当于我们说的resolution
.。
探索,对有的人来说是好事;对另一些人来说是坏事,他们需要确定的东西。探索的时候,多表现得贪婪:你帮我做一下看看,我想看看有什么结果,这是正常的,探索嘛。但是数据探索不是无止境的,虽然探索的时候尽量不带有偏见,但是探索的过程就是形成偏见的过程:指导下游分析。
鉴于单细胞数据探索性的特点,这启示我们:
首先,把数据分析流程分为两个阶段:探索与验证。探索时贪婪,多试试;验证时谨慎,慢慢来。二者要二八开,不要在探索中沉浸太久,探索的过程就像走马观花,获得数据概览,总体概貌。这也是不需要学科背景的一部分,所以哪家公司都可以做。他们的流程也就叫做单细胞探索性数据分析流程。而后面的百分之八十,是需要学科背景的,基本上离开课题组哪家公司都不能做,所以不要问我哪家公司单细胞做得好。这就像,你帮生病的住在的国外朋友找医院一样,医生如果不能对病人望闻问切,只能给你走一个标准体检流程。
君不见,有的单细胞数据就像不断转诊的病人,希望找到可以治愈焦虑的医生。因为连探索都没有遇到好的公司,更别说验证了。
第二,对科技服务公司来说,要找准自己的定位:优化探索流程,以提供研究视角。探索性数据分析是可流程化的,数据的分布,质量的检查,降维聚类,这些可以提供数据概览,让客户一看就可以有个切入点。验证这一块,可以配一个专业的团队和客户一起,在学科背景加持下展开分析。总结验证分析的一般原则,转化到探索流程中去。
探索性数据分析是一门学问
探索性数据分析(Exploratory Data Analysis,简称EDA),探索性数据分析是上世纪六十年代从数据分析中提炼出来的,其方法由美国统计学家John Tukey提出。是指在尽量少的先验假定下进行探索,通过作图(可视化)、制表(统计细胞数)、计算特征量(降维),聚类(发现类)等手段探索数据的结构(群)和规律(轨迹)的一种数据分析方法。特别是单细胞数据以高维多高噪声为显著特点,拿到数据后往往不知所措,不知道从哪里开始了解目前拿到手上的数据(excel看不了,或看不全),这时候探索性数据分析就非常有效。
聚类技术广泛应用于大型数据集的分析,将具有相似性质的样本聚类在一起。例如,聚类常用于单细胞rna测序领域,以识别组织样本中存在的不同细胞类型。执行聚类的算法有很多,结果可能有很大差异。特别是,数据集中出现的组的数量通常是未知的,而算法识别的集群数量可以根据所使用的参数而改变。为了探讨和检验不同聚类分辨率的影响,我们使用聚类树(clustree )可视化显示在多个分辨率下分群之间的关系,允许研究人员看到样本如何随着分群数量的增加而移动。此外,元信息可以覆盖在树中,以告知解决方案的选择,并指导分群的识别。
同样请出我们的数据集:
library(Seurat)
library(SeuratData)
library(clustree)
pbmc3k.final
An object of class Seurat
13714 features across 2638 samples within 1 assay
Active assay: RNA (13714 features, 2000 variable features)
2 dimensional reductions calculated: pca, umap
到底分多少个群是合适的呢?为了规避这个问题,我们多做几次聚类吧。
pbmc3k.final <- FindClusters(
object = pbmc3k.final,
resolution = c(seq(0,1.6,.2))
)
用clustree 看看不同resolution 下的相互关系:
clustree(pbmc3k.final@meta.data, prefix = "RNA_snn_res.")
查一下clustree是何方神圣。
原来为Seurat 提供了接口:
clustree(pbmc3k.final, prefix = "RNA_snn_res.", node_colour = "purple", node_size = 10,
node_alpha = 0.8) # 可以直接输入Seurat对象
然后这是一款专门为探索聚类分析而开发的R包,果然厉害。
我们可以在这个tree上绘制更多信息。
如线粒体信息啦,以及其他你想看的分数值。
clustree(pbmc3k.final@meta.data, prefix = "RNA_snn_res.", node_colour = "percent.mt",
node_colour_aggr = "mean")
我们可以调整布局:
clustree(pbmc3k.final@meta.data, prefix = "RNA_snn_res.", layout = "sugiyama")
增加节点信息:
clustree(pbmc3k.final, prefix = "RNA_snn_res.", node_label = "RNA_snn_res.")
标出线粒体含量:
clustree(pbmc3k.final, prefix = "RNA_snn_res.", node_label = "percent.mt",node_label_aggr = "median")
如果有先验知识,看看分群与之的匹配程度:
label_position <- function(labels) {
if (length(unique(labels)) == 1) {
position <- as.character(unique(labels))
} else {
position <- "mixed"
}
return(position)
}
clustree(pbmc3k.final@meta.data, prefix = "RNA_snn_res.", node_label = "seurat_annotations",
node_label_aggr = "label_position")
那些mixed
的群可以考察一下,是不是可以再分。
绘制表达量。
clustree(pbmc3k.final, prefix = "RNA_snn_res.",
node_colour = "CD79A", node_colour_aggr = "median")
这个可以看出clustree对Seurat的支持力度了。
我们来在umap空间绘制不同resolution 的分布情况。
pbmc3k.final<- AddMetaData(pbmc3k.final,pbmc3k.final@reductions$umap@cell.embeddings,
col.name = c("UMAP_1","UMAP_2"))
pbmc3k.final<- AddMetaData(pbmc3k.final,pbmc3k.final@reductions$pca@cell.embeddings,
col.name = colnames(pbmc3k.final@reductions$pca@cell.embeddings))
clustree_overlay(pbmc3k.final, prefix = "RNA_snn_res.", x_value = "UMAP_1", y_value = "UMAP_2")
clustree_overlay(pbmc3k.final, prefix = "RNA_snn_res.", x_value = "UMAP_1", y_value = "UMAP_2",
use_colour = "points", alt_colour = "blue")
加上标签
clustree_overlay(pbmc3k.final, prefix = "RNA_snn_res.", x_value = "UMAP_1", y_value = "UMAP_2",label_nodes = TRUE)
overlay_list <- clustree_overlay(pbmc3k.final, prefix = "RNA_snn_res.", x_value = "PC_1", y_value = "PC_2",
plot_sides = TRUE)
names(overlay_list)
#> [1] "overlay" "x_side" "y_side"
overlay_list$x_side
overlay_list$y_side
同时支持SingleCellExperiment格式的数据。
suppressPackageStartupMessages(library("SingleCellExperiment"))
data("sc_example")
names(sc_example)
sce <- SingleCellExperiment(assays = list(counts = sc_example$counts,
logcounts = sc_example$logcounts),
colData = sc_example$sc3_clusters,
reducedDims = SimpleList(TSNE = sc_example$tsne))
head(colData(sce))
clustree(sce, prefix = "sc3_", suffix = "_clusters")
我们还可以用ggplot语法来修饰。
clustree(pbmc3k.final, prefix = "RNA_snn_res.") +
guides(edge_colour = FALSE, edge_alpha = FALSE) +scale_color_brewer(palette = "Set1") +
scale_edge_color_continuous(low = "blue", high = "red")+
theme(legend.position = "bottom")