<blockquote>
<p>However, because I know the steps of TPM normalization in theory, one
should firstly normalize to gene length, and then to gene depth.</p>
</blockquote>
<p>No, you should normalize to <strong>transcript length</strong>.  Which requires you to know the relative abundance of all the transcripts so you can correct for all their lengths.</p>
<p>I do not think it's possible to un-normalize RPKM or TPM without knowing all the lengths involved in doing the calculations.</p>
<p>Let me give an example: here is RSEM output for just one gene.  Note that the software thinks there are three transcripts present for this one gene:</p>
<p>transcript_id  gene_id length  effective_length    expected_count  TPM FPKM    IsoPct</p>
<pre><code>ENST00000373020 ENSG00000000003 3768    3718.54 179.95  13.88   7.94    48.61

ENST00000494424 ENSG00000000003 820 770.54  0.00    0.00    0.00    0.00

ENST00000496771 ENSG00000000003 1025    975.54  11.94   3.51    2.01    12.29

ENST00000612152 ENSG00000000003 3796    3746.54 0.00    0.00    0.00    0.00

ENST00000614008 ENSG00000000003 900 850.54  33.11   11.17   6.39    39.10

ENST00000373031 ENSG00000000005 1205    1155.54 0.00    0.00    0.00    0.00

ENST00000485971 ENSG00000000005 542 492.54  0.00    0.00    0.00    0.00
</code></pre>
<p>So, what would you say the effective length should be for the gene level calculations, and would you get that right without having this transcript-level breakdown?</p>

CC BY-SA 4.0
2022-10-18T08:08:15.717Z
I do have the transcript lengths, as I mentioned above I got them from ensemble.
Kev
CC BY-SA 4.0
2022-10-19T04:56:17.527Z
Do you have transcript level counts?
swbarnes2
CC BY-SA 4.0
2022-10-19T07:17:46.947Z
No.. I assume this is something you get when you have BAM files? Anyway, I don't have that. I was able to get the transcript length which is necessary for the normalization. Do you think the code here provided by Michael Love is better? 

https://support.bioconductor.org/p/91218/#91256
Kev
CC BY-SA 4.0
2022-10-19T16:57:50.030Z
No, bam files do not magically give you transcript level counts.  Software like Kallisto and RSEM and Salmon do, and they do all the calculations for you.  Transcript length is not enough.  **Genes have multiple transcripts of different sizes, and you can have a mix of isoforms in your samples.**  The software I mentioned will magically handle all this for you.  I don't know that it's possible for you to do the magic in reverse.  I'm sure you can wave your hands and do some math and get numbers.  I don't know that those numbers will be accurate.
swbarnes2
CC BY-SA 4.0
2022-10-20T10:48:08.203Z
I see. According to Michael Love, as you said,  there is no way to calculate accurate TPM values out of count matrix. As I mentioned earlier I have no access to BAM files unforunatlely. But in this link I think I got my answer, they discuss this matter, and Michael Love provides here a simple code to normalize TPM out of count matrix. Thank you for your help and explenations. This is the link https://support.bioconductor.org/p/91218/#91256
Kev
CC BY-SA 4.0
2022-10-13T22:14:47.343Z
2022-10-19T17:05:18.737Z
2022-10-19T17:05:18.737Z
swbarnes2
<p>I have several RNA-seq datasets. Some of them provide RNA-seq raw counts, some provide FPKM, RPKM and some have transcripts per million (TPM) data. Non of them provide fastq files, all data is processed already. At the end I want all datasets to be normalized to TPM.</p>
<p>I'm using this code in order to normalize raw counts to TPM: (using R)</p>
<pre><code>rpkm &lt;- apply(X = subset(dataset),
                MARGIN = 2,
                FUN = function(x) {
                  10^9 * x / genelength / sum(as.numeric(x))
                })
  
TPM &lt;- apply(rpkm, 2, function(x) x / sum(as.numeric(x)) * 10^6) %&gt;% as.data.frame()
</code></pre>
<p>When RPKM is provided, and no raw counts is available, I use the second line in the same code:</p>
<pre><code>TPM &lt;- apply(rpkm, 2, function(x) x / sum(as.numeric(x)) * 10^6) %&gt;% as.data.frame()
</code></pre>
<p>And when FPKM is provided, I use this formula to transform the data to TPM:</p>
<pre><code>TPM = FPKM*X 
</code></pre>
<p>where <code>X = 1e6/[sum of all FPKM of a sample]</code></p>
<p>NOTE: <code>genelength</code> is obtained using the <code>biomart</code> package in R, to get the transcript length directly out of ensemble.</p>
<p>However, because I know the steps of TPM normalization in theory, one should firstly normalize to gene length, and then to gene depth. I'm not sure this is what the code does, feeling very skiptical about it even thought this code was given to me by a Phd student.</p>
<p>Can you guys please help me with this question? is my code right or should I alter something?</p>
<p>Thank you!</p>

