Multimodal data format — MuData — has been introduced to address the need for cross-platform standard for sharing large-scale multimodal omics data. Importantly, it develops ideas of and is compatible with AnnData standard for storing raw and derived data for unimodal datasets.
In Bioconductor, multimodal datasets have been stored in
MultiAssayExperiment
(MAE) objects. This MuData
package provides functionality to read data from
MuData files into MAE objects as well as to save MAE objects into H5MU files.
The most recent dev build can be installed from GitHub:
library(remotes)
remotes::install_github("ilia-kats/MuData")
Stable version of MuData
will be available in future bioconductor versions.
library(MuData)
library(MultiAssayExperiment)
library(rhdf5)
We’ll use a simple MAE object from the MultiAssayExperiment
package that
we’ll then save in a H5MU file.
data(miniACC)
miniACC
#> A MultiAssayExperiment object of 5 listed
#> experiments with user-defined names and respective classes.
#> Containing an ExperimentList class object of length 5:
#> [1] RNASeq2GeneNorm: SummarizedExperiment with 198 rows and 79 columns
#> [2] gistict: SummarizedExperiment with 198 rows and 90 columns
#> [3] RPPAArray: SummarizedExperiment with 33 rows and 46 columns
#> [4] Mutations: matrix with 97 rows and 90 columns
#> [5] miRNASeqGene: SummarizedExperiment with 471 rows and 80 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
We will now write its contents into an H5MU file with WriteH5MU
:
writeH5MU(miniACC, "miniacc.h5mu")
We can manually check the top level of the structure of the file:
rhdf5::h5ls("miniacc.h5mu", recursive = FALSE)
#> group name otype dclass dim
#> 0 / mod H5I_GROUP
#> 1 / obs H5I_GROUP
#> 2 / obsm H5I_GROUP
#> 3 / obsmap H5I_GROUP
#> 4 / uns H5I_GROUP
#> 5 / var H5I_GROUP
Or dig deeper into the file:
h5 <- rhdf5::H5Fopen("miniacc.h5mu")
h5&'mod'
#> HDF5 GROUP
#> name /mod
#> filename
#>
#> name otype dclass dim
#> 0 Mutations H5I_GROUP
#> 1 RNASeq2GeneNorm H5I_GROUP
#> 2 RPPAArray H5I_GROUP
#> 3 gistict H5I_GROUP
#> 4 miRNASeqGene H5I_GROUP
rhdf5::H5close()
This package provides ReadH5MU
to create an object with data from an H5MU
file. Since H5MU structure has been designed to accommodate more structured
information than MAE, only some data will be read. For instance, MAE has no
support for loading multimodal embeddings or pairwise graphs.
acc <- readH5MU("miniacc.h5mu")
#> Reading as SingleCellExperiment where the original object class is matrix
#> Warning: sampleMap[['assay']] coerced with as.factor()
acc
#> A MultiAssayExperiment object of 5 listed
#> experiments with user-defined names and respective classes.
#> Containing an ExperimentList class object of length 5:
#> [1] RNASeq2GeneNorm: SummarizedExperiment with 198 rows and 79 columns
#> [2] gistict: SummarizedExperiment with 198 rows and 90 columns
#> [3] RPPAArray: SummarizedExperiment with 33 rows and 46 columns
#> [4] Mutations: SingleCellExperiment with 97 rows and 90 columns
#> [5] miRNASeqGene: SummarizedExperiment with 471 rows and 80 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
Importantly, we recover the information from the original MAE object:
head(colData(miniACC)[,1:4])
#> DataFrame with 6 rows and 4 columns
#> patientID years_to_birth vital_status days_to_death
#> <character> <integer> <integer> <integer>
#> TCGA-OR-A5J1 TCGA-OR-A5J1 58 1 1355
#> TCGA-OR-A5J2 TCGA-OR-A5J2 44 1 1677
#> TCGA-OR-A5J3 TCGA-OR-A5J3 23 0 NA
#> TCGA-OR-A5J4 TCGA-OR-A5J4 23 1 423
#> TCGA-OR-A5J5 TCGA-OR-A5J5 30 1 365
#> TCGA-OR-A5J6 TCGA-OR-A5J6 29 0 NA
head(colData(acc)[,1:4])
#> DataFrame with 6 rows and 4 columns
#> patientID years_to_birth vital_status days_to_death
#> <character> <integer> <integer> <integer>
#> TCGA-OR-A5J1 TCGA-OR-A5J1 58 1 1355
#> TCGA-OR-A5J2 TCGA-OR-A5J2 44 1 1677
#> TCGA-OR-A5J3 TCGA-OR-A5J3 23 0 NA
#> TCGA-OR-A5J4 TCGA-OR-A5J4 23 1 423
#> TCGA-OR-A5J5 TCGA-OR-A5J5 30 1 365
#> TCGA-OR-A5J6 TCGA-OR-A5J6 29 0 NA
Features metadata is also recovered:
head(rowData(miniACC[["gistict"]]))
#> DataFrame with 6 rows and 3 columns
#> Gene.Symbol Locus.ID Cytoband
#> <character> <character> <character>
#> DIRAS3 DIRAS3 9077 1p31.3
#> MAPK14 MAPK14 1432 6p21.31
#> YAP1 YAP1 10413 11q22.1
#> CDKN1B CDKN1B 1027 12p13.1
#> ERBB2 ERBB2 2064 17q12
#> G6PD G6PD 2539 Xq28
head(rowData(acc[["gistict"]]))
#> DataFrame with 6 rows and 3 columns
#> Gene.Symbol Locus.ID Cytoband
#> <character> <character> <character>
#> DIRAS3 DIRAS3 9077 1p31.3
#> MAPK14 MAPK14 1432 6p21.31
#> YAP1 YAP1 10413 11q22.1
#> CDKN1B CDKN1B 1027 12p13.1
#> ERBB2 ERBB2 2064 17q12
#> G6PD G6PD 2539 Xq28
It is possible to read H5MU files while keeping matrices (both .X
and
.layers
) on disk.
acc_b <- readH5MU("miniacc.h5mu", backed = TRUE)
#> Reading as SingleCellExperiment where the original object class is matrix
#> Warning: sampleMap[['assay']] coerced with as.factor()
assay(acc_b, "RNASeq2GeneNorm")[1:5,1:3]
#> <5 x 3> DelayedMatrix object of type "double":
#> TCGA-OR-A5J1-01A-11R-A29S-07 TCGA-OR-A5J2-01A-11R-A29S-07
#> DIRAS3 1487.0317 9.6631
#> MAPK14 778.5783 2823.6469
#> YAP1 1009.6061 2305.0590
#> CDKN1B 2101.3449 4248.9584
#> ERBB2 651.2968 246.4098
#> TCGA-OR-A5J3-01A-11R-A29S-07
#> DIRAS3 18.9602
#> MAPK14 1061.7686
#> YAP1 1561.2502
#> CDKN1B 1348.5410
#> ERBB2 90.0607
The data in the assay is a DelayedMatrix
object:
class(assay(acc_b, "RNASeq2GeneNorm"))
#> [1] "DelayedMatrix"
#> attr(,"package")
#> [1] "DelayedArray"
This is in contrast to the acc
object that has matrices in memory:
assay(acc, "RNASeq2GeneNorm")[1:5,1:3]
#> TCGA-OR-A5J1-01A-11R-A29S-07 TCGA-OR-A5J2-01A-11R-A29S-07
#> DIRAS3 1487.0317 9.6631
#> MAPK14 778.5783 2823.6469
#> YAP1 1009.6061 2305.0590
#> CDKN1B 2101.3449 4248.9584
#> ERBB2 651.2968 246.4098
#> TCGA-OR-A5J3-01A-11R-A29S-07
#> DIRAS3 18.9602
#> MAPK14 1061.7686
#> YAP1 1561.2502
#> CDKN1B 1348.5410
#> ERBB2 90.0607
class(assay(acc, "RNASeq2GeneNorm"))
#> [1] "matrix" "array"
mudata (Python) documentation
muon documentation and web page
sessionInfo()
#> R version 4.4.0 beta (2024-04-15 r86425)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 22.04.4 LTS
#>
#> Matrix products: default
#> BLAS: /home/biocbuild/bbs-3.19-bioc/R/lib/libRblas.so
#> LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.10.0
#>
#> locale:
#> [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
#> [3] LC_TIME=en_US.UTF-8 LC_COLLATE=en_US.UTF-8
#> [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
#>
#> time zone: America/New_York
#> tzcode source: system (glibc)
#>
#> attached base packages:
#> [1] stats4 stats graphics grDevices utils datasets methods
#> [8] base
#>
#> other attached packages:
#> [1] SingleCellMultiModal_1.15.2 scater_1.32.0
#> [3] ggplot2_3.5.1 scuttle_1.14.0
#> [5] CiteFuse_1.16.0 MultiAssayExperiment_1.30.0
#> [7] SingleCellExperiment_1.26.0 SummarizedExperiment_1.34.0
#> [9] Biobase_2.64.0 GenomicRanges_1.56.0
#> [11] GenomeInfoDb_1.40.0 IRanges_2.38.0
#> [13] MatrixGenerics_1.16.0 matrixStats_1.3.0
#> [15] MuData_1.8.0 rhdf5_2.48.0
#> [17] S4Vectors_0.42.0 BiocGenerics_0.50.0
#> [19] Matrix_1.7-0 BiocStyle_2.32.0
#>
#> loaded via a namespace (and not attached):
#> [1] splines_4.4.0 filelock_1.0.3
#> [3] tibble_3.2.1 polyclip_1.10-6
#> [5] lifecycle_1.0.4 edgeR_4.2.0
#> [7] lattice_0.22-6 MASS_7.3-60.2
#> [9] magrittr_2.0.3 limma_3.60.0
#> [11] plotly_4.10.4 sass_0.4.9
#> [13] rmarkdown_2.26 jquerylib_0.1.4
#> [15] yaml_2.3.8 metapod_1.12.0
#> [17] cowplot_1.1.3 bayesm_3.1-6
#> [19] DBI_1.2.2 RColorBrewer_1.1-3
#> [21] abind_1.4-5 zlibbioc_1.50.0
#> [23] Rtsne_0.17 purrr_1.0.2
#> [25] mixtools_2.0.0 ggraph_2.2.1
#> [27] tensorA_0.36.2.1 tweenr_2.0.3
#> [29] rappdirs_0.3.3 GenomeInfoDbData_1.2.12
#> [31] ggrepel_0.9.5 irlba_2.3.5.1
#> [33] pheatmap_1.0.12 dqrng_0.3.2
#> [35] DelayedMatrixStats_1.26.0 codetools_0.2-20
#> [37] DelayedArray_0.30.0 ggforce_0.4.2
#> [39] tidyselect_1.2.1 UCSC.utils_1.0.0
#> [41] farver_2.1.1 ScaledMatrix_1.12.0
#> [43] viridis_0.6.5 BiocFileCache_2.12.0
#> [45] jsonlite_1.8.8 BiocNeighbors_1.22.0
#> [47] tidygraph_1.3.1 ggridges_0.5.6
#> [49] survival_3.6-4 dbscan_1.1-12
#> [51] segmented_2.0-4 tools_4.4.0
#> [53] Rcpp_1.0.12 glue_1.7.0
#> [55] BiocBaseUtils_1.6.0 gridExtra_2.3
#> [57] SparseArray_1.4.0 xfun_0.43
#> [59] HDF5Array_1.32.0 dplyr_1.1.4
#> [61] withr_3.0.0 BiocManager_1.30.22
#> [63] fastmap_1.1.1 rhdf5filters_1.16.0
#> [65] bluster_1.14.0 fansi_1.0.6
#> [67] digest_0.6.35 rsvd_1.0.5
#> [69] mime_0.12 R6_2.5.1
#> [71] colorspace_2.1-0 RSQLite_2.3.6
#> [73] utf8_1.2.4 tidyr_1.3.1
#> [75] generics_0.1.3 data.table_1.15.4
#> [77] robustbase_0.99-2 graphlayouts_1.1.1
#> [79] httr_1.4.7 htmlwidgets_1.6.4
#> [81] S4Arrays_1.4.0 uwot_0.2.2
#> [83] pkgconfig_2.0.3 gtable_0.3.5
#> [85] blob_1.2.4 XVector_0.44.0
#> [87] htmltools_0.5.8.1 bookdown_0.39
#> [89] scales_1.3.0 png_0.1-8
#> [91] SpatialExperiment_1.14.0 scran_1.32.0
#> [93] knitr_1.46 rjson_0.2.21
#> [95] reshape2_1.4.4 nlme_3.1-164
#> [97] curl_5.2.1 cachem_1.0.8
#> [99] stringr_1.5.1 BiocVersion_3.19.1
#> [101] parallel_4.4.0 vipor_0.4.7
#> [103] AnnotationDbi_1.66.0 pillar_1.9.0
#> [105] grid_4.4.0 vctrs_0.6.5
#> [107] randomForest_4.7-1.1 BiocSingular_1.20.0
#> [109] dbplyr_2.5.0 beachmat_2.20.0
#> [111] cluster_2.1.6 beeswarm_0.4.0
#> [113] evaluate_0.23 tinytex_0.50
#> [115] magick_2.8.3 cli_3.6.2
#> [117] locfit_1.5-9.9 compiler_4.4.0
#> [119] rlang_1.1.3 crayon_1.5.2
#> [121] labeling_0.4.3 plyr_1.8.9
#> [123] ggbeeswarm_0.7.2 stringi_1.8.3
#> [125] viridisLite_0.4.2 BiocParallel_1.38.0
#> [127] Biostrings_2.72.0 munsell_0.5.1
#> [129] lazyeval_0.2.2 compositions_2.0-8
#> [131] ExperimentHub_2.12.0 sparseMatrixStats_1.16.0
#> [133] bit64_4.0.5 Rhdf5lib_1.26.0
#> [135] KEGGREST_1.44.0 statmod_1.5.0
#> [137] highr_0.10 AnnotationHub_3.12.0
#> [139] kernlab_0.9-32 igraph_2.0.3
#> [141] memoise_2.0.1 bslib_0.7.0
#> [143] DEoptimR_1.1-3 bit_4.0.5