--- title: "SPAROscore: Data Structures" package: "SPAROscore" author: "Venkatesh Kamaraj" date: "`r Sys.Date()`" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{SPAROscore: Data Structures} %\VignetteEngine{knitr::rmarkdown} %\VignetteEncoding{UTF-8} --- ```{r global-options, include = FALSE} knitr::opts_chunk$set( collapse = TRUE, comment = "#>", fig.width = 12, fig.height = 6, out.width = "100%" ) ``` ```{r setup, warning=FALSE, message=FALSE} # load the necessary libraries library(SPAROscore) library(airway) library(msigdbr) library(dplyr) library(Matrix) library(DelayedArray) library(GSEABase) library(Seurat) library(scater) ``` # Supported input data structures SPAROscore is designed to integrate seamlessly with data structures commonly used in bulk, single-cell, and spatial RNA-seq analysis workflows. Rather than requiring users to convert their data into a specific format, SPAROscore accepts a range of gene expression and gene signature data structures. This vignette demonstrates the supported input formats and illustrates how the output adapts to each input type. * For gene expression input, the following data structures are supported * Matrix-like objects: Dense matrices, Sparse Matrices, Delayed Arrays, and Data frames * Bioconductor data structures: SummarizedExperiment and its derived classes like SingleCellExperiment, SpatialExperiment, RangedSummarizedExperiment, tidySummarizedExperiment, etc. * Seurat objects: containing both single-cell and spatial datasets *Note: Matrix-like inputs return a score table, whereas container objects (e.g. SummarizedExperiment and Seurat) are returned with scores added to their metadata.* | Input | Accepted | Output | | :--- | :---: | :--- | | matrix | ✓ | matrix | | sparseMatrix | ✓ | matrix | | DelayedArray | ✓ | matrix | | data.frame | ✓ | matrix | | SummarizedExperiment | ✓ | SummarizedExperiment | | SingleCellExperiment | ✓ | SingleCellExperiment | | SpatialExperiment | ✓ | SpatialExperiment | | Seurat | ✓ | Seurat |
* For the gene signature input, the following formats are supported * For a single signature: A character vector, A GeneSet object * For multiple signatures: A named list of character vectors, GeneSetCollection objects. *Note: The Gene identifiers (gene names, ensembl ids, etc) in the signature must match those used in the expression data.* ## Example datasets In this vignette, we will demonstrate the data structure handling capabilities of SPAROscore using the example dataset from the `airway` package. For the gene signatures, we will use the top differentially expressed genes reported in the [original study](https://doi.org/10.1371/journal.pone.0099625), as well as the hallmark inflammatory response genes taken from the Molecular Signatures Database (MSigDB). ### Load the gene expression dataset ```{r load-data} # load the airway dataset data(airway) # extract the gene expression matrix counts_data <- assay(airway) # extract the metadata metadata <- as.data.frame(colData(airway)) ``` ### Load the gene signatures ```{r load-signature} # set the glucocorticoid response markers from the original study as a signature response_genes <- c("ENSG00000112936", "ENSG00000170606", "ENSG00000120129", "ENSG00000152795", "ENSG00000211445", "ENSG00000163884", "ENSG00000189221", "ENSG00000101347", "ENSG00000196136", "ENSG00000152583", "ENSG00000120658", "ENSG00000157514", "ENSG00000103196", "ENSG00000179094", "ENSG00000152763", "ENSG00000103310", "ENSG00000127954") # load the inflammatory response hallmark genes from msigdb inflammation_genes <- msigdbr(species = "Homo sapiens", collection = "H") %>% filter(gs_name == "HALLMARK_INFLAMMATORY_RESPONSE") %>% pull("ensembl_gene") %>% as.character() ``` # Gene expression as matrix-like data structures ## Dense matrix ```{r matrix} # load gene expression data as dense matrix counts_matrix <- as.matrix(counts_data) # score for the dense matrix scores_matrix <- sparoscore(data = counts_matrix, signatures = inflammation_genes) # view scores scores_matrix ``` Note that one signature gene is absent from the input expression data, and SPAROscore reports this as a warning during scoring. ## SparseMatrix ```{r smatrix} # load gene expression data as sparseMatrix counts_sparse <- as(counts_matrix, "sparseMatrix") # score for the sparseMatrix scores_sparse <- sparoscore(data = counts_sparse, signatures = inflammation_genes) # view scores scores_sparse ``` Gene ranking is performed directly on sparse matrices without first converting them to dense matrices, reducing memory usage and improving computational efficiency. ## DelayedArrays ```{r dmatrix} # load gene expression data as delayedArray counts_delayed <- DelayedArray(counts_matrix) # score for the DelayedArray scores_delayed <- sparoscore(data = counts_delayed, signatures = inflammation_genes) # view scores scores_delayed ``` Note that the gene ranking is performed natively on the DelayedArray object, enabling improved computational efficiency. ## Data frame ```{r dataframe} # load gene expression data as delayedArray counts_df <- as.data.frame(counts_matrix) # score for the DelayedArray scores_df <- sparoscore(data = counts_df, signatures = inflammation_genes) # view scores scores_df ``` Data frames are internally converted to matrices before ranking because matrix operations are more efficient for this step. ### Verify if the output scores are the same with differing input formats ```{r check-results} identical(scores_matrix, scores_sparse) identical(scores_matrix, scores_delayed) identical(scores_matrix, scores_df) ``` # Gene signature representations ## Single signature as a character vector ```{r character} # compute scores from a character vector signature scores_for_vector <- sparoscore(data = counts_matrix, signatures = response_genes) # view scores scores_for_vector ``` ## Single signature as a GeneSet object ```{r geneset} # get a GeneSet object response_geneset <- GeneSet(response_genes) # compute scores from a GeneSet object scores_for_geneset <- sparoscore(data = counts_sparse, signatures = response_geneset, prefix = "hello") # view scores scores_for_geneset ``` ## Multiple signatures as a named list ```{r list} # create a named list of vectors to score for both signatures simultaneously gene_signatures <- list("glucocorticoid_response" = response_genes, "inflammation_response" = inflammation_genes) # compute scores from a list of signatures scores_for_list <- sparoscore(data = counts_sparse, signatures = gene_signatures) # view scores scores_for_list ``` ## Multiple signatures as a GeneSetCollection object ```{r genesetcollection} # create a GeneSetCollection object to score for both signatures simultaneously gene_set_collection <- GeneSetCollection( mapply(function(g, n) GeneSet(unique(g), setName = n), gene_signatures, names(gene_signatures)) ) # compute scores from a GeneSetCollection object scores_for_gsc <- sparoscore(data = counts_matrix, signatures = gene_set_collection) # view scores scores_for_gsc ``` # SummarizedExperiment and derived objects For SummarizedExperiment and its derived objects, after scoring, SPAROscore returns an object of the same class with the scores and the rank caps appended to the `colData`. The calculated gene ranks are added to a new assay named `ranks`. In this example, let us work with a SingleCellExperiment object ```{r sce} # convert airways to a SingleCellExperiment object airway_sce <- as(airway, "SingleCellExperiment") # view the metadata of the object pre-scoring colData(airway_sce) # view the assays present in the object pre-scoring assays(airway_sce) # compute scores for a SummarizedExperiment object airway_sce <- sparoscore(data = airway_sce, assay = "counts", signatures = response_genes) # view the metadata of the object after-scoring colData(airway_sce) # view the assays present in the object after-scoring assays(airway_sce) # the precomputed ranks can be reused for subsequent scoring runs airway_sce <- sparoscore(data=airway_sce, data_has_ranks = TRUE, assay = "ranks", signatures = inflammation_genes, prefix = "run2_") # view the metadata of the object after-scoring colData(airway_sce) ``` # Seurat objects For Seurat objects, after scoring, SPAROscore returns a Seurat object with the scores and the rank caps appended to the metadata. The ranks are stored in a layer named `ranks` in the same assay as the counts. ```{r seurat} # convert airway to a seurat object airway_seurat <- CreateSeuratObject( counts = assay(airway), meta.data = as.data.frame(colData(airway)), project = "Airway_Seurat" ) # view the metadata of the object pre-scoring airway_seurat[[]] # view all the layers in the object pre-scoring Layers(airway_seurat[["RNA"]]) # compute scores for a Seurat object airway_seurat <- sparoscore(data = airway_seurat, assay = "RNA", layer = "counts", signatures = response_genes) # view the metadata of the object after-scoring airway_seurat[[]] # view all the layers in the object after-scoring Layers(airway_seurat[["RNA"]]) # the precomputed ranks can be reused for subsequent scoring runs airway_seurat <- sparoscore(data = airway_seurat, data_has_ranks = TRUE, assay = "RNA", layer = "ranks", signatures = inflammation_genes, prefix = "run2_") # view the metadata of the object after-scoring airway_seurat[[]] ``` This vignette demonstrated the range of expression data containers and gene signature representations accepted by SPAROscore. Matrix-like inputs return score tables, while container objects such as SummarizedExperiment and Seurat are returned with scores and precomputed ranks integrated into the original object. This design allows SPAROscore to fit naturally into existing bulk RNA-seq, ingle-cell RNA-seq, and spatial transcriptomics workflows with minimal data conversion. For examples of in-depth transcriptomics analyses using SPAROscore, refer here: [Transcriptomics technologies](sparoscore_transcriptomics_technologies.html) For examples of additional options and advanced usage, see: [Advanced options](sparoscore_advanced_options.html) ```{r session-info} sessionInfo() ```