scider is a user-friendly R package providing functions to model the global density of cells in a slide of spatial transcriptomics data. All functions in the package are built based on the SpatialExperiment object, allowing integration into various spatial transcriptomics-related packages from Bioconductor. After modelling density, the package allows for serveral downstream analysis, including colocalization analysis, boundary detection analysis and differential density analysis.
if (!require("BiocManager", quietly = TRUE)) {
install.packages("BiocManager")
}
BiocManager::install("scider")
The development version of scider
can be installed from GitHub:
In this vignette, we will use a subset of a Xenium Breast Cancer dataset.
In the data, we have quantification of 541 genes from 10000 cells.
## class: SpatialExperiment
## dim: 541 10000
## metadata(0):
## assays(1): counts
## rownames(541): ENSG00000121270 ENSG00000213088 ... BLANK_0444
## BLANK_0447
## rowData names(3): ID Symbol Type
## colnames(10000): cell_212124 cell_120108 ... cell_252054 cell_568560
## colData names(21): cell_id transcript_counts ... cell_type sample_id
## reducedDimNames(0):
## mainExpName: NULL
## altExpNames(0):
## spatialCoords names(2) : x_centroid y_centroid
## imgData names(1): sample_id
We also have cell-type annotations of these cells, there are 4 cell types.
##
## B cells Breast cancer Fibroblasts T cells
## 643 3550 4234 1573
We can use the function plotSpatial
to visualise the cell position and color the cells by cell types.
scider
can conduct grid-based density analysis for spatial transcriptomics data.
Before calculating density, we need to define cell type-of-interest (COI). In this case, all cell types are COIs.
## [1] "Fibroblasts" "Breast cancer" "T cells" "B cells"
We can perform density calculation for each COI using function gridDensity
. The calculated density and grid information are saved in the metadata of the SpatialExperimnet object.
## [1] "grid_density" "grid_info"
## DataFrame with 11400 rows and 9 columns
## x_grid y_grid node_x node_y node density_fibroblasts
## <numeric> <numeric> <integer> <integer> <character> <numeric>
## 1 329.102 203.852 1 1 1-1 0.00352639
## 2 329.102 299.810 1 2 1-2 0.00432724
## 3 329.102 395.767 1 3 1-3 0.00526027
## 4 329.102 491.725 1 4 1-4 0.00633438
## 5 329.102 587.683 1 5 1-5 0.00755759
## ... ... ... ... ... ... ...
## 11396 9865.73 10663.2 100 110 100-110 0.00743260
## 11397 9865.73 10759.2 100 111 100-111 0.00601659
## 11398 9865.73 10855.2 100 112 100-112 0.00482908
## 11399 9865.73 10951.1 100 113 100-113 0.00384286
## 11400 9865.73 11047.1 100 114 100-114 0.00303176
## density_breast_cancer density_t_cells density_b_cells
## <numeric> <numeric> <numeric>
## 1 0.000124482 0.00200091 0.00308062
## 2 0.000158866 0.00269403 0.00447254
## 3 0.000207521 0.00360691 0.00639036
## 4 0.000278528 0.00478231 0.00893371
## 5 0.000385603 0.00624991 0.01215386
## ... ... ... ...
## 11396 0.00992645 1.85862e-05 0.000385502
## 11397 0.00715312 9.95949e-06 0.000337516
## 11398 0.00504125 5.53001e-06 0.000288967
## 11399 0.00348873 3.29144e-06 0.000242472
## 11400 0.00237981 2.14802e-06 0.000199856
We can visualise the density of each COI using function plotDensity
.
After obtaining grid-based density for each COI, we can then detect regions-of-interest (ROIs) based on density or select by user.
To detect ROIs automatically, we can use the function findROI
.
The detected ROIs are saved in the metadata of the SpatialExperiment object.
## DataFrame with 1464 rows and 6 columns
## component members x y xcoord ycoord
## <factor> <character> <character> <character> <numeric> <numeric>
## 1 1 83-107 83 107 8228.13 10375.37
## 2 1 83-108 83 108 8228.13 10471.33
## 3 1 84-107 84 107 8324.46 10375.37
## 4 1 84-108 84 108 8324.46 10471.33
## 5 1 85-102 85 102 8420.79 9895.58
## ... ... ... ... ... ... ...
## 1460 29 53-104 53 104 5338.24 10087.5
## 1461 29 53-105 53 105 5338.24 10183.5
## 1462 29 53-106 53 106 5338.24 10279.4
## 1463 29 54-105 54 105 5434.57 10183.5
## 1464 29 54-106 54 106 5434.57 10279.4
We can visualise the ROIs with function plotROI
.
Alternatively, users can select ROIs based on their own research interest (drawn by hand). This can be done using function selectRegion
. This function will open an interactive window with an interactive plot for users to zoom-in/-out and select ROI using either a rectangular or lasso selection tool. Users can also press the Export selected points
button to save the ROIs as object in the R environment.
After closing the interactive window, the selected ROI has been saved as a data.frame object named sel_region
in the R environment.
We can then use the postSelRegion
to save the ROI in the metadata of the SpatialExperiment object.
Similarly, we can plot visualise the user-defined ROI with function plotROI
.
After defining ROIs, we can then test the relationship between any two cell types within each ROI or overall but account for ROI variation using a cubic spline or a linear fit.
This can be done with function corrDensity
, by setting the celltype1
and celltype2
parameters, the modelling results are saved in the metadata of the SpatialExperiment object.
We can see the correlation between breast cancer and fibroblasts in each ROI.
## DataFrame with 174 rows and 9 columns
## celltype1 celltype2 ROI ngrid cor.coef t
## <character> <character> <character> <numeric> <numeric> <numeric>
## 1 Fibroblasts Breast cancer 1 25 -0.4212512 -2.227535
## 2 Fibroblasts Breast cancer 2 106 -0.5961093 -7.571454
## 3 Fibroblasts Breast cancer 3 27 -0.9058793 -10.694243
## 4 Fibroblasts Breast cancer 4 42 -0.9245825 -15.348691
## 5 Fibroblasts Breast cancer 5 36 -0.0392948 -0.229303
## ... ... ... ... ... ... ...
## 170 T cells B cells 25 25 0.459082 2.478267
## 171 T cells B cells 26 29 0.865404 8.974262
## 172 T cells B cells 27 21 -0.248482 -1.118180
## 173 T cells B cells 28 38 0.628826 4.852386
## 174 T cells B cells 29 22 0.110237 0.496019
## df p.Pos p.Neg
## <numeric> <numeric> <numeric>
## 1 23 0.982010 1.79903e-02
## 2 104 1.000000 7.83173e-12
## 3 25 1.000000 4.06755e-11
## 4 40 1.000000 1.16320e-18
## 5 34 0.589996 4.10004e-01
## ... ... ... ...
## 170 23 1.04871e-02 0.989513
## 171 27 6.86205e-10 1.000000
## 172 19 8.61285e-01 0.138715
## 173 36 1.17842e-05 0.999988
## 174 20 3.12644e-01 0.687356
We can also visualise the fitting using function plotDensCor
.
Or, we can visualise the statistics between cell types using function plotModStat
with a heatmap.
Based on the grid density, we can ask many biological question about the data. For example, we would like to know if a certain cell type that are located in high density of breast cancer cells are different to the same cell type from a different level of breast cancer region.
To address this question, we first need to divide cells into different levels of grid density. This can be done using a contour identification strategy with function getContour
.
Different level of contour can be visualised with cells using plotContour
.
We can then annotate cells by their locations within each contour using function allocateCells
.
We can visualise cell type composition per level.
## R version 4.4.1 (2024-06-14)
## Platform: x86_64-pc-linux-gnu
## Running under: Ubuntu 24.04.1 LTS
##
## Matrix products: default
## BLAS: /home/biocbuild/bbs-3.20-bioc/R/lib/libRblas.so
## LAPACK: /usr/lib/x86_64-linux-gnu/lapack/liblapack.so.3.12.0
##
## locale:
## [1] LC_CTYPE=en_US.UTF-8 LC_NUMERIC=C
## [3] LC_TIME=en_GB 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: America/New_York
## tzcode source: system (glibc)
##
## attached base packages:
## [1] stats4 stats graphics grDevices utils datasets methods
## [8] base
##
## other attached packages:
## [1] sf_1.0-18 SpatialExperiment_1.16.0
## [3] SingleCellExperiment_1.28.0 SummarizedExperiment_1.36.0
## [5] Biobase_2.66.0 GenomicRanges_1.58.0
## [7] GenomeInfoDb_1.42.0 IRanges_2.40.0
## [9] S4Vectors_0.44.0 BiocGenerics_0.52.0
## [11] MatrixGenerics_1.18.0 matrixStats_1.4.1
## [13] scider_1.4.0 ggplot2_3.5.1
##
## loaded via a namespace (and not attached):
## [1] DBI_1.2.3 deldir_2.0-4 rlang_1.1.4
## [4] magrittr_2.0.3 snakecase_0.11.1 e1071_1.7-16
## [7] compiler_4.4.1 spatstat.geom_3.3-3 mgcv_1.9-1
## [10] fftwtools_0.9-11 vctrs_0.6.5 stringr_1.5.1
## [13] pkgconfig_2.0.3 crayon_1.5.3 fastmap_1.2.0
## [16] magick_2.8.5 XVector_0.46.0 lwgeom_0.2-14
## [19] labeling_0.4.3 utf8_1.2.4 promises_1.3.0
## [22] rmarkdown_2.28 UCSC.utils_1.2.0 purrr_1.0.2
## [25] xfun_0.48 zlibbioc_1.52.0 cachem_1.1.0
## [28] jsonlite_1.8.9 goftest_1.2-3 highr_0.11
## [31] later_1.3.2 DelayedArray_0.32.0 spatstat.utils_3.1-0
## [34] R6_2.5.1 RColorBrewer_1.1-3 bslib_0.8.0
## [37] stringi_1.8.4 spatstat.data_3.1-2 spatstat.univar_3.0-1
## [40] lubridate_1.9.3 jquerylib_0.1.4 Rcpp_1.0.13
## [43] knitr_1.48 tensor_1.5 splines_4.4.1
## [46] httpuv_1.6.15 Matrix_1.7-1 igraph_2.1.1
## [49] timechange_0.3.0 tidyselect_1.2.1 abind_1.4-8
## [52] yaml_2.3.10 spatstat.random_3.3-2 spatstat.explore_3.3-3
## [55] lattice_0.22-6 tibble_3.2.1 shiny_1.9.1
## [58] withr_3.0.2 evaluate_1.0.1 isoband_0.2.7
## [61] units_0.8-5 proxy_0.4-27 polyclip_1.10-7
## [64] pillar_1.9.0 KernSmooth_2.23-24 plotly_4.10.4
## [67] generics_0.1.3 munsell_0.5.1 scales_1.3.0
## [70] xtable_1.8-4 class_7.3-22 glue_1.8.0
## [73] janitor_2.2.0 pheatmap_1.0.12 lazyeval_0.2.2
## [76] tools_4.4.1 data.table_1.16.2 grid_4.4.1
## [79] tidyr_1.3.1 colorspace_2.1-1 nlme_3.1-166
## [82] GenomeInfoDbData_1.2.13 cli_3.6.3 spatstat.sparse_3.1-0
## [85] fansi_1.0.6 S4Arrays_1.6.0 viridisLite_0.4.2
## [88] dplyr_1.1.4 gtable_0.3.6 sass_0.4.9
## [91] digest_0.6.37 classInt_0.4-10 SparseArray_1.6.0
## [94] rjson_0.2.23 htmlwidgets_1.6.4 farver_2.1.2
## [97] htmltools_0.5.8.1 lifecycle_1.0.4 httr_1.4.7
## [100] mime_0.12