License: Artistic-2.0
GSVA provides now specific support for spatial omics data in the
algorithm that runs through the gsvaParam() parameter
constructor, and originally described in the publication by Hänzelmann et al. (2013). At the moment, this
specific support consists of the following features:
SpatialExperiment object.matrix or a dense DelayedMatrix object using
an HDF5Matrix backend. The latter will be particularly used
when the total number of values exceeds 2^31, which is the largest
32-bit standard integer value in R.sparse=FALSE in the call to gsvaParam(), the
classical GSVA algorithm will be used, which for a typical spatial omics
data set will result in longer running times and larger memory
consumption than running it in the default sparse regime for this type
of data.gsva() with a parameter object or in three steps: (1) row
normalization with gsvaRowNorm(); (2) column rank
transformation with gsvaColRanks(); and (3) column
enrichment scores calculation with gsvaColScores().
Splitting the GSVA algorithm into these three steps allows one to
distribute and balance the computational load of the algorithm in a
high-performance computing (HPC) environment with multiple nodes, and to
reuse the output of the first two steps, which are independent of the
gene sets, to calculate enrichment scores for different collections of
gene sets, without having to repeat the first two steps.In what follows, we will illustrate the use of GSVA on a publicly available spatial transcriptomics transcriptomics data set published by Maynard et al. (2021), which is available through the spatialLIBD package, and which contains 12 samples of human dorsolateral prefrontal cortex (DLPFC) tissue.
We import the DLPFC data using the spatialLIBD package, as a SpatialExperiment object, following the instructions at http://research.libd.org/spatialLIBD/articles/spatialLIBD.html.
library(SpatialExperiment)
library(ExperimentHub)
library(spatialLIBD)
ehub <- ExperimentHub()
spe <- fetch_data(type="spe", eh=ehub)Note that this data set contains 12 samples.
table(spe$sample_id)
151507 151508 151509 151510 151669 151670 151671 151672 151673 151674 151675
4226 4384 4789 4634 3661 3498 4110 4015 3639 3673 3592
151676
3460 For the purpose of speeding up processing this vignette, we will
analyze here only the sample with identifier 151673.
There is an indicator column called in_tissue for
identifying spots overlapping the tissue, but apparently all spots have
such a condition.
The column data includes a column called spatialLIBD
with anatomically annotated groups of spots (six cortical layers from
the grey matter and the white matter). This annotation is apparently
missing for a small number of spots, we are going to discard those
spots.
Here, we perform a quality control (QC) and pre-processing steps using the package scrapper (Lun and Kancherla 2022). We start identifying mitochondrial genes.
library(scrapper)
is_mito <- grepl("^MT-", rowData(spe)$gene_name)
table(is_mito)
is_mito
FALSE TRUE
33525 13 Calculate QC metrics and tally the number of low-quality spots.
spe <- quickRnaQc.se(spe, subsets=list(mito=is_mito))
spe$discard <- !spe$keep
table(spe$discard)
FALSE TRUE
3566 45 Plot detected low-quality spots to ensure they are not located in a specific region of the tissue.
Detected low-quality spots in the DLPFC sample 151673.
Filter out low-quality spots.
Filter out genes that are expressed in less than 1% of the spots.
spotsxgene <- rowSums(counts(spe) > 0)
spe <- spe[spotsxgene > floor(ncol(spe)*0.01), ]
dim(spe)
[1] 13842 3566Calculate library size factors and normalized units of expression in logarithmic scale.
Here we use the a collection of brain cell-type marker genes derived from the single-nuclei RNA-seq (snRNA-seq) data set published by Tran et al. (2021), to estimate the most abundant cell type in each spot of the DLPFC sample 151673. This collection of marker gene sets is available in the GSVAdata package, which contains the script that generated the marker gene sets, and can be imported as follows.
library(GSEABase)
library(GSVA)
fname <- file.path(system.file("extdata", package="GSVAdata"),
"human_brain_snRNAseq_cellType_markers.gmt.gz")
gsets <- readGMT(fname)
gsets
GeneSetCollection
names: Astro, Excit_A, ..., Tcell (19 total)
unique identifiers: ENSG00000164199, ENSG00000234377, ..., ENSG00000089335 (1188 total)
types in collection:
geneIdType: ENSEMBLIdentifier (1 total)
collectionType: NullCollection (1 total)We first build a parameter object using the function
gsvaParam(). By default, the expression values in the
logcounts assay will be selected for downstream
analysis.
gsvapar <- gsvaParam(spe, gsets)
gsvapar
class: GSVA::gsvaParam
expression data dim: 13842 3566
number of gene sets: 19
details: use 'details(object)'Second, we call the gsva() function to calculate the
GSVA scores for each spot and each gene set. The output will be a
SpatialExperiment object with the GSVA scores stored in a
new assay called es. When the input spatial omics data is
very large, you can use the three-step approach described in the
single-cell RNA-seq vignette.
es <- gsva(gsvapar)
es
class: SpatialExperiment
dim: 19 3566
metadata(2): qc gsvaParam
assays(1): es
rownames(19): Astro Excit_A ... OPC Tcell
rowData names(1): gs
colnames(3566): AAACAAGTATCTCCCA-1 AAACAATCTACTAGCA-1 ...
TTGTTTGTATTACACG-1 TTGTTTGTGTAAATTC-1
colData names(74): sample_id Cluster ... keep sizeFactor
reducedDimNames(6): PCA TSNE_perplexity50 ... TSNE_perplexity80
UMAP_neighbors15
mainExpName: NULL
altExpNames(0):
spatialCoords names(2) : pxl_col_in_fullres pxl_row_in_fullres
imgData names(4): sample_id image_id data scaleFactorFinally, we assign to each spot the gene set with highest GSVA score,
and store that assignment as a new metadata column into the
spe object.
Figure @ref(fig:dlpfcgsva) shows the annotated layers of the DLPFC data set and the spatial distribution of the most likely cell type in each spot, based on the GSVA scores.
library(ggspavis)
library(patchwork)
library(RColorBrewer)
ctpal <- colorRampPalette(brewer.pal(9, "Set1"))(nlevels(es$cellType))
plts <- list(plotVisium(spe, point_size=0.60, facets=NULL, annotate="spatialLIBD",
pal=brewer.pal(nlevels(spe$spatialLIBD), "Set1")) +
labs(tag="a"),
plotVisium(es, assay="es", point_size=0.60, facets=NULL,
annotate="cellType",
pal=ctpal) +
labs(tag="b")
)
wrap_plots(plts, nrow=1)
spatCor() implemented
also in the GSVA package, which can take as input the
SpatialExperiment object with the GSVA scores obtained in
the previous step.
I <- spatCor(es)
I[order(I$observed, decreasing=TRUE), ]
gene_id observed expected sd p.value sample_id
17 Oligo 0.612102836 -0.0002805049 0.002605108 0.0000000000 151673
3 Excit_B 0.407928577 -0.0002805049 0.002606096 0.0000000000 151673
4 Excit_C 0.359016955 -0.0002805049 0.002606089 0.0000000000 151673
19 Tcell 0.342641318 -0.0002805049 0.002606179 0.0000000000 151673
15 Micro 0.325299838 -0.0002805049 0.002606098 0.0000000000 151673
6 Excit_E 0.318354412 -0.0002805049 0.002606208 0.0000000000 151673
18 OPC 0.312038618 -0.0002805049 0.002606022 0.0000000000 151673
2 Excit_A 0.298156172 -0.0002805049 0.002606154 0.0000000000 151673
7 Excit_F 0.265523623 -0.0002805049 0.002606211 0.0000000000 151673
5 Excit_D 0.190184460 -0.0002805049 0.002606038 0.0000000000 151673
8 Inhib_A 0.186672620 -0.0002805049 0.002605990 0.0000000000 151673
16 Mural 0.181292594 -0.0002805049 0.002606086 0.0000000000 151673
9 Inhib_B 0.169324164 -0.0002805049 0.002605999 0.0000000000 151673
1 Astro 0.152319427 -0.0002805049 0.002605916 0.0000000000 151673
11 Inhib_D 0.137978863 -0.0002805049 0.002605837 0.0000000000 151673
10 Inhib_C 0.136515026 -0.0002805049 0.002605912 0.0000000000 151673
14 Macrophage 0.126416993 -0.0002805049 0.002606060 0.0000000000 151673
12 Inhib_E 0.095574372 -0.0002805049 0.002606035 0.0000000000 151673
13 Inhib_F 0.008786699 -0.0002805049 0.002606099 0.0005028671 151673We can observe that the Oligo gene set has the highest
Moran’s I statistic, which follows from the spatial distribution of the
GSVA scores for that gene set, which is shown in Figure
@ref(fig:dlpfcgsvaoligo).
Spatial distribution of the GSVA scores for the Oligodendrocytes gene set in the DLPFC sample 151673.
We are still benchmarking and testing this version of GSVA for spatial omics data. If you encounter problems or have suggestions, do not hesitate to contact us by opening an issue in the GSVA GitHub repo.
Here is the output of sessionInfo() on the system on
which this document was compiled running pandoc 3.8.3:
sessionInfo()
R version 4.6.1 (2026-06-24)
Platform: x86_64-pc-linux-gnu
Running under: Ubuntu 26.04 LTS
Matrix products: default
BLAS: /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3
LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.32.so; LAPACK version 3.12.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: Etc/UTC
tzcode source: system (glibc)
attached base packages:
[1] stats4 stats graphics grDevices utils datasets methods
[8] base
other attached packages:
[1] patchwork_1.3.2 ggspavis_1.19.1
[3] ggplot2_4.0.3 spatialLIBD_1.25.2
[5] ExperimentHub_3.3.1 AnnotationHub_4.3.2
[7] BiocFileCache_3.3.0 dbplyr_2.6.0
[9] SpatialExperiment_1.23.0 RColorBrewer_1.1-3
[11] igraph_2.3.3 bluster_1.23.0
[13] scrapper_1.7.3 TENxPBMCData_1.31.0
[15] HDF5Array_1.41.0 h5mread_1.5.0
[17] rhdf5_2.57.3 DelayedArray_0.39.3
[19] SparseArray_1.13.2 S4Arrays_1.13.0
[21] abind_1.4-8 Matrix_1.7-6
[23] SingleCellExperiment_1.35.2 org.Hs.eg.db_3.23.1
[25] GSVAdata_1.49.2 GSEABase_1.75.0
[27] graph_1.91.0 annotate_1.91.0
[29] XML_3.99-0.23 AnnotationDbi_1.75.2
[31] GSVA_2.7.12 SummarizedExperiment_1.43.0
[33] Biobase_2.73.2 GenomicRanges_1.65.1
[35] Seqinfo_1.3.0 IRanges_2.47.2
[37] S4Vectors_0.51.6 BiocGenerics_0.59.10
[39] generics_0.1.4 MatrixGenerics_1.25.0
[41] matrixStats_1.5.0 BiocStyle_2.41.0
loaded via a namespace (and not attached):
[1] later_1.4.8 BiocIO_1.23.3
[3] bitops_1.0-9 filelock_1.0.3
[5] tibble_3.3.1 lifecycle_1.0.5
[7] httr2_1.3.0 edgeR_4.11.4
[9] doParallel_1.0.17 lattice_0.22-9
[11] magrittr_2.0.5 limma_3.69.2
[13] plotly_4.12.1 sass_0.4.10
[15] rmarkdown_2.31 jquerylib_0.1.4
[17] yaml_2.3.12 httpuv_1.6.17
[19] otel_0.2.0 ggside_0.4.1
[21] sessioninfo_1.2.4 cowplot_1.2.0
[23] DBI_1.3.0 buildtools_1.0.0
[25] golem_1.0.1 purrr_1.2.2
[27] RCurl_1.98-1.19 rappdirs_0.3.4
[29] circlize_0.4.18 ggrepel_0.9.8
[31] irlba_2.3.7 maketools_1.3.2
[33] DelayedMatrixStats_1.35.0 codetools_0.2-20
[35] scuttle_1.23.1 DT_0.34.0
[37] tidyselect_1.2.1 shape_1.4.6.1
[39] memuse_4.2-3 farver_2.1.2
[41] viridis_0.6.5 ScaledMatrix_1.21.0
[43] shinyWidgets_0.9.1 GenomicAlignments_1.49.1
[45] jsonlite_2.0.0 GetoptLong_1.1.1
[47] BiocNeighbors_2.7.2 scater_1.41.2
[49] iterators_1.0.14 foreach_1.5.2
[51] tools_4.6.1 Rcpp_1.1.2
[53] glue_1.8.1 gridExtra_2.3.1
[55] BiocBaseUtils_1.15.1 xfun_0.60
[57] dplyr_1.2.1 withr_3.0.3
[59] BiocManager_1.30.27 fastmap_1.2.0
[61] rhdf5filters_1.25.3 digest_0.6.39
[63] rsvd_1.0.5 R6_2.6.1
[65] mime_0.13 colorspace_2.1-3
[67] RSQLite_3.53.3 cigarillo_1.3.1
[69] config_0.3.2 tidyr_1.3.2
[71] data.table_1.18.4 rtracklayer_1.73.0
[73] httr_1.4.8 htmlwidgets_1.6.4
[75] pkgconfig_2.0.3 gtable_0.3.6
[77] blob_1.3.0 ComplexHeatmap_2.29.0
[79] S7_0.2.2 XVector_0.53.0
[81] sys_3.4.3 htmltools_0.5.9
[83] clue_0.3-68 scales_1.4.0
[85] png_0.1-9 attempt_0.3.1
[87] knitr_1.51 rjson_0.2.23
[89] curl_7.1.0 cachem_1.1.0
[91] GlobalOptions_0.1.4 stringr_1.6.0
[93] BiocVersion_3.24.0 vipor_0.4.7
[95] parallel_4.6.1 restfulr_0.0.17
[97] pillar_1.11.1 grid_4.6.1
[99] vctrs_0.7.3 promises_1.5.0
[101] BiocSingular_1.29.0 beachmat_2.29.0
[103] xtable_1.8-8 cluster_2.1.8.2
[105] beeswarm_0.4.0 paletteer_1.7.0
[107] evaluate_1.0.5 magick_2.9.1
[109] Rsamtools_2.29.0 cli_3.6.6
[111] locfit_1.5-9.12 compiler_4.6.1
[113] rlang_1.3.0 crayon_1.5.3
[115] labeling_0.4.3 rematch2_2.1.2
[117] ggbeeswarm_0.7.3 stringi_1.8.7
[119] viridisLite_0.4.3 BiocParallel_1.47.0
[121] Biostrings_2.81.6 benchmarkme_1.0.8
[123] sparseMatrixStats_1.25.0 bit64_4.8.2
[125] Rhdf5lib_2.1.0 KEGGREST_1.53.6
[127] statmod_1.5.2 shiny_1.14.0
[129] memoise_2.0.1 bslib_0.11.0
[131] benchmarkmeData_2.0.0 bit_4.6.0