InferCNV是broad出品的一款对单细胞转录组测序数据推断CNV的工具包。这里我们对其自带的数据运行该工具包看一下效果。
首先需要准备3个输入文件, 我们来看一下其自带的三个文件:
- 基因表达矩阵,每一行为基因,每一列为细胞。
dat=read.table(gzfile(system.file("extdata", "oligodendroglioma_expression_downsampled.counts.matrix.gz", package = "infercnv"),'rt'),header=T,check.names = F)
head(dat[,1:6])
MGH54_P16_F12 MGH54_P12_C10 MGH54_P11_C11 MGH54_P15_D06 MGH54_P16_A03 MGH53_P7_B09
A2M 0 0.0000 0.000 0.00000 0.0000 0
A4GALT 0 0.0000 0.000 0.00000 0.0000 0
AAAS 0 37.0080 30.935 21.01100 0.0000 0
AACS 0 0.0000 0.000 0.00000 1.8049 0
AADAT 0 0.0000 0.000 0.00000 0.0000 0
AAGAB 0 3.8928 0.000 0.20744 8.8162 0
- 细胞注释文件包括两列,第一列为细胞名称,第二列为其细胞类型。
anno = read.table(gzfile(system.file("extdata", "oligodendroglioma_annotations_downsampled.txt", package = "infercnv")), header=F, sep='\t', check.names = F)
head(anno)
V1 V2
1 MGH54_P2_C12 Microglia/Macrophage
2 MGH36_P6_F03 Microglia/Macrophage
3 MGH53_P4_H08 Microglia/Macrophage
4 MGH53_P2_E09 Microglia/Macrophage
5 MGH36_P5_E12 Microglia/Macrophage
6 MGH54_P2_H07 Microglia/Macrophage
- 基因坐标文件,是每个基因在基因组上位置的注释。
gene_order = read.table(system.file("extdata", "gencode_downsampled.EXAMPLE_ONLY_DONT_REUSE.txt", package = "infercnv"))
head(gene_order)
V1 V2 V3 V4
1 WASH7P chr1 14363 29806
2 LINC00115 chr1 761586 762902
3 NOC2L chr1 879584 894689
4 MIR200A chr1 1103243 1103332
5 SDF4 chr1 1152288 1167411
6 UBE2J2 chr1 1189289 1209265
其运行分两步,首先建立一个inferCNV对象:
dir.create("./test_example")
infercnv_obj = CreateInfercnvObject(raw_counts_matrix=system.file("extdata", "oligodendroglioma_expression_downsampled.counts.matrix.gz", package = "infercnv"),
annotations_file=system.file("extdata", "oligodendroglioma_annotations_downsampled.txt", package = "infercnv"),
delim="\t",
gene_order_file=system.file("extdata", "gencode_downsampled.EXAMPLE_ONLY_DONT_REUSE.txt", package = "infercnv"),
ref_group_names=c("Microglia/Macrophage","Oligodendrocytes (non-malignant)"))
然后就可以运行啦。这里需要注意的是由于软件自带的单细胞表达矩阵是smart-seq2的结果,所以需要设定cutoff为1, 如果是10X结果需要设定cutoff为0.1。
infercnv_obj = infercnv::run(infercnv_obj,
cutoff=1, # cutoff=1 works well for Smart-seq2, and cutoff=0.1 works well for 10x Genomics
out_dir="./test_example",
cluster_by_groups=TRUE,
denoise=TRUE,
HMM=FALSE,
no_prelim_plot = T,
png_res = 300)
自带数据运行的很快,所有中间和最终结果都保存在我们设定的文件夹test_example下。
首先CNV heatmap如下图,可以看到上半部分是对照组细胞,基本没有CNV event。下半部分是肿瘤细胞(Oligodendroglioma),可以看到其特有的Chr1p及Chr19q缺失。同时由于我们设定了cluster_by_groups=TRUE,我们还可以看到每个样本有自己特有的copy number event。
接下来我们用infercnv.observations.txt来计算每个细胞的CNV score。这里我们根据经验设置一系列的threshold来判断对于每个基因其copy number是不变(Neutral),减少(Copy loss)或增多(Copy gain)。Copy neutral 其score为0,Copy loss和Copy gain都认为是有event, 其score不为0。这里简单粗暴的分了五类,具体如何更好的计算score其实大家可以集思广益,比如建立经验cdf等等。这里我们画了个线箱图如下所示。可以看到Cluster1里细胞的CNV score明显高于其他三组,对应回之前的heatmap(颜色相对应),可以看到确实第一组细胞的CNV event比较多,其次是第四组。
# get groupings
grp <- read.table("test_example/infercnv.observation_groupings.txt", sep=' ', header=T)
# calculate score
obs <- read.table("test_example/infercnv.observations.txt", header=T, check.names = F)
obs[obs > 0 & obs < 0.3] <- 2 #complete loss. 2pts
obs[obs >= 0.3 & obs < 0.7] <- 1 #loss of one copy. 1pts
obs[obs >= 0.7 & obs < 1.3] <- 0 #Neutral. 0pts
obs[obs >= 1.3 & obs <= 1.5] <- 1 #addition of one copy. 1pts
obs[obs > 1.5 & obs <= 2] <- 2 #addition of two copies. 2pts
obs[obs > 2] <- 2 #addition of more than two copies. 2pts
scores <- as.data.frame(colSums(obs))
scores$cluster <- grp$Annotation.Group
colnames(scores) <- c("score", "cluster")
ggplot(scores, aes(x=cluster, y=score, fill=factor(cluster)))+
geom_boxplot(outlier.shape = NA)+
scale_fill_manual(values=c("#8DD3C7", "#A9A0B2", "#F0D1E1", "#FFED6F"))+
labs(fill = "Cluster")
https://github.com/broadinstitute/inferCNV/wiki
https://www.ncbi.nlm.nih.gov/pmc/articles/PMC4123637/