Here, we demonstrate BANKSY domain segmentation on a STARmap PLUS dataset of the mouse brain from Shi et al. (2022).
library(Banksy)
library(data.table)
library(SummarizedExperiment)
library(SpatialExperiment)
library(scater)
library(cowplot)
library(ggplot2)
Data from the study is available from the Single
Cell Portal. We analyze data from well11
. The data
comprise 1,022 genes profiled at subcellular resolution in 43,341
cells.
#' Change paths accordingly
gcm_path <- "../data/well11processed_expression_pd.csv.gz"
mdata_path <- "../data/well11_spatial.csv.gz"
#' Gene cell matrix
gcm <- fread(gcm_path)
genes <- gcm$GENE
gcm <- as.matrix(gcm[, -1])
rownames(gcm) <- genes
#' Spatial coordinates and metadata
mdata <- fread(mdata_path, skip = 1)
headers <- names(fread(mdata_path, nrows = 0))
colnames(mdata) <- headers
#' Orient spatial coordinates
xx <- mdata$X
yy <- mdata$Y
mdata$X <- max(yy) - yy
mdata$Y <- max(xx) - xx
mdata <- data.frame(mdata)
rownames(mdata) <- colnames(gcm)
locs <- as.matrix(mdata[, c("X", "Y", "Z")])
#' Create SpatialExperiment
se <- SpatialExperiment(
assay = list(processedExp = gcm),
spatialCoords = locs,
colData = mdata
)
Run BANKSY in domain segmentation mode with lambda=0.8
.
This places larger weights on the mean neighborhood expression and
azimuthal Gabor filter in constructing the BANKSY matrix. We adjust the
resolution to yield 23 clusters based on the results from Maher et
al. (2023) (see Fig. 1, 2).
lambda <- 0.8
k_geom <- 30
npcs <- 50
aname <- "processedExp"
se <- Banksy::computeBanksy(se, assay_name = aname, k_geom = k_geom)
set.seed(1000)
se <- Banksy::runBanksyPCA(se, lambda = lambda, npcs = npcs)
set.seed(1000)
se <- Banksy::clusterBanksy(se, lambda = lambda, npcs = npcs, resolution = 0.8)
Cluster labels are stored in the colData
slot:
head(colData(se))
#> DataFrame with 6 rows and 4 columns
#> X Y clust_M1_lam0.8_k50_res0.8 sample_id
#> <numeric> <numeric> <factor> <character>
#> 1 24225.5 23984.2 10 sample01
#> 2 24849.2 22679.1 10 sample01
#> 3 24488.3 22970.3 10 sample01
#> 4 24371.4 23727.5 10 sample01
#> 5 24362.2 23300.6 10 sample01
#> 6 24644.5 23112.8 10 sample01
Visualize clustering results:
cnames <- colnames(colData(se))
cnames <- cnames[grep("^clust", cnames)]
plotColData(se, x = "X", y = "Y", point_size = 0.01, colour_by = cnames[1]) +
scale_color_manual(values = pals::glasbey()) +
coord_equal() +
theme(legend.position = "none")
sessionInfo()
#> R version 4.4.2 (2024-10-31)
#> Platform: x86_64-pc-linux-gnu
#> Running under: Ubuntu 24.04.1 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.26.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=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
#>
#> 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] ExperimentHub_2.15.0 AnnotationHub_3.15.0
#> [3] BiocFileCache_2.15.0 dbplyr_2.5.0
#> [5] spatialLIBD_1.18.0 cowplot_1.1.3
#> [7] scater_1.35.0 ggplot2_3.5.1
#> [9] harmony_1.2.3 Rcpp_1.0.13-1
#> [11] data.table_1.16.2 scran_1.35.0
#> [13] scuttle_1.17.0 Seurat_5.1.0
#> [15] SeuratObject_5.0.2 sp_2.1-4
#> [17] SpatialExperiment_1.17.0 SingleCellExperiment_1.29.1
#> [19] SummarizedExperiment_1.37.0 Biobase_2.67.0
#> [21] GenomicRanges_1.59.1 GenomeInfoDb_1.43.2
#> [23] IRanges_2.41.1 S4Vectors_0.45.2
#> [25] BiocGenerics_0.53.3 generics_0.1.3
#> [27] MatrixGenerics_1.19.0 matrixStats_1.4.1
#> [29] Banksy_1.3.0 BiocStyle_2.35.0
#>
#> loaded via a namespace (and not attached):
#> [1] bitops_1.0-9 spatstat.sparse_3.1-0 doParallel_1.0.17
#> [4] httr_1.4.7 RColorBrewer_1.1-3 tools_4.4.2
#> [7] sctransform_0.4.1 DT_0.33 utf8_1.2.4
#> [10] R6_2.5.1 lazyeval_0.2.2 uwot_0.2.2
#> [13] withr_3.0.2 gridExtra_2.3 progressr_0.15.1
#> [16] cli_3.6.3 spatstat.explore_3.3-3 fastDummies_1.7.4
#> [19] labeling_0.4.3 sass_0.4.9 spatstat.data_3.1-4
#> [22] ggridges_0.5.6 pbapply_1.7-2 Rsamtools_2.23.1
#> [25] dbscan_1.2-0 aricode_1.0.3 dichromat_2.0-0.1
#> [28] sessioninfo_1.2.2 parallelly_1.39.0 attempt_0.3.1
#> [31] maps_3.4.2.1 limma_3.63.2 pals_1.9
#> [34] RSQLite_2.3.8 BiocIO_1.17.1 ica_1.0-3
#> [37] spatstat.random_3.3-2 dplyr_1.1.4 Matrix_1.7-1
#> [40] ggbeeswarm_0.7.2 fansi_1.0.6 abind_1.4-8
#> [43] lifecycle_1.0.4 yaml_2.3.10 edgeR_4.5.0
#> [46] SparseArray_1.7.2 Rtsne_0.17 paletteer_1.6.0
#> [49] grid_4.4.2 blob_1.2.4 promises_1.3.2
#> [52] dqrng_0.4.1 crayon_1.5.3 miniUI_0.1.1.1
#> [55] lattice_0.22-6 beachmat_2.23.2 mapproj_1.2.11
#> [58] KEGGREST_1.47.0 magick_2.8.5 sys_3.4.3
#> [61] maketools_1.3.1 pillar_1.9.0 knitr_1.49
#> [64] metapod_1.15.0 rjson_0.2.23 future.apply_1.11.3
#> [67] codetools_0.2-20 leiden_0.4.3.1 glue_1.8.0
#> [70] spatstat.univar_3.1-1 vctrs_0.6.5 png_0.1-8
#> [73] spam_2.11-0 gtable_0.3.6 rematch2_2.1.2
#> [76] cachem_1.1.0 xfun_0.49 S4Arrays_1.7.1
#> [79] mime_0.12 survival_3.7-0 RcppHungarian_0.3
#> [82] iterators_1.0.14 fields_16.3 statmod_1.5.0
#> [85] bluster_1.17.0 fitdistrplus_1.2-1 ROCR_1.0-11
#> [88] nlme_3.1-166 bit64_4.5.2 filelock_1.0.3
#> [91] RcppAnnoy_0.0.22 bslib_0.8.0 irlba_2.3.5.1
#> [94] vipor_0.4.7 KernSmooth_2.23-24 colorspace_2.1-1
#> [97] DBI_1.2.3 tidyselect_1.2.1 bit_4.5.0
#> [100] compiler_4.4.2 curl_6.0.1 BiocNeighbors_2.1.1
#> [103] DelayedArray_0.33.2 plotly_4.10.4 rtracklayer_1.67.0
#> [106] scales_1.3.0 lmtest_0.9-40 rappdirs_0.3.3
#> [109] stringr_1.5.1 digest_0.6.37 goftest_1.2-3
#> [112] spatstat.utils_3.1-1 rmarkdown_2.29 benchmarkmeData_1.0.4
#> [115] RhpcBLASctl_0.23-42 XVector_0.47.0 htmltools_0.5.8.1
#> [118] pkgconfig_2.0.3 fastmap_1.2.0 rlang_1.1.4
#> [121] htmlwidgets_1.6.4 UCSC.utils_1.3.0 shiny_1.9.1
#> [124] farver_2.1.2 jquerylib_0.1.4 zoo_1.8-12
#> [127] jsonlite_1.8.9 BiocParallel_1.41.0 mclust_6.1.1
#> [130] config_0.3.2 RCurl_1.98-1.16 BiocSingular_1.23.0
#> [133] magrittr_2.0.3 GenomeInfoDbData_1.2.13 dotCall64_1.2
#> [136] patchwork_1.3.0 munsell_0.5.1 viridis_0.6.5
#> [139] reticulate_1.40.0 leidenAlg_1.1.4 stringi_1.8.4
#> [142] zlibbioc_1.52.0 MASS_7.3-61 plyr_1.8.9
#> [145] parallel_4.4.2 listenv_0.9.1 ggrepel_0.9.6
#> [148] deldir_2.0-4 Biostrings_2.75.1 sccore_1.0.5
#> [151] splines_4.4.2 tensor_1.5 locfit_1.5-9.10
#> [154] igraph_2.1.1 spatstat.geom_3.3-4 RcppHNSW_0.6.0
#> [157] buildtools_1.0.0 reshape2_1.4.4 ScaledMatrix_1.15.0
#> [160] XML_3.99-0.17 BiocVersion_3.21.1 evaluate_1.0.1
#> [163] golem_0.5.1 BiocManager_1.30.25 foreach_1.5.2
#> [166] httpuv_1.6.15 RANN_2.6.2 tidyr_1.3.1
#> [169] purrr_1.0.2 polyclip_1.10-7 benchmarkme_1.0.8
#> [172] future_1.34.0 scattermore_1.2 rsvd_1.0.5
#> [175] xtable_1.8-4 restfulr_0.0.15 RSpectra_0.16-2
#> [178] later_1.4.1 viridisLite_0.4.2 tibble_3.2.1
#> [181] GenomicAlignments_1.43.0 memoise_2.0.1 beeswarm_0.4.0
#> [184] AnnotationDbi_1.69.0 cluster_2.1.6 shinyWidgets_0.8.7
#> [187] globals_0.16.3