library(MultiAssayExperiment)
library(HDF5Array)
library(SummarizedExperiment)
The HDF5Array
package provides an on-disk representation of large datasets
without the need to load them into memory. Convenient lazy evaluation
operations allow the user to manipulate such large data files based on
metadata. The DelayedMatrix
class in the DelayedArray
package provides a
way to connect to a large matrix that is stored on disk.
First, we create a small matrix for constructing the DelayedMatrix
class.
smallMatrix <- matrix(rnorm(10e5), ncol = 20)
We add rownames and column names to the matrix object for compatibility with
the MultiAssayExperiment
representation.
rownames(smallMatrix) <- paste0("GENE", seq_len(nrow(smallMatrix)))
colnames(smallMatrix) <- paste0("SampleID", seq_len(ncol(smallMatrix)))
Here we use the DelayedArray
constructor function to create a
DelayedMatrix
object.
smallMatrix <- DelayedArray(smallMatrix)
class(smallMatrix)
## [1] "DelayedMatrix"
## attr(,"package")
## [1] "DelayedArray"
# show method
smallMatrix
## <50000 x 20> matrix of class DelayedMatrix and type "double":
## SampleID1 SampleID2 SampleID3 ... SampleID19 SampleID20
## GENE1 -0.4562081 0.5989988 0.1197112 . 0.806507453 1.003823877
## GENE2 -1.3130393 0.3268518 0.5810708 . -0.007831791 -0.747250401
## GENE3 1.6019356 0.1846502 1.4239187 . 0.112324744 1.636777518
## GENE4 -0.4634783 -0.7935095 -2.1467394 . 0.057203982 0.971811192
## GENE5 -0.3331134 -1.0070112 -1.1911608 . 0.146801486 -1.067594503
## ... . . . . . .
## GENE49996 -0.45041347 -0.92181589 1.19481173 . 1.35240005 -0.25664421
## GENE49997 0.90663867 -0.96655724 0.91593526 . 0.99505240 0.51006783
## GENE49998 0.86075404 -0.26418105 -1.28231223 . 0.68677923 0.45102585
## GENE49999 0.64309578 0.09633518 0.79747486 . -0.80709547 -0.44974234
## GENE50000 0.52895075 -1.56421116 1.82009053 . 0.08958689 -1.53833828
dim(smallMatrix)
## [1] 50000 20
Finally, the rhdf5
package stores dimnames
in a standard location.
In order to make use of this functionality, we would use writeHDF5Array
with the with.dimnames
argument:
testh5 <- tempfile(fileext = ".h5")
writeHDF5Array(smallMatrix, filepath = testh5, name = "smallMatrix",
with.dimnames = TRUE)
## <50000 x 20> matrix of class HDF5Matrix and type "double":
## SampleID1 SampleID2 SampleID3 ... SampleID19 SampleID20
## GENE1 -0.4562081 0.5989988 0.1197112 . 0.806507453 1.003823877
## GENE2 -1.3130393 0.3268518 0.5810708 . -0.007831791 -0.747250401
## GENE3 1.6019356 0.1846502 1.4239187 . 0.112324744 1.636777518
## GENE4 -0.4634783 -0.7935095 -2.1467394 . 0.057203982 0.971811192
## GENE5 -0.3331134 -1.0070112 -1.1911608 . 0.146801486 -1.067594503
## ... . . . . . .
## GENE49996 -0.45041347 -0.92181589 1.19481173 . 1.35240005 -0.25664421
## GENE49997 0.90663867 -0.96655724 0.91593526 . 0.99505240 0.51006783
## GENE49998 0.86075404 -0.26418105 -1.28231223 . 0.68677923 0.45102585
## GENE49999 0.64309578 0.09633518 0.79747486 . -0.80709547 -0.44974234
## GENE50000 0.52895075 -1.56421116 1.82009053 . 0.08958689 -1.53833828
To see the file structure we use h5ls
:
h5ls(testh5)
## group name otype dclass dim
## 0 / .smallMatrix_dimnames H5I_GROUP
## 1 /.smallMatrix_dimnames 1 H5I_DATASET STRING 50000
## 2 /.smallMatrix_dimnames 2 H5I_DATASET STRING 20
## 3 / smallMatrix H5I_DATASET FLOAT 50000 x 20
Note that a large matrix from an HDF5 file can also be loaded using the
HDF5ArraySeed
and DelayedArray
functions.
hdf5Data <- HDF5ArraySeed(file = testh5, name = "smallMatrix")
newDelayedMatrix <- DelayedArray(hdf5Data)
class(newDelayedMatrix)
## [1] "HDF5Matrix"
## attr(,"package")
## [1] "HDF5Array"
newDelayedMatrix
## <50000 x 20> matrix of class HDF5Matrix and type "double":
## SampleID1 SampleID2 SampleID3 ... SampleID19 SampleID20
## GENE1 -0.4562081 0.5989988 0.1197112 . 0.806507453 1.003823877
## GENE2 -1.3130393 0.3268518 0.5810708 . -0.007831791 -0.747250401
## GENE3 1.6019356 0.1846502 1.4239187 . 0.112324744 1.636777518
## GENE4 -0.4634783 -0.7935095 -2.1467394 . 0.057203982 0.971811192
## GENE5 -0.3331134 -1.0070112 -1.1911608 . 0.146801486 -1.067594503
## ... . . . . . .
## GENE49996 -0.45041347 -0.92181589 1.19481173 . 1.35240005 -0.25664421
## GENE49997 0.90663867 -0.96655724 0.91593526 . 0.99505240 0.51006783
## GENE49998 0.86075404 -0.26418105 -1.28231223 . 0.68677923 0.45102585
## GENE49999 0.64309578 0.09633518 0.79747486 . -0.80709547 -0.44974234
## GENE50000 0.52895075 -1.56421116 1.82009053 . 0.08958689 -1.53833828
DelayedMatrix
with MultiAssayExperiment
A DelayedMatrix
alone conforms to the MultiAssayExperiment
API requirements.
Shown below, the DelayedMatrix
can be put into a named list
and passed into
the MultiAssayExperiment
constructor function.
HDF5MAE <- MultiAssayExperiment(experiments = list(smallMatrix = smallMatrix))
sampleMap(HDF5MAE)
## DataFrame with 20 rows and 3 columns
## assay primary colname
## <factor> <character> <character>
## 1 smallMatrix SampleID1 SampleID1
## 2 smallMatrix SampleID2 SampleID2
## 3 smallMatrix SampleID3 SampleID3
## 4 smallMatrix SampleID4 SampleID4
## 5 smallMatrix SampleID5 SampleID5
## ... ... ... ...
## 16 smallMatrix SampleID16 SampleID16
## 17 smallMatrix SampleID17 SampleID17
## 18 smallMatrix SampleID18 SampleID18
## 19 smallMatrix SampleID19 SampleID19
## 20 smallMatrix SampleID20 SampleID20
colData(HDF5MAE)
## DataFrame with 20 rows and 0 columns
SummarizedExperiment
with DelayedMatrix
backendA more information rich DelayedMatrix
can be created when used in conjunction
with the SummarizedExperiment
class and it can even include rowRanges
.
The flexibility of the MultiAssayExperiment
API supports classes with
minimal requirements. Additionally, this SummarizedExperiment
with the
DelayedMatrix
backend can be part of a bigger MultiAssayExperiment
object.
Below is a minimal example of how this would work:
HDF5SE <- SummarizedExperiment(assays = smallMatrix)
assay(HDF5SE)
## <50000 x 20> matrix of class DelayedMatrix and type "double":
## SampleID1 SampleID2 SampleID3 ... SampleID19 SampleID20
## GENE1 -0.4562081 0.5989988 0.1197112 . 0.806507453 1.003823877
## GENE2 -1.3130393 0.3268518 0.5810708 . -0.007831791 -0.747250401
## GENE3 1.6019356 0.1846502 1.4239187 . 0.112324744 1.636777518
## GENE4 -0.4634783 -0.7935095 -2.1467394 . 0.057203982 0.971811192
## GENE5 -0.3331134 -1.0070112 -1.1911608 . 0.146801486 -1.067594503
## ... . . . . . .
## GENE49996 -0.45041347 -0.92181589 1.19481173 . 1.35240005 -0.25664421
## GENE49997 0.90663867 -0.96655724 0.91593526 . 0.99505240 0.51006783
## GENE49998 0.86075404 -0.26418105 -1.28231223 . 0.68677923 0.45102585
## GENE49999 0.64309578 0.09633518 0.79747486 . -0.80709547 -0.44974234
## GENE50000 0.52895075 -1.56421116 1.82009053 . 0.08958689 -1.53833828
MultiAssayExperiment(list(HDF5SE = HDF5SE))
## A MultiAssayExperiment object of 1 listed
## experiment with a user-defined name and respective class.
## Containing an ExperimentList class object of length 1:
## [1] HDF5SE: SummarizedExperiment with 50000 rows and 20 columns
## Functionality:
## experiments() - obtain the ExperimentList instance
## colData() - the primary/phenotype DataFrame
## sampleMap() - the sample coordination DataFrame
## `$`, `[`, `[[` - extract colData columns, subset, or experiment
## *Format() - convert into a long or wide DataFrame
## assays() - convert ExperimentList to a SimpleList of matrices
## exportClass() - save data to flat files
Additional scenarios are currently in development where an HDF5Matrix
is
hosted remotely. Many opportunities exist when considering on-disk and off-disk
representations of data with MultiAssayExperiment
.