%\VignetteIndexEntry{04. RNA-seq}
%\VignettePackage{useR2013}



\section{RNA-seq}
\label{sec:rnaseq}

\paragraph{Varieties of RNA-seq}

RNA-seq experiments typically ask about differences in trancription of
genes or other features across experimental groups. The analysis of
designed experiments is statistical, and hence an ideal task for
\R. The overall structure of the analysis, with tens of thousands of
features and tens of samples, is reminiscent of microarray analysis;
some insights from the microarray domain will apply, at least
conceptually, to the analysis of RNA-seq experiments.

The most straight-forward RNA-seq experiments quantify abundance for
known gene models. The known models are derived from reference
databases, reflecting the accumulated knowledge of the community
responsible for the data. A more ambitious approach to RNA-seq
attempts to identify novel transcripts; this is beyond the scope of
today's tutorial.

\Bioconductor{} packages play a role in several stages of an RNA-seq
analysis (Table \ref{tab:rnaseq-pkgs}; a more comprehensive list is
under the
\href{http://bioconductor.org/packages/2.10/BiocViews.html#___RNAseq}{RNAseq}
and
\href{http://bioconductor.org/packages/2.10/BiocViews.html#___HighThroughputSequencing}{HighThroughputSequencing}
BiocViews terms). The \Biocpkg{GenomicRanges} infrastructure can be
effectively employed to quantify known exon or transcript
abundances. Quantified abundances are in essence a matrix of counts,
with rows representing features and columns samples. The
\Biocpkg{edgeR} \cite{pmid19910308} and
\Biocpkg{DESeq2} \cite{AndersHuber2010} packages facilitate analysis of
this data in the context of designed experiments, and are appropriate
when the questions of interest involve between-sample comparisons of
relative abundance. The \Biocpkg{DEXSeq} package extends the approach
in \Biocpkg{edgeR} and \Biocpkg{DESeq2} to ask about within-gene,
between group differences in exon use, i.e., for a given gene, do
groups differ in their exon use?

\begin{table}
  \centering
  \caption{Selected \Bioconductor{} packages for RNA-seq analysis.}
  \label{tab:rnaseq-pkgs}
  \begin{tabular}{lp{.7\textwidth}}
    Package & Description\\
    \hline

    \Biocpkg{EDASeq} & Exploratory analysis and QA; also
    \Biocpkg{qrqc}, \Biocpkg{ShortRead}.\\

    \Biocpkg{edgeR}, \Biocpkg{DESeq2} & Generalized Linear Models using
    negative binomial error. \\

    \Biocpkg{DEXSeq} & Exon-level differential representation. \\

    \Biocpkg{goseq} & Gene set enrichment tailored to RNAseq count
    data; also \Biocpkg{limma}'s \Rfunction{roast} or \Rfunction{camera} after
    transformation with \Rfunction{voom} or \Biocpkg{cqn}. \\

    \Biocpkg{easyRNASeq} & Workflow; also \Biocpkg{ArrayExpressHTS},
    \Biocpkg{rnaSeqMap}, \Biocpkg{oneChannelGUI}. \\

    \Biocpkg{Rsubread} & Alignment (Linux only); also
    \Biocpkg{Biostrings} \Rfunction{matchPDict} for special-purpose
    alignments. \\
    \hline
  \end{tabular}
\end{table}

\subsection{Differential Expression with the \Biocpkg{edgeR} Package}

% FIXME: is the flow ok here?

RNA-seq differential representation experiments, like classical
microarray experiments, consist of a single statistical design (e.g,
comparing expression of samples assigned to `Treatment' versus
`Control' groups) applied to each feature for which there are aligned
reads. While one could naively perform simple tests (e.g., t-tests) on
all features, it is much more informative to identify important
aspects of RNAseq experiments, and to take a flexible route through
this part of the work flow. Key steps involve formulation of a model
matrix to capture the experimental design, estimation of a test static
to describe differences between groups, and calculation of a $P$ value
or other measure as a statement of statistical significance.

\paragraph{Counting and filtering}

An essential step is to arrive at some measure of gene representation
amongst the aligned reads. A straight-forward and commonly used
approach is to count the number of times a read overlaps exons. Nuance
arises when a read only partly overlaps an exon, when two exons
overlap (and hence a read appears to be `double counted'), when reads
are aligned with gaps and the gaps are inconsistent with known exon
boundaries, etc. The \Rfunction{summarizeOverlaps} function in the
\Biocpkg{GenomicRanges} package provides facilities for implementing
different count strategies, using the argument \Rcode{mode} to
determine the counting strategy. The result of
\Rfunction{summarizeOverlaps} can easily be used in subsequent steps
of an RNA-seq analysis.  Software other than \R{} can also be used to
summarize count data. An important point is that the desired input for
downstream analysis is often raw count data, rather than normalized
(e.g., reads per kilobase of gene model per million mapped reads)
values. This is because counts allow information about uncertainty of
estimates to propagate to later stages in the analysis.

The following exercise illustrates key steps in counting and filtering
reads overlapping known genes.

\begin{Exercise}
  The \Rpackage{useR2013} package contains a data set \Rcode{counts}
  with pre-computed count data. Use the \Rfunction{data} command to
  load it. Create a variable \Robject{grp} to define the groups
  associated with each column, using the column names as a proxy for
  more authoritative metadata.

  Create a \Rfunction{DGEList} object (defined in the \Biocpkg{edgeR}
  package) from the count matrix and group information. Calculate
  relative library sizes using the \Rfunction{calcNormFactors}
  function.

  A lesson from the microarray world is to discard genes that cannot
  be informative (e.g., because of lack of variation), regardless of
  statistical hypothesis under evaluation. Filter reads to remove
  those that are represented at less than 1 per million mapped reads,
  in fewer than 2 samples.
\end{Exercise}

\begin{Solution}
  Here we load the data (a matrix of counts) and create treatment
  group names from the column names of the counts matrix.
\begin{Schunk}
\begin{Sinput}
> data(counts)
> dim(counts)
\end{Sinput}
\begin{Soutput}
[1] 14470     7
\end{Soutput}
\begin{Sinput}
> grps <- factor(sub("[1-4].*", "", colnames(counts)),
+                levels=c("untreated", "treated"))
> pairs <- factor(c("single", "paired", "paired",
+                   "single", "single", "paired", "paired"))
> pData <- data.frame(Group=grps, PairType=pairs,
+                     row.names=colnames(counts))
\end{Sinput}
\end{Schunk}

We use the \Biocpkg{edgeR} package, creating a \Rclass{DGEList} object
from the count and group data. The \Rfunction{calcNormFactors}
function estimates relative library sizes for use as offsets in the
generalized linear model.
\begin{Schunk}
\begin{Sinput}
> library(edgeR)
> dge <- DGEList(counts, group=pData$Group)
> dge <- calcNormFactors(dge)
\end{Sinput}
\end{Schunk}

To filter reads, we scale the counts by the library sizes and express
the results on a per-million read scale. This is done using the
\Rfunction{sweep} function, dividing each column by it's library size
and multiplying by \Rcode{1e6}. We require that the gene be
represented at a frequency of at least 1 read per million mapped
(\Rcode{m > 1}, below) in two or more samples (\Rcode{rowSums(m > 1)
  >= 2}), and use this criterion to subset the \Rclass{DGEList}
instance.
\begin{Schunk}
\begin{Sinput}
> m <- sweep(dge$counts, 2, 1e6 / dge$samples$lib.size, `*`)
> ridx <- rowSums(m > 1) >= 2
> table(ridx)                        # number filtered / retained
\end{Sinput}
\begin{Soutput}
ridx
FALSE  TRUE 
 6476  7994 
\end{Soutput}
\begin{Sinput}
> dge <- dge[ridx,]
\end{Sinput}
\end{Schunk}
\end{Solution}

\paragraph{Experimental design}

In \R, an experimental design is specified with the
\Rfunction{model.matrix} function. The function takes as its first
argument a \Robject{formula} describing the independent variables and
their relationship to the response (counts), and as a second argument
a \Robject{data.frame} containing the (phenotypic) data that the
formula describes. A simple formula might read \verb|~ 1 + Group|, which
says that the response is a linear function involving an intercept (1)
plus a term encoded in the variable \Robject{Group}. If (as in our case)
\Robject{Group} is a factor, then the first coefficient (column) of the
model matrix corresponds to the first level of \Robject{Group}, and
subsequent terms correspond to \emph{deviations} of each level from
the first. If \Robject{Group} were \Rclass{numeric} rather than
\Rclass{factor}, the formula would represent linear regressions with
an intercept. Formulas are very flexible, allowing representation of
models with one, two, or more factors as main effects, models with or
without interaction, and with nested effects.

\begin{Exercise}
  To be more concrete, use the \Rfunction{model.matrix} function and a
  formula involving \Robject{Group} to create the model matrix for our
  experiment.
\end{Exercise}

\begin{Solution}
  Here is the experimental design; it is worth discussing with your
  neighbor the interpretation of the \Robject{design} instance.
\begin{Schunk}
\begin{Sinput}
> (design <- model.matrix(~ Group, pData))
\end{Sinput}
\begin{Soutput}
             (Intercept) Grouptreated
treated1fb             1            1
treated2fb             1            1
treated3fb             1            1
untreated1fb           1            0
untreated2fb           1            0
untreated3fb           1            0
untreated4fb           1            0
attr(,"assign")
[1] 0 1
attr(,"contrasts")
attr(,"contrasts")$Group
[1] "contr.treatment"
\end{Soutput}
\end{Schunk}
\end{Solution}

The coefficient (column) labeled `Intercept' corresponds to the first
level of \Robject{Group}, i.e., `untreated'. The coefficient
`Grouptreated' represents the deviation of the treated group from
untreated. Eventually, we will test whether the second coefficient is
significantly different from zero, i.e., whether samples with a `1' in
the second column are, on average, different from samples with a `0'.
On the one hand, use of \Rfunction{model.matrix} to specify
experimental design implies that the user is comfortable with
something more than elementary statistical concepts, while on the
other it provides great flexibility in the experimental design that
can be analyzed.

\paragraph{Negative binomial error}

RNA-seq count data are often described by a negative binomial error
model. This model includes a `dispersion' parameter that describes
biological variation beyond the expectation under a Poisson model. The
simplest approach estimates a dispersion parameter from all the
data. The estimate needs to be conducted in the context of the
experimental design, so that variability between experimental factors
is not mistaken for variability in counts. The square root of the
estimated dispersion represents the coefficient of variation between
biological samples. The following \Biocpkg{edgeR} commands estimate
dispersion.
\begin{Schunk}
\begin{Sinput}
> dge <- estimateTagwiseDisp(dge)
> mean(sqrt(dge$tagwise.dispersion))
\end{Sinput}
\begin{Soutput}
[1] 0.1762471
\end{Soutput}
\end{Schunk}

This approach estimates a dispersion parameter that is
specific to each tag. As another alternative, Anders and Huber
\cite{AndersHuber2010} note that dispersion increases as the mean
number of reads per gene decreases. One can estimate the relationship
between dispersion and mean using \Rfunction{estimateGLMTrendedDisp}
in \Rpackage{edgeR}, using a fitted relationship across all genes to
estimate the dispersion of individual genes. Because in our case
sample sizes (biological replicates) are small, gene-wise estimates of
dispersion are likely imprecise. One approach is to moderate these
estimates by calculating a weighted average of the gene-specific and
common dispersion; \Rfunction{estimateGLMTagwiseDisp} performs this
calculation, requiring that the user provides an \emph{a priori}
estimate of the weight between tag-wise and common dispersion.

\paragraph{Differential representation}

The final steps in estimating differential representation are to fit
the full model; to perform the likelihood ratio test comparing the
full model to a model in which one of the coefficients has been
removed; and to summarize, from the likelihood ratio calculation,
genes that are most differentially represented. The result is a `top
table' whose row names are the Flybase gene ids used to label the
elements of the \Robject{ex} \Rclass{GRangesList}.

\begin{Exercise}
  Use \Rfunction{glmFit} to fit the general linear model. This
  function requires the input data \Robject{dge}, the experimental
  design \Robject{design}, and the estimate of dispersion.

  Use \Rfunction{glmLRT} to form the likelihood ratio test. This
  requires the original data \Robject{dge} and the fitted model from
  the previous part of this question. Which coefficient of the design
  matrix do you wish to test?

  Create a `top table' of differentially represented genes using
  \Rfunction{topTags}.
\end{Exercise}

\begin{Solution}
  Here we fit a generalized linear model to our data and experimental
  design, using the tagwise dispersion estimate.
\begin{Schunk}
\begin{Sinput}
> fit <- glmFit(dge, design)
\end{Sinput}
\end{Schunk}

The fit can be used to calculate a likelihood ratio test, comparing
the full model to a reduced version with the second coefficient
removed. The second coefficient captures the difference between
treated and untreated groups, and the likelihood ratio test asks
whether this term contributes meaningfully to the overall fit.
\begin{Schunk}
\begin{Sinput}
> lrTest <- glmLRT(fit, coef=2)
\end{Sinput}
\end{Schunk}

Here the \Rfunction{topTags} function summarizes results across the
experiment.
\begin{Schunk}
\begin{Sinput}
> tt <- topTags(lrTest, n=10)
> tt[1:3,]
\end{Sinput}
\begin{Soutput}
Coefficient:  Grouptreated 
                logFC   logCPM       LR        PValue           FDR
FBgn0039155 -4.697329 6.035726 564.1616 1.045516e-124 8.357851e-121
FBgn0029167 -2.233879 8.247571 247.1647  1.077884e-55  4.308302e-52
FBgn0034736 -3.499616 4.044214 232.5560  1.651719e-52  4.401281e-49
\end{Soutput}
\end{Schunk}

As a 'sanity check', summarize the original data for the first several
probes, confirming that the average counts of the treatment and
control groups are substantially different.
\begin{Schunk}
\begin{Sinput}
> sapply(rownames(tt$table)[1:4],
+        function(x) tapply(counts[x,], pData$Group, mean))
\end{Sinput}
\begin{Soutput}
          FBgn0039155 FBgn0029167 FBgn0034736 FBgn0035085
untreated        1576    6447.000      382.25    994.2500
treated            64    1482.667       36.00    187.6667
\end{Soutput}
\end{Schunk}
\end{Solution}

\subsection{Additional Steps in RNA-seq Work Flows}

The forgoing provides an elementary work flow. There are many
interesting additional opportunities, including:
\begin{description}
\item[Annotation] Standard \Bioconductor{} facilities, e.g., the
  \Rfunction{select} method from the \Biocpkg{AnnotationDbi} package
  applied to packages such as \Biocannopkg{org.Dm.eg.db} can provide
  biological context (e.g., gene name, KEGG or GO pathway membership)
  for interpretting genes at the top of a top table. Packages using
  \Biocpkg{GenomicFeatures}, e.g.,
  \Biocannopkg{TxDb.Dmelanogaster.UCSC.dm3.ensGene}, can provide
  information on genome structure, e.g., genomic coordinates  of
  exons, and relationship between exons, coding sequences,
  transcripts, and genes.
\item[Gene Set Enrichment] Care needs to be taken because statistical
  signficance of genes is proportional to the number of reads aligning
  to the gene (e.g., due to gene length or GC content); see, e.g.,
  \Biocpkg{goseq}.
\item[Exon-level Differential Representation] The \Biocpkg{DEXSeq}
  package takes an interesting approach to within-gene differential
  expression, testing for interaction between exon use and
  treatment. The forthcoming \Biocpkg{SpliceGraph} package takes this
  a step further by summarizing gene models into graphs, with
  `bubbles' representing alternative splicing events; this reduces the
  number of statistical tests (increasing count per edge and
  statistical power) while providing meaningful insight into the types
  of events (e.g., `exon skip', `alternative acceptor') occuring.
\end{description}

\subsection{Resources}

The \Biocpkg{edgeR}, \Biocpkg{DESeq2}, and \Biocpkg{DEXSeq} package
vignettes provide excellent, extensive discussion of issues and
illustration of methods for RNA-seq differential expression analysis.

