Unconfigured Ad

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts
  • feralBiologist
    Member
    • Jun 2011
    • 61

    The easiest/fastest way to get from BAM to TPM or RPKM

    I have already aligned all my RNA-seq samples using tophat2. I've done the differential analysis using htseq-count and edgeR. I would like to get rpkm and tpm metrics. What is the easiest way to do that using the output of tophat2, htseq-count and edgeR? I also have the reference GTF. So, please, recommend a tool or a workflow that would take me to TPKM or RPKM in less than a day - I have a machine with 32GB RAM and 8 cores and my study comprises 24 samples.
  • dpryan
    Devon Ryan
    • Jul 2011
    • 3478

    #2
    There are a couple ways to go about that. Do you need/want to include multimappers in your fpkm/rpkm numbers (it's faster not to)? Do you want to try to estimate the appropriate transcript length or just use a union gene model (the latter is faster)? If you're happy just using the unique alignments (the counts file from htseq-count) and using a single precomputed size for each gene, then you can make the calculations very quickly. Otherwise, you end up needing cufflinks or something similar and a lot of time.

    Comment

    • a_mt
      Member
      • Jul 2012
      • 34

      #3
      Hi feralBiologist,

      There's a qucik way to do it:

      1. convert your SAM/BAM to wiggle file (you can use bedtools)

      2. multiply every value in wiggle by (1,000,000/no. of reads)

      for eg: if you have 150 million reads, (1,000,000/150,000,000) would be 0.006666

      So multiply every wiggle by 0.00666 !

      Comment

      • feralBiologist
        Member
        • Jun 2011
        • 61

        #4
        Originally posted by dpryan View Post
        There are a couple ways to go about that. Do you need/want to include multimappers in your fpkm/rpkm numbers (it's faster not to)? Do you want to try to estimate the appropriate transcript length or just use a union gene model (the latter is faster)? If you're happy just using the unique alignments (the counts file from htseq-count) and using a single precomputed size for each gene, then you can make the calculations very quickly. Otherwise, you end up needing cufflinks or something similar and a lot of time.
        I could go without the multimappers and I'm happy using the union model. So in this case I could just take the htseq-count results and just divide by the gene length as contained in the GTF file?

        Comment

        • dpryan
          Devon Ryan
          • Jul 2011
          • 3478

          #5
          Yeah, so the edgeR rpkm() function from biostars would be the easiest then. You can get the gene length in R with the following script. I wrote it originally to do more than you want, so just remove the fasta and %GC specific stuff.
          Code:
          #!/usr/bin/Rscript
          library(GenomicRanges)
          library(rtracklayer)
          library(Rsamtools)
          
          GTFfile = "something.GTF"
          FASTAfile = "something.fa"
          
          #Load the annotation and reduce it
          GTF <- import.gff(GTFfile, format="gtf", genome="GRCm38.71", asRangedData=F, feature.type="exon")
          grl <- reduce(split(GTF, elementMetadata(GTF)$gene_id))
          reducedGTF <- unlist(grl, use.names=T)
          elementMetadata(reducedGTF)$gene_id <- rep(names(grl), elementLengths(grl))
          
          #Open the fasta file
          FASTA <- FaFile(FASTAfile)
          open(FASTA)
          
          #Add the GC numbers
          elementMetadata(reducedGTF)$nGCs <- letterFrequency(getSeq(FASTA, reducedGTF), "GC")[,1]
          elementMetadata(reducedGTF)$widths <- width(reducedGTF)
          
          #Create a list of the ensembl_id/GC/length
          calc_GC_length <- function(x) {
              nGCs = sum(elementMetadata(x)$nGCs)
              width = sum(elementMetadata(x)$widths)
              c(width, nGCs/width)
          }
          output <- t(sapply(split(reducedGTF, elementMetadata(reducedGTF)$gene_id), calc_GC_length))
          colnames(output) <- c("Length", "GC")
          
          write.table(output, file="GC_lengths.tsv", sep="\t")
          Change "something.GTF", obviously. You then have the lengths for rpkm() in edgeR.

          Comment

          • feralBiologist
            Member
            • Jun 2011
            • 61

            #6
            @dpryan, @a_mt: Thanks for your fast replies. I ran the code by dpryan and it works neatly!

            Comment

            • feralBiologist
              Member
              • Jun 2011
              • 61

              #7
              Just for the record, I'll link the reply of Madelaine, too: http://www.biostars.org/p/85148

              Comment

              • dpryan
                Devon Ryan
                • Jul 2011
                • 3478

                #8
                Glad to hear it worked. In the future, please try to just post on one forum and not here and biostars and the bioconductor email list. Most of the places have rules against cross-posting.

                Comment

                • westerman
                  Rick Westerman
                  • Jun 2008
                  • 1104

                  #9
                  Originally posted by dpryan View Post
                  Glad to hear it worked. In the future, please try to just post on one forum and not here and biostars and the bioconductor email list. Most of the places have rules against cross-posting.
                  Aren't the "rules" more about cross-posting within a forum? In other words don't post the same question in different threads on the same forum. I think that posting the same question to different forums/mailing lists is perfectly legitimate since there are likely to be different people reading those forums/lists.

                  Comment

                  • swbarnes2
                    Senior Member
                    • May 2008
                    • 910

                    #10
                    Originally posted by westerman View Post
                    Aren't the "rules" more about cross-posting within a forum? In other words don't post the same question in different threads on the same forum. I think that posting the same question to different forums/mailing lists is perfectly legitimate since there are likely to be different people reading those forums/lists.
                    There's a top 10 list of things not to do on forums like these floating around, and one of those suggestions is to not to post the question on two different sites.

                    Even if the readership is different, it's kind of a waste for someone there to spend the time answering the question when someone here has already given the asker what s/he wants. I think that's the reasoning.

                    Comment

                    • padmoo
                      Member
                      • Jun 2015
                      • 16

                      #11
                      Hi everyone,

                      I've been trying to get RPKM's too and I get the following error:

                      rpkm2 <- rpkm(d, gene.length=length, normalized.lib.size=TRUE, log=FALSE)
                      Warning message:
                      In y/gene.length.kb :
                      longer object length is not a multiple of shorter object length

                      I do get an output of RPKM's, so I am wondering what the error is about. Does anyone know what the problem is? Are there overlaps or something like that?

                      Comment

                      • dpryan
                        Devon Ryan
                        • Jul 2011
                        • 3478

                        #12
                        That's a warning, not an error. This is due to you giving a different number of gene lengths than there are genes in "d".

                        Comment

                        • padmoo
                          Member
                          • Jun 2015
                          • 16

                          #13
                          Yes, that was it. I didn't pay attention when I filtered out some genes in a previous step.

                          Comment

                          • super0925
                            Senior Member
                            • Feb 2014
                            • 206

                            #14
                            Originally posted by dpryan View Post
                            Yeah, so the edgeR rpkm() function from biostars would be the easiest then. You can get the gene length in R with the following script. I wrote it originally to do more than you want, so just remove the fasta and %GC specific stuff.
                            Code:
                            #!/usr/bin/Rscript
                            library(GenomicRanges)
                            library(rtracklayer)
                            library(Rsamtools)
                            
                            GTFfile = "something.GTF"
                            FASTAfile = "something.fa"
                            
                            #Load the annotation and reduce it
                            GTF <- import.gff(GTFfile, format="gtf", genome="GRCm38.71", asRangedData=F, feature.type="exon")
                            grl <- reduce(split(GTF, elementMetadata(GTF)$gene_id))
                            reducedGTF <- unlist(grl, use.names=T)
                            elementMetadata(reducedGTF)$gene_id <- rep(names(grl), elementLengths(grl))
                            
                            #Open the fasta file
                            FASTA <- FaFile(FASTAfile)
                            open(FASTA)
                            
                            #Add the GC numbers
                            elementMetadata(reducedGTF)$nGCs <- letterFrequency(getSeq(FASTA, reducedGTF), "GC")[,1]
                            elementMetadata(reducedGTF)$widths <- width(reducedGTF)
                            
                            #Create a list of the ensembl_id/GC/length
                            calc_GC_length <- function(x) {
                                nGCs = sum(elementMetadata(x)$nGCs)
                                width = sum(elementMetadata(x)$widths)
                                c(width, nGCs/width)
                            }
                            output <- t(sapply(split(reducedGTF, elementMetadata(reducedGTF)$gene_id), calc_GC_length))
                            colnames(output) <- c("Length", "GC")
                            
                            write.table(output, file="GC_lengths.tsv", sep="\t")
                            Change "something.GTF", obviously. You then have the lengths for rpkm() in edgeR.

                            Hi D

                            I found your post to calculate the gene length.
                            I have one BAM file and want to get the RPKM for each genes. I have the genes.gtf and genome.fa in the same directory.
                            For your script, I only change your command to 'GTF <- import.gff(GTFfile, format="gtf", genome="hg19", asRangedData=F, feature.type="exon")'
                            Other are same.
                            after I ran this script I got the error
                            "Error in letterFrequency(getSeq(FASTA, reducedGTF), "GC") :
                            error in evaluating the argument 'x' in selecting a method for function 'letterFrequency': Error in value[[3L]](cond) :
                            record 1666 (chr6_ssto_hap7:1871448-1871615) failed
                            file: genome.fa
                            Calls: getSeq ... tryCatch -> tryCatchList -> tryCatchOne -> <Anonymous>
                            Execution halted
                            "

                            Why?
                            Thank you!
                            Last edited by super0925; 09-10-2015, 08:45 AM.

                            Comment

                            • super0925
                              Senior Member
                              • Feb 2014
                              • 206

                              #15
                              Originally posted by a_mt View Post
                              Hi feralBiologist,

                              There's a qucik way to do it:

                              1. convert your SAM/BAM to wiggle file (you can use bedtools)

                              2. multiply every value in wiggle by (1,000,000/no. of reads)

                              for eg: if you have 150 million reads, (1,000,000/150,000,000) would be 0.006666

                              So multiply every wiggle by 0.00666 !
                              Hi a_mt Could you give me the commands? I don't know how to transfer from SAM to wiggle by bedtools.
                              I now have sample.BAM , genome.fa and genes.gtf in the same directory.
                              Thank you very much!

                              Comment

                              Latest Articles

                              Collapse

                              • SEQadmin2
                                Cancer Drug Resistance: The Lingering Barrier to Rising Survival
                                by SEQadmin2



                                Cancer survival rates have significantly increased in the last few decades in the United States, reaching a combined 70% 5-year survival rate by 2021. Behind this number, there are years of research to find new therapies, drug targets, and early detection methods. But there is one core challenge that keeps slowing down these advances, and it’s about drug resistance.

                                There is no single reason why many patients don’t respond to treatment as expected. Cancer is...
                                Today, 05:17 AM
                              • GATTACAT
                                Reply to Nine Things a Sample Prep Scientist Thinks About Before Sequencing
                                by GATTACAT
                                Love this - good data definitely starts from good input, and poor input can only give relatively poor data. I particularly like the mention of Nanodrop/absorbance based methods for quantification. It's such a toss up if you'll get an accurate reading or what amounts to a randomly generated number, and a lot of library/sequencing related issues can be traced back to poor quant.
                                07-01-2026, 11:43 AM
                              • SEQadmin2
                                Nine Things a Sample Prep Scientist Thinks About Before Sequencing
                                by SEQadmin2


                                I’m not a sequencing expert. I’m a purification scientist who uses NGS to evaluate workflows my group develops. With this perspective, we think about the sample first and the NGS workflow second. The sequencer is an exceptionally honest reporter, but it can only report on what you give it, so whether you get clean, interpretable data from an NGS workflow is largely determined before you begin.

                                Here are nine questions we think about, in roughly the order they matter, before...
                                06-18-2026, 07:11 AM

                              ad_right_rmr

                              Collapse

                              News

                              Collapse

                              Topics Statistics Last Post
                              Started by SEQadmin2, Yesterday, 11:05 AM
                              0 responses
                              7 views
                              0 reactions
                              Last Post SEQadmin2  
                              Started by SEQadmin2, 07-02-2026, 11:08 AM
                              0 responses
                              28 views
                              0 reactions
                              Last Post SEQadmin2  
                              Started by SEQadmin2, 06-30-2026, 05:37 AM
                              0 responses
                              28 views
                              0 reactions
                              Last Post SEQadmin2  
                              Started by SEQadmin2, 06-26-2026, 11:10 AM
                              0 responses
                              27 views
                              0 reactions
                              Last Post SEQadmin2  
                              Working...