inferCNV:inferCNV用与探索肿瘤单细胞RNA-seq数据,分析其中的体细胞大规模染色体拷贝数变化(copy number alterations, CNA), 例如整条染色体或大片段染色体的增加或丢失(gain or deletions)。工作原理是,以一组"正常"细胞作为参考,分析肿瘤基因组上各个位置的基因表达量强度变化. 通过热图的形式展示每条染色体上的基因相对表达量,相对于正常细胞,肿瘤基因组总会过表达或者低表达。
inferCNV常用用途是区分上皮细胞是良性还是恶行,以及肿瘤细胞的恶性程度。
流程:
Step1:软件安装
参考(https://github.com/broadinstitute/inferCNV/wiki)
首先安装JAGS:
Linux环境下安装:conda install -c conda-forge jags
(注意:inferCNV十分吃资源,建议在服务器上运行,因此只列出Linux环境)
然后安装相应R包:
install.packages("rjags")
if (!requireNamespace("BiocManager", quietly = TRUE))
install.packages("BiocManager")
BiocManager::install("infercnv")
Step2:制作infercnv输入文件及运行
需要准备3个输入数据:
1.单细胞RNA-seq表达量的原始矩阵
2.注释文件,记录肿瘤和正常细胞
3.基因或染色体位置文件
第一个是Genes x Cells的表达矩阵(matrix),行名是基因,列名是细胞编号。
第二个是样本注释信息文件,命名为cellAnnotations.txt。一共两列,第一列是对应第一个文件的列名,第二列是细胞的分组,没有列标题。
MGH36_P6_F03 Microglia/Macrophage
MGH54_P16_F12 Oligodendrocytes (non-malignant)
MGH54_P12_C10 Oligodendrocytes (non-malignant)
MGH36_P1_B02 malignant_MGH36
MGH36_P1_H10 malignant_MGH36
第三个是基因位置信息文件,命名为geneOrderingFile.txt。一共四列,第一列对应第一个文件的行名,其余三列则是基因的位置,没有标题。注:基因名不能有重复
WASH7P chr1 14363 29806
LINC00115 chr1 761586 762902
NOC2L chr1 879584 894689
SDF4 chr1 1152288 1167411
UBE2J2 chr1 1189289 1209265
第一步,制作对象
由于笔者数据集太大,无法保存count矩阵,因此选择先抽取十分之一细胞进行cnv检测
library(Seurat)
sce = readRDS('sce.all.final.rds')#此为注释好的seurat文件
dim(sce)
sce.tmp = sce[, sample(1:ncol(sce),round(ncol(sce)/10)) ]#进行随机抽样
#此处尤其要注意需要用as.data.frame(),否则细胞名种的""-和"."会互换,导致无法与样本注释文件匹配
dat = as.data.frame(GetAssayData(sce.tmp, slot='counts' ,assay = 'RNA'))#表达矩阵
dat[1:4,1:4]
dim(dat)
groupinfo = data.frame(v1=colnames(dat),v2=Idents(sce.tmp))#样本注释文件
head(groupinfo)
#使用jimmy老师的AnnoProbe包制作染色体位置文件
library(AnnoProbe)
geneInfor=annoGene(rownames(dat),"SYMBOL",'human')
colnames(geneInfor)
geneInfor=geneInfor[with(geneInfor, order(chr, start)),c(1,4:6)]
geneInfor=geneInfor[!duplicated(geneInfor[,1]),]
head(geneInfor)
## 这里可以去除性染色体
# 也可以把染色体排序方式改变
dat=dat[rownames(dat) %in% geneInfor[,1],]
dat=dat[match( geneInfor[,1], rownames(dat) ),]
dim(dat)
expFile='expFile.txt'
write.table(dat,file = expFile,sep = '\t',quote = F)
groupFiles='groupFiles.txt'
head(groupinfo)
write.table(groupinfo,file = groupFiles,sep = '\t',quote = F,col.names = F,row.names = F)
head(geneInfor)
geneFile='geneFile.txt'
write.table(geneInfor,file = geneFile,sep = '\t',quote = F,col.names = F,row.names = F)
#至此,三个输入文件制作完成,运行infercnv
rm(list=ls())
options(stringsAsFactors = F)
library(Seurat)
library(ggplot2)
library(infercnv)
expFile='expFile.txt'
groupFiles='groupFiles.txt'
geneFile='geneFile.txt'
infercnv_obj = CreateInfercnvObject(raw_counts_matrix=expFile,
annotations_file=groupFiles,
delim="\t",
gene_order_file= geneFile,
ref_group_names=c('CD4+ T cells' ,'B cells')) ## 这个取决于自己的分组信息里面的
这一步的一个关键参数是, 用于设置参考组。假如你并不知道哪个组是正常,哪个组不正常,那么设置为ref_group_name=NULL, 那么inferCNV会以所有细胞的平均表达作为参照,这适用于有足够细胞存在差异的情况。
第二步:将作为input数据
infercnv_obj2 = infercnv::run(infercnv_obj,
cutoff=0.1, # use 1 for smart-seq, 0.1 for 10x-genomics
out_dir= './infercnv_out' , #选择输入文件夹
cluster_by_groups=T, # 选择TRUE是按样本分组 改为FALSE会进行按另一个参数k_obs_groups给出的分组数(默认为1)进行分组
hclust_method="ward.D2", plot_steps=F,num_threads = 30 ,denoise=T, HMM=F)
第二步的关键参数是,用于筛选哪些基因会用于分析,即所有细胞平均表达量的最小阈值。官方教程建议10X设置为1,Smart-seq2设置为1。则用于声明是否根据细胞注释文件的分组对肿瘤细胞进行分群。参数选择为T则会对图片进行去噪,以便更直观地判断CNV。为了给读者进行一个区分比较,笔者放denoise为T和F两种情况图片以供参考(以下两张图片非上步骤实际运行结果)
(denoise=T时去噪后结果)
(denoise=F时去噪前结果)
最终会输出很多文件在目录下,实际有用的是下面几个:
- infercnv.preliminary.png : 初步的inferCNV展示结果(未经去噪或HMM预测)
- infercnv.png : 最终inferCNV产生的去噪后的热图
- infercnv.references.txt : 正常细胞矩阵
- infercnv.observations.txt : 肿瘤细胞矩阵
- infercnv.observation_groupings.txt : 肿瘤细胞聚类后的分组关系
- infercnv.observations_dendrogram.txt : NEWICK格式,展示细胞间的层次关系
Step3:提取亚群进行infercnv预测
上述步骤只是为了确定哪些亚群中可能存在恶性细胞,不建议直接以上述抽样结果为最终结论。还需对抽样时显示为恶性细胞亚群进行细分后再进行infercnv
#提取亚群
library(Seurat)
library(ggplot2)
library(clustree)
dir.create('subset_epi')
sce = readRDS('3-cell/sce.all.final.rds')
setwd('subset_epi/')
table(Idents(sce))
cells.use = row.names([email protected])[which([email protected]$celltype=='Epithelial')]
length(cells.use)
sce = subset(sce, cells=cells.use)
sce
sce = NormalizeData(object = sce, normalization.method = "LogNormalize",
scale.factor = 1e4)
sce <- FindVariableFeatures(sce, selection.method = 'vst', nfeatures = 2000)
sce <- ScaleData(sce, vars.to.regress = "percent_mito")
sce <- RunPCA(sce, features = VariableFeatures(object = sce))
ElbowPlot(sce,ndims = 30)
sce <- FindNeighbors(sce, dims = 1:20)
sce <- FindClusters(sce, resolution = c(seq(0.1,1,0.2)))
clustree([email protected],prefix = 'RNA_snn_res.')
sce <- FindClusters(sce, resolution = 0.3 )
head(Idents(sce), 5)
table(sce$seurat_clusters)
sce <- RunUMAP(sce, dims = 1:20)
head([email protected])
p1 <- DimPlot(sce, reduction = 'umap', group.by = 'orig.ident',
label = TRUE, pt.size = 0.5)
ggsave(p1,filename = 'epi_orig.ident.png',width = 8,height = 8)
p2 <- DimPlot(sce, reduction = 'umap', group.by = 'seurat_clusters',
label = TRUE, pt.size = 0.5) + NoLegend()
ggsave(p2,filename = 'epi_clusters.png',width = 8,height = 8)
saveRDS(sce,file = "sce.epi_subset.rds")
#随后再运行Step2中的infercnv
Step4:结果解析
- 首先关于左上角的图例:(0,0.5,1,1.5,2)分别表示相对于Normal细胞的染色体区域基因表达量的倍数,红色表示该区域基因量相对增多,蓝色表示该区域基因量相对减少。柱子的长度表示对应区域的多少。
- 上半部分的热图:表示指定为Normal细胞的表达分布情况,正常情况下应该都是白色,没有明显集中的CNV区域。基因在整个染色体上从左向右排列。
- 下半部分的热图:相对于上半部分的Normal cell,计算的得到的每个tumor-like细胞的CNV图谱(即从肿瘤细胞表达数据中减去正常细胞表达数据以产生差异,其中染色体区域扩增显示为红色块,而染色体区域缺失显示为蓝色块);然后根据所有细胞的相似性进行树状图聚类。
细节
行:两个热图的行均对应于细胞
列:两个热图的列均对应于基因,按照染色体位置排序。
提取信息:inferCNV会输出一个map_metadata_from_infercnv .txt文件用于记录每个细胞的元信息,所有信息都可以从该文件中进行提取。或者使用infercnv::add_to_seurat
将信息直接增加到原来的seurat对象中。
参考:
- https://mp.weixin.qq.com/s/v9yM5q5MPUJGwecXWijexg
- https://mp.weixin.qq.com/s/Sp9bEoQZXdCgKR8iBlFYKQ