计算基因表达量TPM(Transcripts Per Million)值的经典步骤 gene_lengths(基因长度)是计算基因表达量时的一个关键参数

背景知识

gene_lengths(基因长度)是计算基因表达量时的一个关键参数,主要用于消除因基因本身长短不同而对定量结果造成的影响,让不同基因的表达水平更具可比性。

下面的表格能帮你快速理解它的核心定义和常见计算方法:

核心定义 为什么需要它? 最常见的计算方法

指一个基因的有效转录区域的总长度,通常以碱基对为单位。 在RNA-seq中,更长的基因在随机打断和测序过程中,会有更多片段来自该基因,导致其原始读数更高。直接比较不同基因的counts会误以为长基因表达量更高。 非冗余外显子长度之和:将一个基因的所有外显子(exon)合并,去除重叠部分后计算总长度。

💡 基因长度的不同计算方式

在实际分析中,根据研究目的的不同,"基因长度"有几种常见的定义和计算方法:

  1. 非冗余外显子长度之和:这是最常用和推荐的方法。它计算的是一个基因所有外显子(即编码区和非编码区)合并后的总长度,能最准确地代表该基因转录本的潜在长度。
  2. 非冗余CDS长度之和:只计算编码蛋白的外显子(CDS区)的总长度。如果你特别关注蛋白质的编码潜力,这种方法可能更合适。
  3. 最长转录本长度:对于有多个可变转录本的基因,选择其最长的那个转录本的长度作为该基因的代表长度。
  4. 多个转录本长度的平均值:计算一个基因所有转录本长度的平均值,作为一种折中的方案。

🧬 如何获取基因长度

通常,我们需要从基因注释文件中提取基因长度信息。使用R语言的 GenomicFeatures 包可以方便地完成这项工作。基本步骤如下:

加载必要的包

library(GenomicFeatures)

从GTF或GFF文件创建转录组数据库

txdb <- makeTxDbFromGFF(“your_annotation_file.gtf”, format=“gtf”)

按基因提取所有外显子,并计算每个基因的非冗余外显子总长度

exons_per_gene <- exonsBy(txdb, by = “gene”)
gene_lengths <- sum(width(reduce(exons_per_gene)))

转换为数据框,方便使用

gene_lengths_df <- data.frame(
gene_id = names(gene_lengths),
length = as.numeric(gene_lengths)
)

💻 在表达量标准化中的应用

基因长度最主要的应用场景就是将原始读数转换为TPM或FPKM/RPKM这类标准化表达量。以你之前遇到的TPM计算代码为例:

计算RPK (Reads Per Kilobase):先对基因长度进行校正

rpk <- count_mat / (gene_lengths / 1000)

计算TPM:再对测序深度进行校正

tpm <- t( t(rpk) / colSums(rpk) ) * 1e6

• 第一步:rpk <- count_mat / (gene_lengths / 1000)。这一步的目的是消除基因长度的影响。将每个基因的原始读数除以其长度(以千碱基为单位),得到"每千碱基的读数"。这样,长基因和短基因就站在了同一起跑线上。

• 第二步:tpm <- t( t(rpk) / colSums(rpk) ) * 1e6。这一步的目的是消除样本间总测序深度(即总读数)的差异。将每个基因的RPK除以该样本所有基因RPK的总和,再乘以100万,得到"每百万转录本数"。这使得每个样本的TPM总和都是100万,便于跨样本比较。

⚠️ 注意事项

• 确保顺序一致:在计算时,务必确保gene_lengths向量中的基因顺序与表达量矩阵中的行名完全一致。

• 使用有效长度:更精确的计算会使用"有效长度",它会考虑测序片段的长度分布,但通常情况下用上述总外显子长度已足够。

• 注释文件版本:不同来源或版本的注释文件(如UCSC, Ensembl, GENCODE)计算的基因长度可能会有细微差异。

希望这些解释能帮助你更好地理解gene_lengths这个概念及其在数据分析中的重要性!

sample_counts <- rowSums(count_mat)          # 总 counts
gene_lengths  # 如果你有序列长度向量
tpm <- t( t(count_mat) / gene_lengths )      # 每长度
tpm <- tpm / colSums(tpm) * 1e6              # 百万标准化
sample_tpm <- rowMeans(tpm) 

计算基因表达量TPM(Transcripts Per Million)值的经典步骤

。下面我为你详细解释每一步的意图、背后的原理,并提供一些注意事项。

📌 TPM计算原理与步骤分解

首先,TPM的计算目标是对基因的表达量进行标准化,使其既考虑不同样本之间的测序深度差异,也考虑基因本身长度差异,从而使得不同基因在不同样本间的表达量具有可比性。

下面的表格清晰地展示了整个计算流程和每一步的核心目的:

