1、Quality control

原文链接Chapter 6 Quality Control

一、基础知识

1 为什么QC

因为低质量的cell通常会contribute to misleading results in downstream analyses

  • form their distinct cluster
  • distort PCA
  • cause "upregulated" genes

2 QC指标

  • 细胞测序文库:越大越好
    The library size is defined as the total sum of counts across all relevant features for each cell.
  • 非0基因数量:越多越好
    The number of expressed features in each cell is defined as the number of endogenous genes with non-zero counts for each cell.
  • ERCC含量:一般取小
    The proportion of reads mapped to spike-in transcripts is calculated relative to the total count across all features (including spike-ins) for each cell.

spike-in是已知浓度的外源RNA分子。在单细胞裂解液中加入spike-in后,再进行反转录。最广泛使用的spike-in是由External RNA Control Consortium (ERCC)提供的。ERCC含量大,则说明total sum变小

  • Mito线粒体基因含量:一般取小,意义同ERCC
    the proportion of reads mapped to genes in the mitochondrial genome

3、示例数据

#scRNAseq包的一个公共数据
library(scRNAseq)
sce.416b <- LunSpikeInData(which="416b") 
sce.416b$block <- factor(sce.416b$block)
sce.416b
dim(sce.416b) #46604个基因,192个细胞

二、QC metrics 计算

  • 如上所说主要是基于测序文库,基因数量,ERCC含量/MIto含量三个指标进行筛选。
  • 一般测序文库,基因数量可根据原始表达矩阵计算,ERCC/Mito含量则需要进行则需要根据基因名判断。利用scater包可自动计算每个细胞上述指标
  • 以mito含量为例,本例为ensemble ID。可利用AnnotationHub包获取基因的染色体信息,再进行相关含量统计。
## 注释线粒体基因
library(AnnotationHub)
ens.mm.v97 <- AnnotationHub()[["AH73905"]]
chr.loc <- mapIds(ens.mm.v97, keys=rownames(sce.416b),
                  keytype="GENEID", column="SEQNAME")
sort(table(chr.loc))
is.mito.alt <- which(chr.loc=="MT")
table(is.mito.alt)
#返回所有是线粒体基因的行名号
#biomaRt法
library("biomaRt")
ensembl = useMart("ensembl",dataset="hsapiens_gene_ensembl") #人
attributes = listAttributes(ensembl)
test <- getBM(attributes=c('ensembl_gene_id', 'chromosome_name', 'hgnc_symbol'), 
      mart = ensembl)
2-1

如果基因名为SYMBOL ID,那么我们可以直接grepl("^MT-", rownames(sce))

# 基于线粒体注释,利用scater包直接计算上述三者指标
library(scater)
df <- perCellQCMetrics(sce.416b, subsets=list(Mito=is.mito.alt))
dim(df) ##192个细胞里表达情况(包括线粒体的相关情况)
colnames(df)
df[1:4,1:4]
2-2

关于 percent_top_number,表示的是一个比例。以percent_top_50为例,表示某细胞sum数前50个gene的sum和除以该细胞的counts sum总和。

  • 上述得到的是独立的结果数据表,可以利用函数,将结果注释到sce对象的cilData slot 里
colnames(colData(sce.416b))
sce.416b <- addPerCellQC(sce.416b, subsets=list(Mito=is.mito))
colnames(colData(sce.416b))
#除Mito信息外,也还自动注释了ERCC信息

计算所有细胞的这三个及指标,就可以筛选低质量细胞了。注意筛选的前体是我们假设the QC metrics are independent of the biological state of each cell. Poor values (e.g., low library sizes, high mitochondrial proportions) are presumed to be driven by technical factors rather than biological processes, meaning that the subsequent removal of cells will not misrepresent the biology in downstream analyses.

三、鉴定低质量细胞

  • 这一步的关键是如何设置异常的指标阈值

1、fixed thresholds

即设置固定的阈值,一般通过经验判断,例如(1)library sizes below 100,000 reads;(2)express fewer than 5,000 genes;(3)have spike-in proportions above 10%; or have mitochondrial proportions above 10%.

qc.lib <- df$sum < 1e5
qc.nexprs <- df$detected < 5e3
qc.spike <- df$altexps_ERCC_percent > 10
qc.mito <- df$subsets_Mito_percent > 10
discard <- qc.lib | qc.nexprs | qc.spike | qc.mito
DataFrame(LibSize=sum(qc.lib), NExprs=sum(qc.nexprs),
    SpikeProp=sum(qc.spike), MitoProp=sum(qc.mito), Total=sum(discard))
3-1

2、adaptive thresholds

  • 即根据指标里所有细胞的分布,判断异常点isOutlier。这就假设了大部分都是高质量细胞
  • 原理:if it is more than 3 MADs from the median. 一般对log转换后的指标进行筛选