CC BY-SA 4.0
2022-10-15T09:11:00.603Z
Regarding the use of TPM, it's a good idea to be aware of the issues associated with it, even if it's your only available option. There are a few different TPM questions that have been asked previously, [this answer](https://bioinformatics.stackexchange.com/a/16377/73) has a reasonable summary.
gringer
<genetics>
From RNA-seq raw counts to normalized data
# From RNA-seq raw counts to normalized data

(Asked by: username_0 on 2022-10-13)

I have several RNA-seq datasets. Some of them provide RNA-seq raw counts, some provide FPKM, RPKM and some have transcripts per million (TPM) data. Non of them provide fastq files, all data is processed already. At the end I want all datasets to be normalized to TPM.
I'm using this code in order to normalize raw counts to TPM: (using R)
rpkm <- apply(X = subset(dataset),
                MARGIN = 2,
                FUN = function(x) {
                  10^9 * x / genelength / sum(as.numeric(x))
                })
  
TPM <- apply(rpkm, 2, function(x) x / sum(as.numeric(x)) * 10^6) %>% as.data.frame()

When RPKM is provided, and no raw counts is available, I use the second line in the same code:
TPM <- apply(rpkm, 2, function(x) x / sum(as.numeric(x)) * 10^6) %>% as.data.frame()

And when FPKM is provided, I use this formula to transform the data to TPM:
TPM = FPKM*X 

where X = 1e6/[sum of all FPKM of a sample]
NOTE: genelength is obtained using the biomart package in R, to get the transcript length directly out of ensemble.
However, because I know the steps of TPM normalization in theory, one should firstly normalize to gene length, and then to gene depth. I'm not sure this is what the code does, feeling very skiptical about it even thought this code was given to me by a Phd student.
Can you guys please help me with this question? is my code right or should I alter something?
Thank you!

**Tags:** genetics
> **Comments:**
> **username_1**: Regarding the use of TPM, it's a good idea to be aware of the issues associated with it, even if it's your only available option. There are a few different TPM questions that have been asked previously, [this answer](https://bioinformatics.stackexchange.com/a/16377/73) has a reasonable summary.  

---

## 1 answers

### Answer by username_2 on 2022-10-13. Score: 2

However, because I know the steps of TPM normalization in theory, one
should firstly normalize to gene length, and then to gene depth.

No, you should normalize to transcript length.  Which requires you to know the relative abundance of all the transcripts so you can correct for all their lengths.
I do not think it's possible to un-normalize RPKM or TPM without knowing all the lengths involved in doing the calculations.
Let me give an example: here is RSEM output for just one gene.  Note that the software thinks there are three transcripts present for this one gene:
transcript_id  gene_id length  effective_length    expected_count  TPM FPKM    IsoPct
ENST00000373020 ENSG00000000003 3768    3718.54 179.95  13.88   7.94    48.61

ENST00000494424 ENSG00000000003 820 770.54  0.00    0.00    0.00    0.00

ENST00000496771 ENSG00000000003 1025    975.54  11.94   3.51    2.01    12.29

ENST00000612152 ENSG00000000003 3796    3746.54 0.00    0.00    0.00    0.00

ENST00000614008 ENSG00000000003 900 850.54  33.11   11.17   6.39    39.10

ENST00000373031 ENSG00000000005 1205    1155.54 0.00    0.00    0.00    0.00

ENST00000485971 ENSG00000000005 542 492.54  0.00    0.00    0.00    0.00

So, what would you say the effective length should be for the gene level calculations, and would you get that right without having this transcript-level breakdown?

> **Comments:**
> **username_0**: I do have the transcript lengths, as I mentioned above I got them from ensemble.  
> **username_2**: Do you have transcript level counts?  
> **username_0**: No.. I assume this is something you get when you have BAM files? Anyway, I don't have that. I was able to get the transcript length which is necessary for the normalization. Do you think the code here provided by Michael Love is better?   https://support.bioconductor.org/p/91218/#91256  
> **username_2**: No, bam files do not magically give you transcript level counts.  Software like Kallisto and RSEM and Salmon do, and they do all the calculations for you.  Transcript length is not enough.  **Genes have multiple transcripts of different sizes, and you can have a mix of isoforms in your samples.**  The software I mentioned will magically handle all this for you.  I don't know that it's possible for you to do the magic in reverse.  I'm sure you can wave your hands and do some math and get numbers.  I don't know that those numbers will be accurate.  
> **username_0**: I see. According to Michael Love, as you said,  there is no way to calculate accurate TPM values out of count matrix. As I mentioned earlier I have no access to BAM files unforunatlely. But in this link I think I got my answer, they discuss this matter, and Michael Love provides here a simple code to normalize TPM out of count matrix. Thank you for your help and explenations. This is the link https://support.bioconductor.org/p/91218/#91256  

---

