# Using SuperCellCyto for Stratified Summarising

Have you been following the vignette on how to create supercells, and wonder whether it is possible to use `SuperCellCyto` as a replacement for stratified sampling to avoid overcrowding UMAP/tSNE plot?

The short answer to that is, yes we can. We call this stratified summarising, and `SuperCellCyto` can be used for this purpose. To do this, all we need to do is simply set the sample column of our data to not be the biological sample the cell came from, but rather` the column we want to stratify the data based on.

For example, when drawing UMAP or tSNE plot, we commonly subsample each cluster or cell type to avoid crowding the plot. Instead of subsampling, we can generate supercells for each cluster or cell type simply by specifying the column that denotes the cluster or cell type each cell belong to as the `sample_colname` parameter!

Let’s illustrate this using a clustered (using k-means) toy data.

    library(SuperCellCyto)

    set.seed(42)

    # Simulate some data
    dat <- simCytoData()
    markers_col <- paste0("Marker_", seq_len(10))
    cell_id_col <- "Cell_Id"

    # Run kmeans
    clust <- kmeans(
        x = dat[, markers_col, with = FALSE],
        centers = 5
    )

    clust_col <- "kmeans_clusters"
    dat[[clust_col]] <- paste0("cluster_", clust$cluster)

To perform stratified summarising, we supply the cluster column (`kmeans_clusters` in the example above), as `runSuperCellCyto`’s `sample_colname` parameter.

    supercells <- runSuperCellCyto(
        dt = dat,
        markers = markers_col,
        sample_colname = clust_col,
        cell_id_colname = cell_id_col
    )

Now, if we look at the `supercell_expression_matrix`, each row (each supercell) will be denoted with the cluster it belongs to, and not the biological sample it came from:

    # Inspect the top 3 and bottom 3 of the expression matrix and some columns.
    rbind(
        head(supercells$supercell_expression_matrix, n = 3),
        tail(supercells$supercell_expression_matrix, n = 3)
    )[, c("kmeans_clusters", "SuperCellId", "Marker_10")]
    #>    kmeans_clusters                    SuperCellId Marker_10
    #>             <char>                         <char>     <num>
    #> 1:       cluster_4   SuperCell_1_Sample_cluster_4  14.64662
    #> 2:       cluster_4   SuperCell_2_Sample_cluster_4  14.66858
    #> 3:       cluster_4   SuperCell_3_Sample_cluster_4  14.41837
    #> 4:       cluster_5 SuperCell_498_Sample_cluster_5  16.99003
    #> 5:       cluster_5 SuperCell_499_Sample_cluster_5  17.09864
    #> 6:       cluster_5 SuperCell_500_Sample_cluster_5  15.85447

If we look at the number of supercells created and check how many cells there were in each cluster, we will find that, for each cluster, we get approximately `n_cells_in_the_cluster/20` where 20 is the `gam` parameter value we used for `runSuperCellCyto` (this is the default).

    # Compute how many cells per cluster, and divide by 20, the gamma value.
    table(dat$kmeans_clusters) / 20
    #>
    #> cluster_1 cluster_2 cluster_3 cluster_4 cluster_5
    #>    120.25    130.30    119.75    129.70    500.00

    table(supercells$supercell_expression_matrix$kmeans_clusters)
    #>
    #> cluster_1 cluster_2 cluster_3 cluster_4 cluster_5
    #>       120       130       120       130       500

## Session information

    sessionInfo()
    #> R version 4.5.2 (2025-10-31)
    #> Platform: x86_64-pc-linux-gnu
    #> Running under: Ubuntu 24.04.3 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    parallel  stats     graphics  grDevices utils     datasets
    #> [8] methods   base
    #>
    #> other attached packages:
    #>  [1] future_1.69.0               Seurat_5.4.0
    #>  [3] SeuratObject_5.3.0          sp_2.2-0
    #>  [5] qs2_0.1.7                   bluster_1.20.0
    #>  [7] scater_1.38.0               ggplot2_4.0.1
    #>  [9] BiocSingular_1.26.1         scran_1.38.0
    #> [11] scuttle_1.20.0              SingleCellExperiment_1.32.0
    #> [13] SummarizedExperiment_1.40.0 Biobase_2.70.0
    #> [15] GenomicRanges_1.62.1        Seqinfo_1.0.0
    #> [17] IRanges_2.44.0              S4Vectors_0.48.0
    #> [19] BiocGenerics_0.56.0         generics_0.1.4
    #> [21] MatrixGenerics_1.22.0       matrixStats_1.5.0
    #> [23] flowCore_2.22.1             data.table_1.18.2.1
    #> [25] BiocParallel_1.44.0         SuperCellCyto_1.0.0
    #> [27] BiocStyle_2.38.0
    #>
    #> loaded via a namespace (and not attached):
    #>   [1] RcppAnnoy_0.0.23       splines_4.5.2          later_1.4.5
    #>   [4] tibble_3.3.1           polyclip_1.10-7        fastDummies_1.7.5
    #>   [7] lifecycle_1.0.5        edgeR_4.8.2            globals_0.19.0
    #>  [10] lattice_0.22-7         MASS_7.3-65            magrittr_2.0.4
    #>  [13] limma_3.66.0           plotly_4.12.0          sass_0.4.10
    #>  [16] rmarkdown_2.30         jquerylib_0.1.4        yaml_2.3.12
    #>  [19] metapod_1.18.0         httpuv_1.6.16          otel_0.2.0
    #>  [22] sctransform_0.4.3      spam_2.11-3            spatstat.sparse_3.1-0
    #>  [25] reticulate_1.44.1      cowplot_1.2.0          pbapply_1.7-4
    #>  [28] buildtools_1.0.0       RColorBrewer_1.1-3     abind_1.4-8
    #>  [31] Rtsne_0.17             purrr_1.2.1            ggrepel_0.9.6
    #>  [34] irlba_2.3.7            listenv_0.10.0         spatstat.utils_3.2-1
    #>  [37] maketools_1.3.2        goftest_1.2-3          RSpectra_0.16-2
    #>  [40] spatstat.random_3.4-4  dqrng_0.4.1            fitdistrplus_1.2-6
    #>  [43] parallelly_1.46.1      codetools_0.2-20       DelayedArray_0.36.0
    #>  [46] tidyselect_1.2.1       farver_2.1.2           ScaledMatrix_1.18.0
    #>  [49] viridis_0.6.5          spatstat.explore_3.7-0 jsonlite_2.0.0
    #>  [52] BiocNeighbors_2.4.0    progressr_0.18.0       ggridges_0.5.7
    #>  [55] survival_3.8-6         tools_4.5.2            ica_1.0-3
    #>  [58] Rcpp_1.1.1             glue_1.8.0             gridExtra_2.3
    #>  [61] SparseArray_1.10.8     xfun_0.56              dplyr_1.1.4
    #>  [64] withr_3.0.2            BiocManager_1.30.27    fastmap_1.2.0
    #>  [67] digest_0.6.39          rsvd_1.0.5             R6_2.6.1
    #>  [70] mime_0.13              scattermore_1.2        tensor_1.5.1
    #>  [73] spatstat.data_3.1-9    tidyr_1.3.2            FNN_1.1.4.1
    #>  [76] httr_1.4.7             htmlwidgets_1.6.4      S4Arrays_1.10.1
    #>  [79] uwot_0.2.4             pkgconfig_2.0.3        gtable_0.3.6
    #>  [82] RProtoBufLib_2.22.0    lmtest_0.9-40          S7_0.2.1
    #>  [85] XVector_0.50.0         sys_3.4.3              htmltools_0.5.9
    #>  [88] dotCall64_1.2          scales_1.4.0           png_0.1-8
    #>  [91] spatstat.univar_3.1-6  knitr_1.51             reshape2_1.4.5
    #>  [94] nlme_3.1-168           cachem_1.1.0           zoo_1.8-15
    #>  [97] stringr_1.6.0          KernSmooth_2.23-26     miniUI_0.1.2
    #> [100] vipor_0.4.7            pillar_1.11.1          grid_4.5.2
    #> [103] vctrs_0.7.1            RANN_2.6.2             promises_1.5.0
    #> [106] stringfish_0.18.0      cytolib_2.22.0         beachmat_2.26.0
    #> [109] xtable_1.8-4           cluster_2.1.8.1        beeswarm_0.4.0
    #> [112] evaluate_1.0.5         cli_3.6.5              locfit_1.5-9.12
    #> [115] compiler_4.5.2         rlang_1.1.7            future.apply_1.20.1
    #> [118] labeling_0.4.3         plyr_1.8.9             ggbeeswarm_0.7.3
    #> [121] stringi_1.8.7          deldir_2.0-4           viridisLite_0.4.2
    #> [124] SuperCell_1.1          lazyeval_0.2.2         spatstat.geom_3.7-0
    #> [127] Matrix_1.7-4           RcppHNSW_0.6.0         patchwork_1.3.2
    #> [130] statmod_1.5.1          shiny_1.12.1           ROCR_1.0-12
    #> [133] igraph_2.2.1           RcppParallel_5.1.11-1  bslib_0.10.0