qc.lib2 <- isOutlier(df$sum, log=TRUE, type="lower")  
#lower表示取小,结果返回的是逻辑值T/F
attr(qc.lib2, "thresholds") #查看筛选阈值
qc.nexprs2 <- isOutlier(df$detected, log=TRUE, type="lower")
attr(qc.nexprs2, "thresholds")
qc.spike2 <- isOutlier(df$altexps_ERCC_percent, type="higher")
attr(qc.spike2, "thresholds")
qc.mito2 <- isOutlier(df$subsets_Mito_percent, type="higher")
attr(qc.mito2, "thresholds")
discard2 <- qc.lib2 | qc.nexprs2 | qc.spike2 | qc.mito2
#整合
DataFrame(LibSize=sum(qc.lib2), NExprs=sum(qc.nexprs2),
    SpikeProp=sum(qc.spike2), MitoProp=sum(qc.mito2), Total=sum(discard2))
3-2
  • 可利用scater提供的函数,一次完成上述计算
reasons <- quickPerCellQC(df, percent_subsets=c("subsets_Mito_percent",
    "altexps_ERCC_percent"))
#返回维度与df相同的数据框,内容变为逻辑值,即是否应该抛弃
colSums(as.matrix(reasons))
tips:batch factor

考虑批次效应可能带来的错误筛选,计算予以调整,在上面的quickPerCellQC可以设置batch参数

batch <- paste0(sce.416b$phenotype, "-", sce.416b$block)
batch.reasons <- quickPerCellQC(df, percent_subsets=c("subsets_Mito_percent",
                                                      "altexps_ERCC_percent"), batch=batch)
colSums(as.matrix(batch.reasons))
3-3

注意这里同样也假设所有的batch都是高质量的,如果已知某一个batch可能都有问题,那么就不应该调整这个batch,以免影响整体的判断。具体可分别判断每个batch的阈值,观察比较有无明显异常值。

四、绘图观察剔除细胞

1、指标细胞阈值可视化

sce.416b$phenotype <- ifelse(grepl("induced", sce.416b$phenotype),
                             "induced", "wild type")
sce.416b$discard <- reasons$discard

gridExtra::grid.arrange(
  plotColData(sce.416b, x="block", y="sum", colour_by="discard",
              other_fields="phenotype") + facet_wrap(~phenotype) + 
    scale_y_log10() + ggtitle("Total count"),
  plotColData(sce.416b, x="block", y="detected", colour_by="discard", 
              other_fields="phenotype") + facet_wrap(~phenotype) + 
    scale_y_log10() + ggtitle("Detected features"),
  plotColData(sce.416b, x="block", y="subsets_Mito_percent", 
              colour_by="discard", other_fields="phenotype") + 
    facet_wrap(~phenotype) + ggtitle("Mito percent"),
  plotColData(sce.416b, x="block", y="altexps_ERCC_percent", 
              colour_by="discard", other_fields="phenotype") + 
    facet_wrap(~phenotype) + ggtitle("ERCC percent"),
  ncol=1
)
4-1

2、线粒体基因相关性绘图

plotColData(sce.416b, x="sum", y="subsets_Mito_percent", colour_by="discard")

如图表明,剔除的细胞都是sum小,而造成mito含量相对提高的异常细胞。正常细胞是mito含量与sum成正比的。


4-2

五、去除低质量细胞

straightforward!

filtered <- sce.416b[,!reasons$discard]
最后的验证
  • whether an entire cell type is inadvertently discarded. 即被删除的细胞是否为一种特殊的细胞类型,而非低质量细胞
lost <- calculateAverage(counts(sce.416b)[,!discard])
kept <- calculateAverage(counts(sce.416b)[,discard])

library(edgeR)
logged <- cpm(cbind(lost, kept), log=TRUE, prior.count=2)
logFC <- logged[,1] - logged[,2]
abundance <- rowMeans(logged)
plot(abundance, logFC, xlab="Average count", ylab="Log-FC (lost/kept)", pch=16)
points(abundance[is.mito], logFC[is.mito], col="dodgerblue", pch=16)
  • If the discarded pool is enriched for a certain cell type, we should observe increased expression of the corresponding marker genes. 如图点均在水平轴附近,说明并非 filter out a cell type in the 416B dataset.


    5

关于empty droplets

  • 一般来说,我们拿到的数据都是过滤掉empty droplets的了。但如果看到sce对象有好几万个cell,就可能是未过滤empty droplets
  • 关于判断、过滤empty droplets,就简单介绍下相关函数,具体原理见原文
e.out <- emptyDrops(counts(sce.pbmc))
# See ?emptyDrops for an explanation of why there are NA values.
summary(e.out$FDR <= 0.001)
sce.pbmc <- sce.pbmc[,which(e.out$FDR <= 0.001)]

以上是第六章QC部分的简单流程笔记。原文还介绍了判断是否为empty droplets (第五点),以及保留低质量细胞的意义(第七点),详见Chapter 6 Quality Control
本系列笔记基于OSCA全流程的大致流程梳理,详细原理可参考原文。如有错误,恳请指正!
此外还有刘小泽老师整理的全文翻译笔记,详见目录

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,186评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,858评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 158,620评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,888评论 1 285
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,009评论 6 385
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,149评论 1 291
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,204评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,956评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,385评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,698评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,863评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,544评论 4 335
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,185评论 3 317
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,899评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,141评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,684评论 2 362
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,750评论 2 351