DEFormats facilitates data conversion between the most widely used tools for differential gene expression analysis; currently, the Bioconductor packages DESeq2 and edgeR are supported. It provides converter functions of the form as.<class>(object)
, where <class>
is the name of the class to which object
should be coerced. Additionally, DEFormats extends the original packages by offering constructors for common count data input formats, e.g. SummarizedExperiment objects.
The following examples demonstrate how to shuttle data between DESeqDataSet and DGEList containers. Before we start, let’s first load the required packages.
library(DESeq2)
library(edgeR)
library(DEFormats)
We will illustrate the functionality of the package on a mock expression data set of an RNA-seq experiment. The sample counts table can be generated using the function provided by DEFormats:
counts = simulateRnaSeqData()
The resulting object is a matrix with rows corresponding to genomic features and columns to samples.
head(counts)
## sample1 sample2 sample3 sample4 sample5 sample6
## gene1 85 76 103 107 140 124
## gene2 1 6 11 6 1 4
## gene3 80 98 39 82 97 113
## gene4 92 83 59 85 100 98
## gene5 36 24 18 50 22 15
## gene6 0 0 1 4 2 3
In order to construct a DGEList object we need to provide, apart from the counts matrix, the sample grouping.
group = rep(c("A", "B"), each = 3)
dge = DGEList(counts, group = group)
dge
## An object of class "DGEList"
## $counts
## sample1 sample2 sample3 sample4 sample5 sample6
## gene1 85 76 103 107 140 124
## gene2 1 6 11 6 1 4
## gene3 80 98 39 82 97 113
## gene4 92 83 59 85 100 98
## gene5 36 24 18 50 22 15
## 995 more rows ...
##
## $samples
## group lib.size norm.factors
## sample1 A 42832 1
## sample2 A 40511 1
## sample3 A 39299 1
## sample4 B 43451 1
## sample5 B 40613 1
## sample6 B 43662 1
A DGEList object can be easily converted to a DESeqDataSet object with the help of the function as.DESeqDataSet
.
dds = as.DESeqDataSet(dge)
dds
## class: DESeqDataSet
## dim: 1000 6
## metadata(1): version
## assays(1): counts
## rownames(1000): gene1 gene2 ... gene999 gene1000
## rowData names(0):
## colnames(6): sample1 sample2 ... sample5 sample6
## colData names(3): group lib.size norm.factors
Just to make sure that the coercions conserve the data and metadata, we now convert dds
back to a DGEList and compare the result to the original dge
object.
identical(dge, as.DGEList(dds))
## [1] TRUE
Note that because of the use of reference classes in the SummarizedExperiment class which DESeqDataSet extends, identical
will return FALSE
for any two DESeqDataSet instances, even for ones constructed from the same input:
dds1 = DESeqDataSetFromMatrix(counts, data.frame(condition=group), ~ condition)
dds2 = DESeqDataSetFromMatrix(counts, data.frame(condition=group), ~ condition)
identical(dds1, dds2)
## [1] FALSE
Instead of a count matrix, simulateRnaSeqData
can also return an annotated RangedSummarizedExperiment object. The advantage of such an object is that, apart from the counts matrix stored in the assay
slot, it also contains sample description in colData
, and gene information stored in rowRanges
as a GRanges
object.
se = simulateRnaSeqData(output = "RangedSummarizedExperiment")
se
## class: RangedSummarizedExperiment
## dim: 1000 6
## metadata(1): version
## assays(1): counts
## rownames(1000): gene1 gene2 ... gene999 gene1000
## rowData names(3): trueIntercept trueBeta trueDisp
## colnames(6): sample1 sample2 ... sample5 sample6
## colData names(1): condition
The se
object can be readily used to construct a DESeqDataSet object,
dds = DESeqDataSet(se, design = ~ condition)
which can be converted to a DGEList using the familiar method.
dge = as.DGEList(dds)
dge
## An object of class "DGEList"
## $counts
## sample1 sample2 sample3 sample4 sample5 sample6
## gene1 85 76 103 107 140 124
## gene2 1 6 11 6 1 4
## gene3 80 98 39 82 97 113
## gene4 92 83 59 85 100 98
## gene5 36 24 18 50 22 15
## 995 more rows ...
##
## $samples
## group lib.size norm.factors
## sample1 A 42832 1
## sample2 A 40511 1
## sample3 A 39299 1
## sample4 B 43451 1
## sample5 B 40613 1
## sample6 B 43662 1
##
## $genes
## seqnames start end width strand trueIntercept trueBeta trueDisp
## gene1 1 1 100 100 * 6.525909 0 0.1434076
## gene2 1 101 200 100 * 3.347533 0 0.4929634
## gene3 1 201 300 100 * 6.659599 0 0.1395659
## gene4 1 301 400 100 * 6.544859 0 0.1428412
## gene5 1 401 500 100 * 4.829283 0 0.2407022
## 995 more rows ...
Note the additional genes
element on the dge
list compared to the object from the previous section.
Similarly as for the DESeqDataSet
constructor from DESeq2, it is possible to directly use RangedSummarizedExperiment objects as input to the generic DGEList
constructor defined in DEFormats. This allows you to use common input objects regardless of whether you are applying DESeq2 or edgeR to perform your analysis, or to easily switch between these two tools in your pipeline.
dge = DGEList(se)
dge
## An object of class "DGEList"
## $counts
## sample1 sample2 sample3 sample4 sample5 sample6
## gene1 85 76 103 107 140 124
## gene2 1 6 11 6 1 4
## gene3 80 98 39 82 97 113
## gene4 92 83 59 85 100 98
## gene5 36 24 18 50 22 15
## 995 more rows ...
##
## $samples
## group lib.size norm.factors condition
## sample1 A 42832 1 A
## sample2 A 40511 1 A
## sample3 A 39299 1 A
## sample4 B 43451 1 B
## sample5 B 40613 1 B
## sample6 B 43662 1 B
##
## $genes
## seqnames start end width strand trueIntercept trueBeta trueDisp
## gene1 1 1 100 100 * 6.525909 0 0.1434076
## gene2 1 101 200 100 * 3.347533 0 0.4929634
## gene3 1 201 300 100 * 6.659599 0 0.1395659
## gene4 1 301 400 100 * 6.544859 0 0.1428412
## gene5 1 401 500 100 * 4.829283 0 0.2407022
## 995 more rows ...
Even though there is no direct method to go from a DGEList to a RangedSummarizedExperiment, the coercion can be easily performed by first converting the object to a DESeqDataSet, which is a subclass of RangedSummarizedExperiment, and then coercing the resulting object to its superclass.
dds = as.DESeqDataSet(dge)
rse = as(dds, "RangedSummarizedExperiment")
rse
## class: RangedSummarizedExperiment
## dim: 1000 6
## metadata(1): version
## assays(1): counts
## rownames(1000): gene1 gene2 ... gene999 gene1000
## rowData names(3): trueIntercept trueBeta trueDisp
## colnames(6): sample1 sample2 ... sample5 sample6
## colData names(4): group lib.size norm.factors condition
sessionInfo()
## R version 3.3.1 (2016-06-21)
## Platform: x86_64-pc-linux-gnu (64-bit)
## Running under: Ubuntu 16.04.1 LTS
##
## locale:
## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=en_US.UTF-8 LC_COLLATE=C
## [5] LC_MONETARY=en_US.UTF-8 LC_MESSAGES=en_US.UTF-8
## [7] LC_PAPER=en_US.UTF-8 LC_NAME=C
## [9] LC_ADDRESS=C LC_TELEPHONE=C
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C
##
## attached base packages:
## [1] parallel stats4 stats graphics grDevices utils datasets
## [8] methods base
##
## other attached packages:
## [1] DEFormats_1.2.0 edgeR_3.16.0
## [3] limma_3.30.0 DESeq2_1.14.0
## [5] SummarizedExperiment_1.4.0 Biobase_2.34.0
## [7] GenomicRanges_1.26.0 GenomeInfoDb_1.10.0
## [9] IRanges_2.8.0 S4Vectors_0.12.0
## [11] BiocGenerics_0.20.0 BiocStyle_2.2.0
##
## loaded via a namespace (and not attached):
## [1] genefilter_1.56.0 locfit_1.5-9.1 splines_3.3.1
## [4] lattice_0.20-34 colorspace_1.2-7 htmltools_0.3.5
## [7] yaml_2.1.13 chron_2.3-47 survival_2.39-5
## [10] XML_3.98-1.4 foreign_0.8-67 DBI_0.5-1
## [13] BiocParallel_1.8.0 RColorBrewer_1.1-2 plyr_1.8.4
## [16] stringr_1.1.0 zlibbioc_1.20.0 munsell_0.4.3
## [19] gtable_0.2.0 evaluate_0.10 latticeExtra_0.6-28
## [22] knitr_1.14 geneplotter_1.52.0 AnnotationDbi_1.36.0
## [25] Rcpp_0.12.7 acepack_1.3-3.3 xtable_1.8-2
## [28] backports_1.0.3 checkmate_1.8.1 scales_0.4.0
## [31] formatR_1.4 Hmisc_3.17-4 annotate_1.52.0
## [34] XVector_0.14.0 gridExtra_2.2.1 ggplot2_2.1.0
## [37] digest_0.6.10 stringi_1.1.2 grid_3.3.1
## [40] tools_3.3.1 bitops_1.0-6 magrittr_1.5
## [43] RCurl_1.95-4.8 tibble_1.2 RSQLite_1.0.0
## [46] Formula_1.2-1 cluster_2.0.5 Matrix_1.2-7.1
## [49] data.table_1.9.6 assertthat_0.1 rmarkdown_1.1
## [52] rpart_4.1-10 nnet_7.3-12