In this exercise, we will analyze RNA-seq data to measure changes in gene expression levels between wild-type and a mutant strain of the bacterium Listeria monocytogenes.
- Review mapping reads with an example of how to use qsub to map many data sets in parallel on TACC.
- Review samtools and SAM/BAM conversion.
- Learn how to use bedtools/HTseq to count reads overlapping genes.
- Become familiar with basic R usage and installing BioConductor modules.
- Learn how to use edgeR/DESeq to identify differentially expressed genes.
Table of Contents
Download data files
Copy the data files for this example into your $SCRATCH space:
Single-end Illumina 36-bp reads
wild-type, biological replicate 1
Single-end Illumina 36-bp reads
?sigB mutant, biological replicate 1
Single-end Illumina 36-bp reads
wild-type, biological replicate 2
Single-end Illumina 36-bp reads
?sigB mutant, biological replicate 2
Reference Genome sequence (FASTA)
Listeria monocytogenes strain 10403S
Reference Genome features (GFF)
Listeria monocytogenes strain 10403S
This data was submitted to the Sequence Read Archive (SRA) to accompany this paper:
- Oliver, H.F., et al. (2009) Deep RNA sequencing of L. monocytogenes reveals overlapping and extensive stationary phase and sigma B-dependent transcriptomes, including multiple highly transcribed noncoding RNAs. BMC Genomics 10:641. Pubmed
You can view the data in the ENA SRA here: http://www.ebi.ac.uk/ena/data/view/SRP001753
If you want to skip the read alignment step...
To get right to the new stuff, you can copy the mapped read BAM files and the reference sequence files that you will need using these commands:
Then, skip over the #Create BAM file of mapped reads section below.
Using the R environment for statistical computing
Many of the modules for doing statistical tests on NGS data have been written in the "R" language for statistical computing. If you're not familiar with R, then this section is probably going to be a bit confusing. (You might be thinking "Stop with the new languages already guys! Uncle!") To orient you, we are going to run the R command, which launches the R shell inside our terminal. Like the bash shell that we normally use, the R shell interprets commands, but now they are R commands rather than bash commands. The prompt changes from
> when you are in the R shell, to help clue you in to this fact. The R shell is inside the bash shell. So when you quit R, you will be back where you were in the bash shell.
R is the favorite language of pirates.
R is a very common scripting language used in statistics. There are whole courses on using R going on in other SSI classrooms as we speak! Inside the R universe, you have access to an incredibly large number of useful statistical functions (Fisher's exact test, nonlinear least-squares fitting, ANOVA ...). R also has advanced functionality for producing plots and graphs as output. We'll take advantage of all of this here. You are well on your way to becoming denizens of the polyglot bioinformatics community now.
R is a bit of it's own bizarro world, as far as how its commands work. (Futhermore, Googling "R" to get help can be very frustrating.) The conventions of most other programming and scripting languages seem to have been re-invented by someone who wanted to do everything their own way in R. Just like we wrote shell scripts in
bash, you can write
R scripts that carry out complicated analyses.
Do not copy the > characters in the R examples.
They are the R prompt to remind you which commands are to be run inside the R shell!
Hints for working with R
- Don't forget: it's
- For help, type
qkey gets you out of help, just like for a
- The left arrow
<-(less-than-dash) is the same as an equals sign
=. You can use them interchangeably.
- The prompt we will sometimes be showing for R is
>. Don't type this for a command. It is like the
login1$at the beginning of the bash prompt when you log in to Lonestar. It just means that you are in the
- You can type the name of a variable to have its value displayed. Like this...
Bioconductor modules for R
Like other languages, R can be expanded by loading modules. The R equivalent of Bioperl or Biopython is Bioconductor. Bioconductor can theoretically do things for you like convert sequences (none of us use it for that), but where it really shines is in doing statistical tests (where is it second-to-none in this list of languages). Many functions for analyzing microarray data are implemented in R, and this strength has now carried over to the analysis of RNAseq data.
Here's how you install two modules that we will need for this exercise:
The install commands may take several minutes to complete. You can read ahead while they run or even open a new terminal window and connect it to Lonestar and continue onward in the tutorial as you wait for R.
When you start R later, you will not need to re-install the modules. You can load them with just these commands:
These commands will work for any Bioconductor module!
Create BAM file of mapped reads
Map reads using Bowtie
For RNA-seq analysis we're mainly counting the reads that align well, so we choose to use bowtie. (You could also use BWA or many other mappers.)
We've done this several times before, so you should be able to come up with the full command lines if you refer back to the original lesson.
Be careful we are now mapping single-end reads, so you may have to look at the bowtie help to figure out how to do that!
You will need to first build the index file, just once and in "interactive mode" is fine (it's fast, so you don't need an idev shell). Then, you will need to submit a
commands file with four lines to the TACC queue using qsub.
Please give the final output files the names:
bowtie-build once then
bowtie for each separate sample.
Now create a
bowtie_commands file that looks like this using nano or another text editor:
Remember that there are 12 processors per node on Lonestar, so we choose to use 3 for each of the 4 jobs with the
-p 3 option.
Create the launcher script and run it:
Remember that you cannot qsub from within an idev shell!
Convert Bowtie output to BAM
Create a new
samtools_commands file so that you convert all of these files from SAM to sorted and indexed BAM all at one time by using qsub.
Linux expert tip: you can string together commands all on one line, so that they are sent to the same core one after another by separating them on the line with
Note the use of the variable $FILE, by which we set a variable's value int he first part of the line and use it over and over in the latter part of the line. This is a mini use of shell scripting.
Create a new launcher script and submit this new job to the queue. Be sure you have samtools loaded as the node that your job launches on will inherit your current environment, including whatever modules you have loaded:
- Is this a strand-specific RNA-seq library? Try using IGV to view some of the BAM file data and examine the reads mapped to each gene.
Count reads mapping to genes
bedtools is a great utility for working with sequence features and mapped reads in BAM, BED, VCF, and GFF formats.
We are going to use it to count the number of reads that map to each gene in the genome. Load the module and check out the help for bedtools and the multicov specific command that we are going to use:
The multicov command takes a feature file (GFF) and counts how many reads are in certain regions from many input files. By default it counts how many reads overlap the feature on either strand, but it can be made specific with the
-s option. Unfortunately, this option only exists for the multicov command in a version of bedtools that is newer than the module on TACC, so we don't include it in the example command below.
Note: Remember that the chromosome names in your gff file should match the way the chromosomes are named in the reference fasta file used in the mapping step. For example, if BAM file used for mapping contains chr1, chrX etc, the GFF file must also call the chromosomes as chr1, chrX and so on.
Our GFF file has a lot of redundant features that describe a gene multiple times, so we are going to trim it just to have "gene" features using
What is this doing? It's taking all the lines that begin with (^), then "NC_017544", then any number of spaces or tabs, then "GenBank", then any number of spaces or tabs, then "gene". Use
head to see the before and after.
In order to use the bedtools command on our data, do the following:
Then take a peek at the data...
HTseq is another tool to count reads. bedtools has many many useful functions, and counting reads is just one of them. In contrast, HTseq is a specialized utility for counting reads, and it does not have many functions other than that. HTseq is very slow and you need to run multiple command lines in order to do the same job as what bedtools multicov did. Why do we learn this? Well, you may want to care about reads mapped on intersection when you count reads. Please take a look at this page, and if this sophisticated counting method looks useful for you, use HTseq. Otherwise, use bedtools.
gene_counts_HTseq.gff has 5 more lines than gene_counts.gff. Check out the last 5 lines. They are basic statistics.
The basic statistics (last 5 lines) is useful to know, but should be removed to use it as a input file for DEGseq
Finally, gene_counts_HTseq.tab is ready to use. HTseq-count is strand-specific in default. Therefore, read counts for each gene in gene_counts_HTseq.gff are approximately a half counts in gene_counts.gff for the corresponding gene.
Analyze differential gene expression
Our data that is cluttered with a lot of extra columns and one column stuffed with
tag=value information (including the gene names that we want!). Let's clean it up a bit before loading into R - which likes to work on simple tables. GFF are tab-delimited files.
We can do this cleanup many ways, but a quick one is to use the Unix string editor
sed. This command replaces the entire beginning of the line up to
locus_tag= with nothing (that is, it deletes it). This conveniently leaves us with just the locus_tag and the columns of read counts in each gene. If you were writing a real pipeline, you would probably want to use a Perl or Python script that would check to be sure that each line had the locus_tag (they do), among other things.
After it has run, take a peek at the new file:
Be very careful how you copy and paste from the example below.
Do not copy the
> characters. Some commands are spread across multiple lines. The
> are missing at the beginning of the lines after the first one in these cases. So this:
Is the same as:
It's ok to copy across the multiple lines and paste into R as long as you get all the way to the closing parenthesis.
The commands for this example are also described in the DESeq vignette (PDF) .
DESeq-wt-vs-mut.csv is a comma-delimited file that could be reloaded into R or viewed in Excel.
You should copy the two *.pdf files that were created back to your local computer to view them using scp
- What are the numbers returned by
sizeFactors( cds )?Answer...
They are, roughly speaking, the relative average coverage of each data set. Specifically, they are the size parameter of the negative binomial fit to the counts per gene per data file.
- What are the dispersion estimates?
The model assumes there is also a per-gene aspect to the variance in counts observed, that is again fit to a negative binomial distribution (=overdispersed Poisson distribution). In this model, the lower the counts are, the more dispersion relative to the mean is expected (red line in graph). Thus, higher fold changes are required in lowly expressed genes to call the same observed fold-change difference as significant.
- What was the predominant effect of the mutation on gene expression in this Listeria strain?
edgeR is another R package that you can use to do a similar analysis.
These commands use the negative binomial model, calculate the false discovery rate (FDR ~ adjusted p-value), and make a plot similar to the one from DESeq.
Note that the "FC" fold change calculated is initially the reverse of that for the DESeq example for the output here. It is wt relative to mut. To fix this, we put a negative in there for the log fold change.
- Compare the expression changes predicted by DESeq and edgeR to each other.
- Does edgeR or DESeq predict more significant changes?
- In an actual RNAseq analysis, you might want to trim stray adaptor sequences from your data using the tools discussed in Evaluating your raw sequencing data.
- You can get a lot more information from RNAseq data than you could from a microarray experiment. You can map transcriptional start sites, areas of unexpected transcription, splice sites, etc. - all because you have full sequence information that we have barely used in this example.
- You can call variants from mapped RNAseq data, just be aware that many regions will have no coverage (because they are not expressed as RNA).
- Visualize mapped reads in BAM files using IGV to manually check some of the gene counts.
- Look at the more sophisticated "Tuxedo" suite of RNAseq tools, which performs many functions that are especially useful in Eukaryotic genomes.