BRGenomics包括用于spike-in规范化的实用程序。

一种典型的方法是在文库制备之前添加spike-in(外源细胞或合成寡核苷酸),然后将其映射到A结合基因组包含目标生物体染色体(以映射实验读数)以及用于插入的序列/染色体。

这种所谓的“竞争性对齐”会导致创建包含染色体混合的BAM文件,因此应该很容易识别插入的染色体。

1计算插入读数

库(BRGenomics)

对于本节,我们将使用包含正常染色体和插入染色体的4个虚拟数据集的列表。考虑前2个数据集:

grl [1:2]
## seqnames ranges strand | score ##    |  ## [1] chr1 1 + | 1 ## [2] chr2 2 + | 1 ## [3] spikechr1 3 + | 1 ## [4] spikechr2 4 + | 1 ## ------- # seqinfo: 4个序列来自一个未指定的基因组;## seqnames ranges strand | score ##    |  ## [1] chr1 1 + | 2 ## [2] chr2 2 + | 2 ## [3] spikechr1 3 + | 1 ## [4] spikechr2 4 + | 1 ## ------- ## seqinfo: 4个序列来自一个未指定的基因组;没有seqlengths

我们可以通过全名或匹配尖峰染色体的正则表达式来识别尖峰染色体。在这种情况下,我们将我们的spike- In染色体命名为包含字符串“spike”,这使它们易于识别。

计算每个数据集的读取次数:

getSpikeInCounts(grl, si_pattern = "spike", ncores = 1)
## sample total_reads exp_reads spike_reads ## 1 gr1_rep1 4 2 2 ## 2 gr2_rep1 6 4 2 ## 3 gr1_rep2 5 2 3 ## 4 gr2_rep2 12 8 4

2过滤插入读取

我们还可以从数据中删除插入读取:

removeSpikeInReads(grl[1:2], si_pattern = "spike", ncores = 1)
## seqnames ranges strand | score ##    |  ## [1] chr1 1 + | 1 ## [2] chr2 2 + | 1 ## ------- ## seqinfo:来自未指定基因组的2个序列;## seqnames ranges strand | score ##    |  ## [1] chr1 1 + | 2 ## [2] chr2 2 + | 2 ## ------- ## seqinfo:来自未指定基因组的2个序列;没有seqlengths

如果我们想要分离尖峰读取,有一个类似的方法getSpikeInReads ()函数。

3.峰值归一化因子

有几种生成峰值归一化因子的方法,但我们提倡使用一种特定的方法,它生成我们称之为单元的单元年代幅度归一化R欧洲航空防务与航天公司P数以百万计的映射读数为负C控制(SRPMC).给定样本的SRPMC归一化因子我\ \ ()定义如下:

\[SRPMC:\ NF_i = \frac{\sum reads_{spikein, control}}{\sum reads_{spikein, i}} \cdot \frac{10^6}{\sum reads_{experimental, control}}\]

这个表达式有效地计算负对照和所有其他样本的Reads Per Million (RPM)归一化我\ \ ()根据其插入读数的比例缩放为等效单位。我们在下面提供一个更显式的推导。

3.1SRPMC的推导

峰值归一化的基本概念是,实验读数与峰值读数的比值可用于校正起始物质的全局变化。我们称之为比率R欧洲航空防务与航天公司P年代输入读取(石头剪刀):

\[RPS = \frac{\sum reads_{experimental}}{\sum reads_{spikein}}\]

单独来看,这一数字仅反映了回收和映射的峰值物质的相对数量。有关材料变化的有意义的信息只能从样品之间的直接比较中获得。对于任何样本,我\ \ (),我们可以计算信号的整体变化作为从负控制中恢复的材料的比例:

\ [RelativeSignal_i = \压裂{RPS_i} {RPS_{控制}}\]

spike-in归一化的通常目的是测量样品之间总物质(例如RNA)的生物学差异,而上述比率是对这一差异的直接测量。

为了生成归一化因子,我们使用上述比率来调整RPM (Reads Per Million mapped Reads)归一化因子,为了清晰起见,我们将其定义如下:

\ [RPM: \ NF_i = \压裂{1}{\压裂{\ {reads_i}}和{10 ^ 6}}= \压裂{10 ^ 6}{\和{reads_i}} \]

(除非表示,\(读取\)指非插入式读取)。

