Subsampled views: pull from a share of the cells, and reproduce it exactly#

Open In Colab

When the viewer opened a seeded subsample (chosen under Session › Subsampling › Cells to open, or fitted to the device for a dataset of millions of cells; Subsampled loading), everything you make covers only the open cells. This tutorial shows what cellucid_pull() writes for the other cells, and how to take exactly the open cells in R with cellucid_subsample_cells().

Time: 10 minutes. The same tutorial in Python: Subsampled views.

# A fresh R library (Google Colab's R runtime, a new machine) installs the packages once.
for (package in c("remotes", "SeuratObject")) {
  if (!requireNamespace(package, quietly = TRUE)) install.packages(package)
}
if (!requireNamespace("cellucid", quietly = TRUE)) {
  if ("cellucid" %in% rownames(available.packages())) install.packages("cellucid") else remotes::install_github("theislab/cellucid-r")
}

The data#

SeuratObject’s own example, pbmc_small: 80 blood cells, 230 genes, a t-SNE and the clusters RNA_snn_res.1. Use your own Seurat or SingleCellExperiment object in its place.

library(cellucid)
library(SeuratObject)
data("pbmc_small")
seu <- pbmc_small
seu
viewer <- cellucid_view(seu, dataset_id = "pbmc-small", dataset_name = "PBMC small")

Open a share of the cells#

In the viewer, expand Session and its Subsampling; under Cells to open, set the slider to 25 %, choose Uniform, leave the seed at 0, and press Apply: 20 of the 80 cells are open. Lasso some of them and Confirm, then run the next cell.

opened <- Filter(function(result) identical(result$kind, "subset"), cellucid_results(viewer))[[1]]
open_cells <- if (is.null(opened$cells)) seq_len(ncol(seu)) else opened$cells
cat(length(open_cells), "of", ncol(seu), "cells are open; digest", opened$meta$digest, "\n")

Every result names cells by their position in the whole object (1-based here), whatever share is open; the result of kind subset lists the open cells, and its digest is the one the Session panel shows.

Pull: unknown, not “not selected”#

pulled <- cellucid_pull(seu, viewer, return_summary = TRUE)
seu <- pulled$data
lasso <- grep("^cellucid_highlight__", names(pulled$summary$columns), value = TRUE)[[1]]
table(seu[[lasso]][, 1], useNA = "ifany")

A highlight column is TRUE for the highlighted cells, FALSE for open cells that are not, and NA for the cells the viewer never opened: unknown. A label or score is NA there too. Count on the open cells only:

sum(seu[[lasso]][open_cells, 1])

Reproduce the subsample exactly#

cellucid_subsample_cells() follows the same specification as the web app and Python’s cellucid.subsample_cells(), checked against one shared conformance fixture. It returns 1-based positions.

kept <- cellucid_subsample_cells(seu, fraction = 0.25, method = "uniform", seed = 0)
identical(as.numeric(kept), as.numeric(open_cells))
small <- seu[, kept]  # exactly the cells the viewer showed
small

In the viewer

In R

Blocks (the Dataset box’s Details say “blocks of …”)

cellucid_subsample_cells(seu, fraction = 0.25, method = "blocks", block_size = ..., seed = 0)

Stratified on groups

cellucid_subsample_cells(seu, fraction = 0.25, method = "stratified", groupby = "groups")

Stratified, Same count per category

... method = "stratified", groupby = "groups", allocation = "balanced"

Spatial on the t-SNE

cellucid_subsample_cells(seu, fraction = 0.25, method = "spatial", basis = "tsne")

With uniform and blocks, a smaller share is inside a larger one (same seed):

ten <- cellucid_subsample_cells(seu, fraction = 0.1, seed = 0)
all(ten %in% kept)
balanced <- cellucid_subsample_cells(seu, 20, method = "stratified", groupby = "groups", allocation = "balanced")
table(seu$groups[balanced])

A link can name the subsample (&cells=25%&sample=uniform&seed=0 after the dataset), so everyone opens the same cells; for a dataset opened by a link, Copy link under Cells to open makes one (a dataset R serves has no link to share). A session saved on a subsample records its cells: cellucid_pull(seu, "my.cellucid-session") writes NA for the cells it did not open, as above.

cellucid_stop(viewer)

Next#