This vignette describes the steps to generate supercells for cytometry data using SuperCellCyto R package.
Briefly, supercells are “mini” clusters of cells that are similar in their marker expressions. The motivation behind supercells is that instead of analysing millions of individual cells, you can analyse thousands of supercells, making downstream analysis much faster while maintaining biological interpretability.
See other vignettes for how to:
You can install stable version of SuperCellCyto from Bioconductor using:
if (!requireNamespace("BiocManager", quietly = TRUE))
install.packages("BiocManager")
BiocManager::install("SuperCellCyto")For the latest development version, you can install it from GitHub
using pak:
The function which creates supercells is called
runSuperCellCyto, and it operates on a
data.table object, an enhanced version of R native
data.frame.
In addition to needing the data stored in a data.table
object it also requires:
runSuperCellCyto
does not perform any data transformation or scaling.If you are not sure how to import CSV or FCS files into
data.table object, and/or how to subsequently prepare the
object ready for SuperCellCyto, please consult this vignette. In that vignette, we also
provide an explanation behind why we need to have the cell ID and sample
column.
For this vignette, we will simulate some toy data using the
simCytoData function. Specifically, we will simulate 15
markers and 3 samples, with each sample containing 10,000 cells. Hence
in total, we will have a toy dataset containing 15 markers and 30,000
cells.
n_markers <- 15
n_samples <- 3
dat <- simCytoData(nmarkers = n_markers, ncells = rep(10000, n_samples))
head(dat)
#> Marker_1 Marker_2 Marker_3 Marker_4 Marker_5 Marker_6 Marker_7 Marker_8
#> <num> <num> <num> <num> <num> <num> <num> <num>
#> 1: 10.789836 9.822495 17.34582 17.75142 11.336342 15.44986 17.91171 16.15778
#> 2: 10.819115 10.823170 15.86403 16.86742 11.007650 15.72372 20.39214 16.41687
#> 3: 11.209821 12.623392 16.57565 18.04358 8.700197 14.07813 18.71387 17.91655
#> 4: 12.143803 10.309700 15.96415 17.74553 10.197229 14.61589 18.71064 16.06251
#> 5: 9.698432 10.857674 15.78921 15.87041 11.032786 15.08917 17.06383 16.78889
#> 6: 10.135686 11.183344 17.35600 17.39988 8.956799 13.12902 18.42801 16.03306
#> Marker_9 Marker_10 Marker_11 Marker_12 Marker_13 Marker_14 Marker_15
#> <num> <num> <num> <num> <num> <num> <num>
#> 1: 16.22377 11.437029 12.32953 5.042304 6.988809 5.460839 12.45165
#> 2: 17.43672 11.816580 13.54892 5.499189 5.775180 4.815513 12.23547
#> 3: 15.62479 9.397134 11.92753 7.278637 7.118176 5.123954 11.20727
#> 4: 17.80606 13.523091 13.27146 6.145756 6.171611 7.609215 11.35478
#> 5: 17.22835 11.370754 12.15739 4.219715 7.086325 3.447191 11.36627
#> 6: 18.00599 9.859370 14.13316 4.854726 7.699413 4.907197 14.06306
#> Sample Cell_Id
#> <char> <char>
#> 1: Sample_1 Cell_1
#> 2: Sample_1 Cell_2
#> 3: Sample_1 Cell_3
#> 4: Sample_1 Cell_4
#> 5: Sample_1 Cell_5
#> 6: Sample_1 Cell_6For our toy dataset, we will transform our data using arcsinh
transformation. We will use the base R asinh function to do
this:
# Specify which columns are the markers to transform
marker_cols <- paste0("Marker_", seq_len(n_markers))
# The co-factor for arc-sinh
cofactor <- 5
# Do the transformation
dat_asinh <- asinh(dat[, marker_cols, with = FALSE] / cofactor)
# Rename the new columns
marker_cols_asinh <- paste0(marker_cols, "_asinh")
names(dat_asinh) <- marker_cols_asinh
# Add them our previously loaded data
dat <- cbind(dat, dat_asinh)
head(dat[, marker_cols_asinh, with = FALSE])
#> Marker_1_asinh Marker_2_asinh Marker_3_asinh Marker_4_asinh Marker_5_asinh
#> <num> <num> <num> <num> <num>
#> 1: 1.512128 1.427645 1.957215 1.979444 1.557149
#> 2: 1.514588 1.514928 1.871721 1.930370 1.530293
#> 3: 1.546889 1.656358 1.913653 1.995166 1.320945
#> 4: 1.620444 1.470998 1.877723 1.979124 1.461138
#> 5: 1.416332 1.517818 1.867213 1.872104 1.532371
#> 6: 1.455706 1.544730 1.957778 1.960205 1.346237
#> Marker_6_asinh Marker_7_asinh Marker_8_asinh Marker_9_asinh Marker_10_asinh
#> <num> <num> <num> <num> <num>
#> 1: 1.846520 1.988099 1.889234 1.893128 1.565245
#> 2: 1.863251 2.113561 1.904441 1.962238 1.595236
#> 3: 1.758471 2.030361 1.988359 1.857238 1.388376
#> 4: 1.793869 2.030194 1.883586 1.982402 1.720655
#> 5: 1.824071 1.941475 1.925897 1.950687 1.559923
#> 6: 1.692967 2.015497 1.881834 1.993156 1.430986
#> Marker_11_asinh Marker_12_asinh Marker_13_asinh Marker_14_asinh
#> <num> <num> <num> <num>
#> 1: 1.634494 0.8873437 1.1366805 0.9450681
#> 2: 1.722445 0.9502378 0.9868665 0.8550411
#> 3: 1.603849 1.1699516 1.1516433 0.8987951
#> 4: 1.703058 1.0345023 1.0377616 1.2068188
#> 5: 1.621478 0.7666155 1.1479763 0.6439926
#> 6: 1.762149 0.8606788 1.2166844 0.8681881
#> Marker_15_asinh
#> <num>
#> 1: 1.643634
#> 2: 1.627401
#> 3: 1.546681
#> 4: 1.558636
#> 5: 1.559562
#> 6: 1.757462We will also create a column Cell_id_dummy which uniquely
identify each cell. It will have values such as
Cell_1, Cell_2, all the way until Cell_x where
x is the number of cells in the dataset.
dat$Cell_id_dummy <- paste0("Cell_", seq_len(nrow(dat)))
head(dat$Cell_id_dummy, n = 10)
#> [1] "Cell_1" "Cell_2" "Cell_3" "Cell_4" "Cell_5" "Cell_6" "Cell_7"
#> [8] "Cell_8" "Cell_9" "Cell_10"By default, the simCytoData function will generate cells
for multiple samples, and that the resulting data.table
object will already have a column called Sample that denotes
the sample the cells come from.
Let’s take note of the sample and cell id column for later.
Now that we have our data, let’s create some supercells. To do this,
we will use runSuperCellCyto function and pass the markers,
sample and cell ID columns as parameters.
The reason why we need to specify the markers is because the function
will create supercells based on only the expression of those markers. We
highly recommend creating supercells using all markers in your data, let
that be cell type or cell state markers. However, if for any reason you
only want to only use a subset of the markers in your data, then make
sure you specify them in a vector that you later pass to
runSuperCellCyto function.
For this tutorial, we will use all the arcsinh transformed markers in the toy data.
supercells <- runSuperCellCyto(
dt = dat,
markers = marker_cols_asinh,
sample_colname = sample_col,
cell_id_colname = cell_id_col
)Let’s dig deeper into the object it created:
It is a list containing 3 elements:
names(supercells)
#> [1] "supercell_expression_matrix" "supercell_cell_map"
#> [3] "supercell_object"The supercell_object contains the metadata used to
create the supercells. It is a list, and each element contains the
metadata used to create the supercells for a sample. This will come in
handy if we need to either regenerate the supercells using different
gamma values (so we get more or less supercells) or do some debugging
later down the line. More on regenerating supercells on Controlling supercells
granularity section below.
The supercell_expression_matrix contains the marker
expression of each supercell. These are calculated by taking the average
of the marker expression of all the cells contained within a
supercell.
head(supercells$supercell_expression_matrix)
#> Marker_1_asinh Marker_2_asinh Marker_3_asinh Marker_4_asinh Marker_5_asinh
#> <num> <num> <num> <num> <num>
#> 1: 1.457837 1.479434 1.880622 1.977005 1.429080
#> 2: 1.549172 1.551151 1.897130 1.967239 1.395770
#> 3: 1.368406 1.472668 1.894366 1.961235 1.479493
#> 4: 1.526131 1.452006 1.892533 1.977045 1.471499
#> 5: 1.558795 1.616255 1.865065 1.953651 1.384398
#> 6: 1.512934 1.421222 1.886112 1.946369 1.450825
#> Marker_6_asinh Marker_7_asinh Marker_8_asinh Marker_9_asinh Marker_10_asinh
#> <num> <num> <num> <num> <num>
#> 1: 1.815849 2.032541 1.913263 1.945947 1.423793
#> 2: 1.796565 2.012049 1.918354 1.936755 1.609476
#> 3: 1.803591 2.044754 1.934347 1.953739 1.485316
#> 4: 1.826393 2.025796 1.916426 1.937584 1.457860
#> 5: 1.803682 2.008068 1.906903 1.948849 1.406209
#> 6: 1.824069 2.005643 1.899271 1.943823 1.578915
#> Marker_11_asinh Marker_12_asinh Marker_13_asinh Marker_14_asinh
#> <num> <num> <num> <num>
#> 1: 1.721034 1.0129262 1.0345403 1.0653789
#> 2: 1.735682 1.1388725 0.8000132 0.8395323
#> 3: 1.716389 1.0116008 0.9901611 0.7726526
#> 4: 1.671709 1.0224636 1.0267019 0.8442861
#> 5: 1.699378 0.7337115 0.8092318 0.8780779
#> 6: 1.670241 0.7627220 0.8455728 0.8806260
#> Marker_15_asinh Sample SuperCellId
#> <num> <char> <char>
#> 1: 1.629300 Sample_1 SuperCell_1_Sample_Sample_1
#> 2: 1.661530 Sample_1 SuperCell_2_Sample_Sample_1
#> 3: 1.570702 Sample_1 SuperCell_3_Sample_Sample_1
#> 4: 1.645933 Sample_1 SuperCell_4_Sample_Sample_1
#> 5: 1.679507 Sample_1 SuperCell_5_Sample_Sample_1
#> 6: 1.603383 Sample_1 SuperCell_6_Sample_Sample_1Therein, we will have the following columns:
markers_col variable. In this example, they are the arcsinh
transformed markers in our toy data.Sample in this case) denoting which sample a
supercell belongs to, (note the column name is the same as what is
stored in sample_col variable).SuperCellId column denoting the unique ID of the
supercell.Let’s have a look at SuperCellId:
head(unique(supercells$supercell_expression_matrix$SuperCellId))
#> [1] "SuperCell_1_Sample_Sample_1" "SuperCell_2_Sample_Sample_1"
#> [3] "SuperCell_3_Sample_Sample_1" "SuperCell_4_Sample_Sample_1"
#> [5] "SuperCell_5_Sample_Sample_1" "SuperCell_6_Sample_Sample_1"Let’s break down one of them,
SuperCell_1_Sample_Sample_1. SuperCell_1 is a
numbering (1 to however many supercells there are in a sample) used to
uniquely identify each supercell in a sample. Notably, you may encounter
this (SuperCell_1, SuperCell_2) being repeated
across different samples, e.g.,
supercell_ids <- unique(supercells$supercell_expression_matrix$SuperCellId)
supercell_ids[grep("SuperCell_1_", supercell_ids)]
#> [1] "SuperCell_1_Sample_Sample_1" "SuperCell_1_Sample_Sample_2"
#> [3] "SuperCell_1_Sample_Sample_3"While these 3 supercells’ id are pre-fixed with
SuperCell_1, it does not make them equal to one another!
SuperCell_1_Sample_Sample_1 will only contain cells from
Sample_1 while SuperCell_1_Sample_Sample_2
will only contain cells from Sample_2.
By now, you may have noticed that we appended the sample name into each supercell id. This aids in differentiating the supercells in different samples.
supercell_cell_map maps each cell in our dataset to the
supercell it belongs to.
head(supercells$supercell_cell_map)
#> SuperCellID CellId Sample
#> <char> <char> <char>
#> 1: SuperCell_205_Sample_Sample_1 Cell_1 Sample_1
#> 2: SuperCell_441_Sample_Sample_1 Cell_2 Sample_1
#> 3: SuperCell_201_Sample_Sample_1 Cell_3 Sample_1
#> 4: SuperCell_76_Sample_Sample_1 Cell_4 Sample_1
#> 5: SuperCell_63_Sample_Sample_1 Cell_5 Sample_1
#> 6: SuperCell_186_Sample_Sample_1 Cell_6 Sample_1This map is very useful if we later need to expand the supercells out. Additionally, this is also the reason why we need to have a column in the dataset which uniquely identify each cell.
runSuperCellCyto in parallelBy default, runSuperCellCyto will process each sample
one after the other. As each sample is processed independent of one
another, strictly speaking, we can process all of them in parallel.
To do this, we need to:
BiocParallelParam object from the BiocParallel
package. This object can either be of type MulticoreParamor
SnowParam. We highly recommend consulting their vignette
for more information.BiocParallelParam
object to the number of samples we have in the dataset.load_balancing parameter for
runSuperCellCyto function to TRUE. This is to ensure even
distribution of the supercell creation jobs. As each sample will be
processed by a parallel job, we don’t want a job that processs large
sample to also be assigned other smaller samples if possible. If you
want to know more how this feature works, please refer to our
manuscript.This is described in the runSuperCellCyto function’s
documentation, but let’s briefly go through it here.
The runSuperCellCyto function is equipped with various
parameters which can be customised to alter the composition of the
supercells. The one that is very likely to be used the most is the gamma
parameter, denoted as gam in the function. By default, the
value for gam is set to 20, which we found work well for
most cases.
The gamma parameter controls how many supercells to generate, and
indirectly, how many cells are captured within each supercell. This
parameter is resolved into the following formula
gamma=n_cells/n_supercells where n_cell
denotes the number of cells and n_supercells denotes the
number of supercells.
In general, the larger gamma parameter is set to, the less supercells we will get. Say for instance we have 10,000 cells. If gamma is set to 10, we will end up with about 1,000 supercells, whereas if gamma is set to 50, we will end up with about 200 supercells.
You may have noticed, after reading the sections above,
runSuperCellCyto is ran on each sample independent of each
other, and that we can only set 1 value as the gamma parameter. Indeed,
for now, the same gamma value will be used across all samples, and that
depending on how many cells we have in each sample, we will end up with
different number of supercells for each sample. For instance, say we
have 10,000 cells for sample 1, and 100,000 cells for sample 2. If gamma
is set to 10, for sample 1, we will get 1,000 supercells (10,000/10)
while for sample 2, we will get 10,000 supercells (100,000/10).
Do note: whatever gamma value you chose, you should not expect each supercell to contain exactly the same number of cells. This behaviour is intentional to ensure rare cell types are not intermixed with non-rare cell types in a supercell.
If you have run runSuperCellCyto once and have not
discarded the SuperCell object it generated (no serious, please don’t!),
you can use the object to quickly regenerate supercells
using different gamma values.
As an example, using the SuperCell object we have generated for our
toy dataset, we will regenerate the supercells using gamma of 10 and 50.
The function to do this is recomputeSupercells. We will
store the output in a list, one element per gamma value.
addt_gamma_vals <- c(10, 50)
supercells_addt_gamma <- lapply(addt_gamma_vals, function(gam) {
recomputeSupercells(
dt = dat,
sc_objects = supercells$supercell_object,
markers = marker_cols_asinh,
sample_colname = sample_col,
cell_id_colname = cell_id_col,
gam = gam
)
})We should end up with a list containing 2 elements. The 1st element contains supercells generated using gamma = 10, and the 2nd contains supercells generated using gamma = 50.
supercells_addt_gamma[[1]]
#> $supercell_expression_matrix
#> Marker_1_asinh Marker_2_asinh Marker_3_asinh Marker_4_asinh
#> <num> <num> <num> <num>
#> 1: 1.533868 1.521524 1.859817 1.964372
#> 2: 1.505259 1.566631 1.882147 1.961299
#> 3: 1.580626 1.455574 1.894140 1.980214
#> 4: 1.350802 1.585817 1.891966 1.979003
#> 5: 1.518465 1.578852 1.892906 1.964989
#> ---
#> 2996: 1.707285 1.582906 1.199769 1.892020
#> 2997: 1.798407 1.577798 1.308907 1.819611
#> 2998: 1.754838 1.564464 1.384137 1.874782
#> 2999: 1.864944 1.635150 1.498143 1.862958
#> 3000: 1.689662 1.537745 1.457800 1.873703
#> Marker_5_asinh Marker_6_asinh Marker_7_asinh Marker_8_asinh
#> <num> <num> <num> <num>
#> 1: 1.526567 1.788001 2.001939 1.887042
#> 2: 1.584334 1.809421 2.037887 1.940836
#> 3: 1.429877 1.835490 2.032382 1.932427
#> 4: 1.446701 1.801880 2.013071 1.912873
#> 5: 1.490082 1.807551 2.023138 1.914893
#> ---
#> 2996: 1.933404 2.013963 1.724407 1.570893
#> 2997: 1.982914 2.054180 1.746413 1.659361
#> 2998: 1.946740 2.071483 1.688407 1.671840
#> 2999: 2.014623 2.081866 1.763041 1.674721
#> 3000: 1.935950 2.049732 1.727515 1.661437
#> Marker_9_asinh Marker_10_asinh Marker_11_asinh Marker_12_asinh
#> <num> <num> <num> <num>
#> 1: 1.9317267 1.4847831 1.704690 0.8071119
#> 2: 1.9643452 1.3172733 1.672192 0.9005033
#> 3: 1.9391327 1.4014284 1.675455 0.9361391
#> 4: 1.9436634 1.3938612 1.744428 0.8917024
#> 5: 1.9541755 1.4703247 1.650159 0.9296157
#> ---
#> 2996: 1.0974716 1.2554067 1.474586 1.2500108
#> 2997: 1.3765879 0.9035809 1.182241 1.3907021
#> 2998: 1.2991878 1.1471364 1.372961 1.5666941
#> 2999: 1.2975055 1.1456796 1.341760 1.4789371
#> 3000: 0.9035863 0.8735152 1.313258 1.3034588
#> Marker_13_asinh Marker_14_asinh Marker_15_asinh Sample
#> <num> <num> <num> <char>
#> 1: 0.9212785 0.9925281 1.533630 Sample_1
#> 2: 1.1332110 0.9108530 1.577333 Sample_1
#> 3: 1.0364456 0.8769989 1.637387 Sample_1
#> 4: 1.0448616 0.9450559 1.652326 Sample_1
#> 5: 1.0639993 0.8641191 1.646703 Sample_1
#> ---
#> 2996: 1.5211456 1.8574173 1.342579 Sample_3
#> 2997: 1.6757832 1.9655159 1.443640 Sample_3
#> 2998: 1.5892516 1.9356372 1.287251 Sample_3
#> 2999: 1.6454196 1.9704936 1.448235 Sample_3
#> 3000: 1.6466552 1.9284189 1.204571 Sample_3
#> SuperCellId
#> <char>
#> 1: SuperCell_1_Sample_Sample_1
#> 2: SuperCell_2_Sample_Sample_1
#> 3: SuperCell_3_Sample_Sample_1
#> 4: SuperCell_4_Sample_Sample_1
#> 5: SuperCell_5_Sample_Sample_1
#> ---
#> 2996: SuperCell_996_Sample_Sample_3
#> 2997: SuperCell_997_Sample_Sample_3
#> 2998: SuperCell_998_Sample_Sample_3
#> 2999: SuperCell_999_Sample_Sample_3
#> 3000: SuperCell_1000_Sample_Sample_3
#>
#> $supercell_cell_map
#> SuperCellID CellId Sample
#> <char> <char> <char>
#> 1: SuperCell_373_Sample_Sample_1 Cell_1 Sample_1
#> 2: SuperCell_787_Sample_Sample_1 Cell_2 Sample_1
#> 3: SuperCell_590_Sample_Sample_1 Cell_3 Sample_1
#> 4: SuperCell_663_Sample_Sample_1 Cell_4 Sample_1
#> 5: SuperCell_611_Sample_Sample_1 Cell_5 Sample_1
#> ---
#> 29996: SuperCell_8_Sample_Sample_3 Cell_29996 Sample_3
#> 29997: SuperCell_909_Sample_Sample_3 Cell_29997 Sample_3
#> 29998: SuperCell_565_Sample_Sample_3 Cell_29998 Sample_3
#> 29999: SuperCell_108_Sample_Sample_3 Cell_29999 Sample_3
#> 30000: SuperCell_377_Sample_Sample_3 Cell_30000 Sample_3The output generated by recomputeSupercells is
essentially a list:
supercell_expression_matrix: A data.table object that
contains the marker expression for each supercell.supercell_cell_map: A data.table that maps each cell to
its corresponding supercell.As mentioned before, gamma dictates the granularity of supercells. Compared to the previous run where gamma was set to 20, we should get more supercells for gamma = 10, and less for gamma = 50. Let’s see if that’s the case.
In the future, we may add the ability to specify different
gam value for different samples. For now, if we want to do
this, we will need to break down our data into multiple
data.table objects, each containing data from 1 sample, and
run runSuperCellCyto function on each of them with
different gam parameter value. Something like the
following:
n_markers <- 10
dat <- simCytoData(nmarkers = n_markers)
markers_col <- paste0("Marker_", seq_len(n_markers))
sample_col <- "Sample"
cell_id_col <- "Cell_Id"
samples <- unique(dat[[sample_col]])
gam_values <- c(10, 20, 10)
supercells_diff_gam <- lapply(seq_len(length(samples)), function(i) {
sample <- samples[i]
gam <- gam_values[i]
dat_samp <- dat[dat$Sample == sample, ]
supercell_samp <- runSuperCellCyto(
dt = dat_samp,
markers = markers_col,
sample_colname = sample_col,
cell_id_colname = cell_id_col,
gam = gam
)
return(supercell_samp)
})Subsequently, to extract and combine the
supercell_expression_matrix and
supercell_cell_map, we will need to use
rbind:
supercell_expression_matrix <- do.call(
"rbind", lapply(
supercells_diff_gam, function(x) x[["supercell_expression_matrix"]]
)
)
supercell_cell_map <- do.call(
"rbind", lapply(
supercells_diff_gam, function(x) x[["supercell_cell_map"]]
)
)rbind(
head(supercell_expression_matrix, n = 3),
tail(supercell_expression_matrix, n = 3)
)
#> Marker_1 Marker_2 Marker_3 Marker_4 Marker_5 Marker_6 Marker_7 Marker_8
#> <num> <num> <num> <num> <num> <num> <num> <num>
#> 1: 12.14807 11.620891 19.13752 18.94671 14.12643 15.860296 14.71135 6.318346
#> 2: 12.54633 12.052210 18.43880 18.22843 11.63702 15.352256 15.11670 6.614769
#> 3: 11.05224 10.782447 18.00147 19.28489 12.43380 14.920031 16.42899 7.447646
#> 4: 11.47916 7.942444 14.09707 14.75091 16.05935 8.213979 18.29807 9.244490
#> 5: 12.68788 7.484611 12.16817 15.37025 15.08324 7.552937 16.46797 11.263458
#> 6: 12.01336 7.545514 14.31913 18.80307 17.44875 9.092580 19.11617 11.017966
#> Marker_9 Marker_10 Sample SuperCellId
#> <num> <num> <char> <char>
#> 1: 17.44534 18.539581 Sample_1 SuperCell_1_Sample_Sample_1
#> 2: 16.80756 16.972126 Sample_1 SuperCell_2_Sample_Sample_1
#> 3: 18.01664 16.537296 Sample_1 SuperCell_3_Sample_Sample_1
#> 4: 19.33676 10.129761 Sample_2 SuperCell_498_Sample_Sample_2
#> 5: 19.38477 10.696790 Sample_2 SuperCell_499_Sample_Sample_2
#> 6: 20.02112 9.379978 Sample_2 SuperCell_500_Sample_Sample_2rbind(head(supercell_cell_map, n = 3), tail(supercell_cell_map, n = 3))
#> SuperCellID CellId Sample
#> <char> <char> <char>
#> 1: SuperCell_113_Sample_Sample_1 Cell_1 Sample_1
#> 2: SuperCell_96_Sample_Sample_1 Cell_2 Sample_1
#> 3: SuperCell_308_Sample_Sample_1 Cell_3 Sample_1
#> 4: SuperCell_38_Sample_Sample_2 Cell_19998 Sample_2
#> 5: SuperCell_244_Sample_Sample_2 Cell_19999 Sample_2
#> 6: SuperCell_235_Sample_Sample_2 Cell_20000 Sample_2If for whatever reason you don’t mind (or perhaps more to the point
want) each supercell to contain cells from different biological samples,
you still need to have the sample column in your
data.table. However, what you need to do is essentially set
the value in the column to exactly one unique
value. That way, SuperCellCyto will treat all cells as coming from one
sample.
Just note, the parallel processing feature in SuperCellCyto won’t work for this as you will essentially only have 1 sample and nothing for SuperCellCyto to parallelise.
Is your dataset so huge that you are constantly running out of RAM when generating supercells? This thing happens and we have a solution for it.
Since supercells are generated for each sample independent of others you can easily break up the process. For example:
supercell_expression_matrix and
supercell_cell_map, and export them out as a csv file using
data.table’s fwrite function.Once you have processed all the samples, you can then load all
supercell_expression_matrix and
supercell_cell_map csv files and analyse them.
If you want to regenerate the supercells using different gamma
values, load the relevant output saved using the qs package and the
relevant data (remember to note which output belongs to which sets of
samples!), and run recomputeSupercells function.
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] parallel stats graphics grDevices utils datasets methods
#> [8] base
#>
#> other attached packages:
#> [1] BiocParallel_1.44.0 SuperCellCyto_1.0.0 BiocStyle_2.38.0
#>
#> loaded via a namespace (and not attached):
#> [1] cli_3.6.5 knitr_1.50 rlang_1.1.6
#> [4] xfun_0.54 data.table_1.17.8 jsonlite_2.0.0
#> [7] buildtools_1.0.0 plyr_1.8.9 htmltools_0.5.8.1
#> [10] maketools_1.3.2 sys_3.4.3 sass_0.4.10
#> [13] rmarkdown_2.30 grid_4.5.2 evaluate_1.0.5
#> [16] jquerylib_0.1.4 fastmap_1.2.0 yaml_2.3.10
#> [19] lifecycle_1.0.4 BiocManager_1.30.26 compiler_4.5.2
#> [22] igraph_2.2.1 codetools_0.2-20 Rcpp_1.1.0
#> [25] pkgconfig_2.0.3 lattice_0.22-7 digest_0.6.37
#> [28] SuperCell_1.0.1 R6_2.6.1 RANN_2.6.2
#> [31] magrittr_2.0.4 bslib_0.9.0 Matrix_1.7-4
#> [34] tools_4.5.2 cachem_1.1.0