单细胞分析前期很重要的一步是细胞类型注释,这一步看似很简单,有时候做起来却是最耗时的一步。如果数据很好,用经典的或者文献里的marker很轻松就可以定义出细胞类型,此时这一步可以说是易如反掌。但若是marker在数据中不好使,那看似简单的事情做起来也就不简单了。
此时,最容易想到的办法是扩大范围,使用更多的marker,利用数据库便顺利成章。利用所有可能的marker
将clsuter
与数据库中的细胞类型对应起来,即是手动注释的第一步。cluster
的marker
里面出现最多的细胞类型应该就是细胞群的身份。从代码实现的角度来说,就是各cluster
的marker
与数据库各细胞类型的marker
两两求交集,然后以marker
重叠数量的多少作为判断细胞类型的依据。虽然原理不复杂,但有时候还挺有用。
这个方法自己分析单细胞项目时经常用,所以写了函数方便每次做这个事情。但后来发现居然有人为此写了一个R包easybio
,为了方便使用包里面的函数和可视化,所以据此改写函数。比如,包可以将cluster
与CellMarker2
数据库做匹配,很方便地获得各cluster
对应的细胞类型及marker
。但作者采用的方式是将数据库封装到包里面,降低了扩展性,比如数据库是否有更新,不方便使用其他数据库。
为了提升通用性,改写了一下函数,提前准备好数据即可。使用数据库最重要的是marker和细胞类型,无论使用哪个数据库提前准备好这两个信息即可,列名分别为:marker
、cell_name
。
head(marker)
p_val avg_log2FC pct.1 pct.2 p_val_adj cluster gene
CD14 1.086367e-143 3.340479 1.000 0.136 2.796743e-139 0 CD14
S100A12 5.457276e-136 3.092504 0.990 0.137 1.404921e-131 0 S100A12
VCAN 8.175862e-135 3.171629 1.000 0.166 2.104794e-130 0 VCAN
LGALS2 4.906484e-124 3.025258 0.917 0.108 1.263125e-119 0 LGALS2
S100A9 5.231927e-124 3.499215 1.000 0.252 1.346907e-119 0 S100A9
CD36 1.881132e-119 2.879678 0.985 0.177 4.842785e-115 0 CD36
head(db)
marker cell_name
1 CYGB CD34+ CLP
2 ADA CD34+ CLP
3 UMODL1 CD34+ CLP
4 AC125603.1 CD34+ CLP
5 AGPS CD34+ CLP
6 TRBVB CD34+ CLP
source('manual_annotation.r')
res <- matchdb(marker, db, n=50)
head(res)
cluster cell_name uniqueN N
<fctr> <char> <int> <int>
1: 0 Neutrophil 28 28
2: 0 Immature-Neutrophil 4 4
3: 0 CD34+ HSC 1 1
4: 0 Eosinophil 1 1
5: 0 Erythroblast 1 1
6: 0 Granulocytic-UNK 1 1
ordered_symbol
<list>
1: AC004921.1,AC009506.1,AC022098.3,AC097504.2,AC116667.1,AL391832.3,...
2: FCGR1A,FLVCR2,NLRP3,TMEM51
3: PPM1H
4: FMN1
5: ALDH1A1
6: SIGLEC12
orderN markerWith
<list> <list>
1: 1,1,1,1,1,1,... S100A9,CD14,FOLR3,STAB1,PLA2G7,ASGR2,...
2: 1,1,1,1 FCGR1A,NLRP3,TMEM51,FLVCR2
3: 1 PPM1H
4: 1 FMN1
5: 1 ALDH1A1
6: 1 SIGLEC12
然后,利用可视化函数查看结果,直接从图上来看cluster
与细胞类型的对应关系:
library(easybio)
plotPossibleCell(res[, head(.SD), by = cluster], min.uniqueN = 2)
如此便可以很轻松地从图上可以看出cluster
最有可能属于哪一个细胞类型。顺带也修改了check_marker
、get_marker
、plotSeuratDot
三个函数,以能够适应自己提供的数据,方便做一些检验。
checkmk(marker, db, c(4, 9), topcellN=1)
$`Natural killer cell`
[1] "NCAM1" "GNLY" "NKG7" "FCGR3A" "KLRF1"
$Megakaryocyte
[1] "PPBP" "PF4" "ITGA2B" "TUBB1" "MYL9"
getmk(db, c('Natural killer cell', 'Megakaryocyte'), number=6)
$`Natural killer cell`
[1] "NCAM1" "GNLY" "NKG7" "FCGR3A" "KLRF1" "KLRD1"
$Megakaryocyte
[1] "PPBP" "PF4" "ITGA2B" "TUBB1" "MYL9" "GP9"
p <- plotdot(obj, c(4, 9), marker, db, topcellN=2)
p$clusters_9
现在写这样的函数并不难,只要能够描述清楚需求,借助大模型可以很轻松地写出相应的代码。但如果懒得自已弄了,不想花时间去倒腾和验证代码,可以后台回复manual_annotation
获取。