步骤 代码 目的解释 数学含义

  1. 计算总Counts sample_counts <- rowSums(count_mat) 计算每个基因在所有样本中的原始读数(Counts)之和。这通常用于观察基因的整体表达水平,但并非TPM计算的必需步骤。 对每行(每个基因)求和

  2. 长度校正 tpm <- t( t(count_mat) / gene_lengths ) 核心步骤1:消除基因长度对表达量的影响。将每个基因的Counts除以其有效长度(例如,非冗余外显子长度之和),得到“每碱基的读数”。 Counts(i,s) / Length(i)

  3. 样本标准化 tpm <- tpm / colSums(tpm) * 1e6 核心步骤2:消除样本间测序深度差异。将每个样本经过长度校正后的值,除以该样本所有基因校正值之和,再乘以100万。使得每个样本的TPM总和为100万。 [Counts(i,s)/Length(i)] / [Σ(Counts(j,s)/Length(j))] * 10^6

  4. 计算平均表达 sample_tpm <- rowMeans(tpm) 后续分析:计算每个基因在多个样本中的平均TPM值,用于比较基因间的相对表达水平。 对每行(每个基因)求均值

💡 关键细节与注意事项

在实际操作中,以下几个细节对结果的准确性至关重要:

  1. 基因长度向量 gene_lengths:这是计算中的关键输入。它的长度必须与 count_mat 矩阵的行数(基因数量)完全一致,并且顺序要一一对应。你需要一个包含每个基因有效长度的向量,其获取方式可以是:
    ◦ 使用 Bioconductor 的注释包(如 TxDb.Hsapiens.UCSC.hg19.knownGene),通过计算非冗余外显子长度之和或最长转录本长度来获得。

    ◦ 使用 biomaRt 包 从 Ensembl 数据库在线查询获取。

  2. 矩阵转置操作 t( ):步骤2中的双重转置 t( t(count_mat) / gene_lengths ) 是一个巧妙的技巧。因为R语言中矩阵除以向量的操作是按列进行的。我们的目标是对每一行(每个基因)的Counts除以其对应的长度,所以需要先转置矩阵,让“基因”变成列,进行按列除法后,再转置回来恢复原始维度。

  3. TPM与FPKM/RPKM的区别:TPM和FPKM都是经过长度和测序深度校正的单位,但它们的标准化思路有细微, 但至关重要的差别:
    ◦ FPKM 是先对长度做校正,然后对测序深度做校正。

    ◦ TPM 是先对长度做校正,然后对校正后的总值进行标准化。

    ◦ 结果就是,一个样本中所有基因的TPM值总和始终为100万,这使得TPM在不同样本间的比较更为直观和稳定。因此,TPM现在被更广泛地推荐使用。

🛠️ 主要应用场景

TPM值标准化后,主要用于:
• 比较同一样本内不同基因的表达水平:例如,找出哪个基因在某个细胞或组织里表达最高。

• 比较不同样本间同一基因的表达水平:例如,观察某个基因在疾病组和对照组中的表达差异。

希望这份详细的解释能帮助你透彻理解TPM的计算过程!如果你对获取基因长度或代码实现还有其他疑问,可以随时再问我。

t(t(rpk) / colSums(rpk)) * 1e6 这一行“两次转置”的目的只有一句话:

让 R 把“每个基因在该细胞里的占比”按 方向做向量除法,而 R 的 / 默认是 列-wise 操作。


1. 先看清维度

假设

  • rpk:基因 × 细胞 矩阵,维度 G × C
               cell1  cell2  cell3
geneA            10     20     30
geneB            40     50     60
geneC            70     80     90

2. 我们想干什么?

TPM 第 2 步:
把每个细胞内部所有基因的 RPK 加总 → 得到该细胞的 library size(以 RPK 为单位),然后把该细胞里每个基因的 RPK 除以这个总和,再乘 1e6。

也就是

TPM_gc = RPK_gc / (sum_g RPK_g,c) * 1e6

按列做除法


3. R 的 / 规则

  • 如果 x 是矩阵,y 是向量,那么
    x / y 会把 y 的每个元素对应到 x 的每一列 去做除法(column-wise)。
    维度必须 length(y) == ncol(x)

但我们现在的矩阵是 G × C,而 colSums(rpk) 长度 = C。
直接写 rpk / colSums(rpk) 会把“每列”除以对应的 colSums,正好是我们想要的列方向除法!


4. 那为什么还要两次转置?

历史原因 / 防呆写法 / 早期代码 copy-paste 习惯。

  • 早期有人担心“如果矩阵是 细胞 × 基因 呢?”
    t(rpk) 变成 C × G,此时 colSums() 长度 = G,再 / 就是按基因方向除,不符合 TPM 定义
    于是再 t() 回来,确保最终维度还是 G × C

  • 另一种场景:
    如果你手里拿到的是 细胞 × 基因 矩阵,那么

    t(t(rpk) / colSums(rpk))
    

    就是“先转置成基因×细胞,按列除,再转置回细胞×基因”——通用模板,不管原始维度怎样,写完一定对


5. 现代写法(更直观)

只要你能 100% 确定 rpk基因 × 细胞,可以直接:

tpm <- rpk / colSums(rpk) * 1e6

一次转置都不需要,结果完全一样


一句话总结

  • 两次转置 = 通用模板,不管矩阵是“基因×细胞”还是“细胞×基因”都能按 完成 TPM 归一化。
  • 如果你已明确维度是 基因×细胞t(t(...)) 完全可以省掉,直接 rpk / colSums(rpk) * 1e6 即可。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值