RPM归一化(即读深度归一化)是最简单、可能也是最常见的归一化形式。对于一个基础的(未受干扰的)阴性对照,RPM应该产生最可移植的信号度量,因为我们打算让阴性对照显示典型的生理学,并且我们希望这种状态是可重复的。因此,我们希望在负控制中有以RPM为单位的归一化信号。

为了实现这一点,我们将样本之间的插入标准化读取的比率相乘我\ \ ()样本的RPM归一化因子为阴性对照我\ \ ().这将读数计数转换为我们总结为的单位年代幅度归一化R欧洲航空防务与航天公司P数以百万计的映射读数为负C控制(SRPMC):

\ [SRPMC: \ NF_i = \压裂{RPS_i} {RPS_{控制}}\ cdot \压裂{10 ^ 6}{\和{reads_i}} \]

同样,SRPMC导致阴性对照被RPM(测序深度)归一化,而所有其他样本都是等效的,直接可比较的单位。我们已经有效地确定了这些样本的相对比例基于刺入读取的比率。

如果我们代入\ (RPS \)上面的变量。\ (\ {reads_i} \总和)消去,将分数化简得到原来的公式:

\[SRPMC:\ NF_i = \frac{\sum reads_{spikein, control}}{\sum reads_{spikein, i}} \cdot \frac{10^6}{\sum reads_{experimental, control}}\]

4计算归一化因子

我们可以计算每个样本的SRPMC归一化因子getSpikeInNFs ()函数,使用与计算插入读取数相同的语法。

然而,我们还必须确定阴性对照,这是将具有“参考”(RPM)归一化的样本。我们可以使用正则表达式(ctrl_pattern参数)或通过提供负控件的名称ctrl_names参数)。

默认方法是“SRPMC”,但也有其他选项。

getSpikeInNFs(grl, si_pattern = "spike", ctrl_pattern = "gr1", ncores = 1)
## [1] 500000 500000 500000 375000

(NFs值很高,因为我们的虚拟数据只包含少量读取)。

默认情况下,使用归一化因子批正常化,以便在任何复制中(由示例名称中“rep”后面的字符标识),负控制是RPM规范化的,而其他条件则被规范化为复制内的负控制(详细信息请参阅文档)。

目前,批处理规范化要求样例名称以匹配格式的字符串结尾“_rep1”“_rep2”等。如果示例名称不符合此模式,则可以使用sample_names论点。

5规范数据

我们也可以用spikeInNormGRanges ()函数同时查找尖峰读入,计算尖峰归一化因子,过滤尖峰读入,并归一化读计数:

spikeInNormGRanges(grl, si_pattern = "spike", ctrl_pattern = "gr1", ncores = 1)
## seqnames ranges strand | score ##    |  ## [1] chr1 1 + | 5e+05 ## [2] chr2 2 + | 5e+05 ## ------- ## seqinfo: 2个来自未指定基因组的序列;## seqnames ranges strand | score ##    |  ## [1] chr1 1 + | 1e+06 ## [2] chr2 2 + | 1e+06 ## ------- # seqinfo: 2个序列来自一个未指定的基因组;## seqnames ranges strand | score ##    |  ## [1] chr1 1 + | 5e+05 ## [2] chr2 2 + | 5e+05 ## ------- # seqinfo: 2个序列来自一个未指定的基因组;## seqnames ranges strand | score ##    |  ## [1] chr1 1 + | 1500000 ## [2] chr2 2 + | 1500000 ## ------- ## seqinfo: 2个序列来自一个未指定的基因组;没有seqlengths

6子抽样归一化

6.1基本原理

当在基因组浏览器中查看基因组数据(或以其他方式绘制单个基因的信号)时,碱基对分辨率数据的稀疏性可能会挑战我们的视觉感知。

考虑两个来自相同样本的数据集,但其中一个测序深度更高。这两个数据集可以归一化,使信号计数相等,但具有更高测序深度的数据集还将发现额外的位点。当在基因组浏览器中绘制时,一个区域内的总信号可能是相同的,但更高测序的数据集将覆盖更多的位置,但具有更低的峰值,而较低测序的数据集相比之下将看起来稀疏和尖峰。

下面,我们比较来自同一数据集的同一基因的PRO-seq数据。在一种情况下,我们随机采样该基因的一半读数,而在另一种情况下,我们将所有读数计数除以2。

数据(“PROseq”)的数据(“txs_dm6_chr4”)
# select a single gene gene_i <- txs_dm6_chr4[185]。gene_i <- subsetByOverlaps(PROseq, gene_i) #采样一半的原始读取set.seed(11) sreads。gene_i <- subsampleGRanges(读取。Gene_i, prop = 0.5, ncores = 1) # downscale raw reads by factor 2 score(reads. Gene_i) <- 0.5 * score(reads. Gene_i)
Sum (score(reads.gene_i)) ## [1] 738.5 Sum (score(sreads.gene_i)) ## [1] 738
plot(x = 1:width(gene_i), y = getCountsByPositions(sreads. bypositions)gene_i, gene_i), type = "h", ylim = c(0,20), main = "PRO-seq(向下采样)",xlab = "距离TSS", ylab = "向下采样PRO-seq读取")

plot(x = 1:width(gene_i), y = getCountsByPositions(读取。gene_i, gene_i), type = "h", ylim = c(0,20), main = "PRO-seq(缩小)",xlab = "距离TSS", ylab = "缩小PRO-seq读取")

上面的两个图来自相同的数据,包含相同数量的信号,但它们的轮廓明显不同。特别是当在基因组浏览器中绘制大区域的许多样本时,由测序深度引起的差异可能会产生误导。如果一些数据集“高而尖”,而另一些数据集“短而平滑”,估计差异可能具有挑战性。

在信号没有全局变化的情况下,上述情况可以通过等测序深度或下采样来匹配读数来预先解决。

然而,当需要考虑总信号中显著的生物变化时,匹配原始读数计数并不是解决方案。

例如,考虑一个例子,在两个样本之间有一个真实的,两倍的生物转录差异。如果我们能够避免所有的技术干扰,直接测量每个细胞的转录,我们将有望在较低的条件下发现一半的转录复合物。在这两种情况下获得等效的测序深度实际上是一种技术上的人工产物,通过乘法降低信号的比例可能会导致上述观察到的视觉挑战。

6.2归一化子采样

为了解决上述问题,我们包含了一个函数subsampleBySpikeIn ()随机采样读取,以匹配数据集之间的标准化信号比例。

函数在内部使用getSpikeInNFs ()函数,但不是SRPMC规范化,而是使用选项method = "SNR",该算法计算将每个数据集缩小的归一化因子,以匹配具有最少插入读取的数据集。由此,为每个数据集建立“期望读取”的数量,随后对该读取数量进行随机采样。

removeSpikeInReads(grl, si_pattern = "spike", ncores = 1)
## seqnames ranges strand | score ##    |  ## [1] chr1 1 + | 1 ## [2] chr2 2 + | 1 ## ------- ## seqinfo:来自未指定基因组的2个序列;## seqnames ranges strand | score ##    |  ## [1] chr1 1 + | 2 ## [2] chr2 2 + | 2 ## ------- ## seqinfo:来自未指定基因组的2个序列;## seqnames ranges strand | score ##    |  ## [1] chr1 1 + | 1 ## [2] chr2 2 + | 1 ## ------- ## seqinfo:来自未指定基因组的2个序列;## seqnames ranges strand | score ##    |  ## [1] chr1 1 + | 4 ## [2] chr2 2 + | 4 ## ------- ## seqinfo:来自未指定基因组的2个序列;没有seqlengths
getSpikeInNFs(grl, si_pattern = "spike", method = "SNR", batch_norm = FALSE, ncores = 1)
## [1] 1.0000000 1.0000000 0.6666667 0.5000000
subsampleBySpikeIn(grl, si_pattern = "spike", batch_norm = FALSE, ncores = 1)
## seqnames ranges strand | score ##    |  ## [1] chr1 1 + | 1 ## [2] chr2 2 + | 1 ## ------- ## seqinfo:来自未指定基因组的2个序列;## seqnames ranges strand | score ##    |  ## [1] chr1 1 + | 2 ## [2] chr2 2 + | 2 ## ------- ## seqinfo:来自未指定基因组的2个序列;## seqnames ranges strand | score ##    |  ## [1] chr1 1 + | 1 ## ------- ## seqinfo: 2个序列来自一个未指定的基因组;## seqnames ranges strand | score ##    |  ## [1] chr1 1 + | 1 ## [2] chr2 2 + | 3 ## ------- ## seqinfo:来自未指定基因组的2个序列;没有seqlengths

通过子抽样的标准化牺牲了信息,以减少数据集之间的偏差。