bootstrapCluster {scran} | R Documentation

## Assess cluster stability by bootstrapping

### Description

Generate bootstrap replicates and recluster on them to determine the stability of clusters with respect to sampling noise.

### Usage

    bootstrapCluster(x, FUN, clusters = NULL, transposed = FALSE,
      iterations = 20, ...)

### Arguments

`x` | A two-dimensional object containing cells in columns. This is usually a numeric matrix of log-expression values, but can also be a SingleCellExperiment object. If `transposed=TRUE`, cells are expected to be in the rows, e.g., for precomputed PCs.
`FUN` | A function that accepts `x` and returns a vector of cluster identities.
`clusters` | A vector of cluster identities obtained by calling `FUN(x, ...)`. This is provided as an additional argument in the case that the clusters have already been computed, in which case we can save a single round of computation.
`transposed` | Logical scalar indicating whether `x` is transposed with cells in the rows.
`iterations` | Integer scalar specifying the number of bootstrap iterations.
`...` | Further arguments to pass to `FUN` to control the clustering procedure.

### Details

Bootstrapping is conventionally used to evaluate the precision of an estimator by applying it to an in silico-generated replicate dataset. We can (ab)use this framework to determine the stability of the clusters in the context of a scRNA-seq analysis. We sample cells with replacement from `x`, perform clustering with `FUN` and compare the new clusters to `clusters`.

The relevant statistic is the co-assignment probability for each pair of original clusters, i.e., the probability that a randomly chosen cells from each of the two original clusters will be put in the same bootstrap cluster. High co-assignment probabilities indicate that the two original clusters were not stably separated. We might then only trust separation between two clusters if their co-assignment probability was less than some threshold, e.g., 5%.

The co-assignment probability of each cluster to itself provides some measure of per-cluster stability. A probability of 1 indicates that all cells are always assigned to the same cluster across bootstrap iterations, while internal structure that encourages the formation of subclusters will lower this probability.

### Value

A numeric matrix with upper triangular entries filled with the co-assignment probabilities for each pair of clusters in `clusters`.

### Statistical notes

We use the co-assignment probability as it is more interpretable than, say, the Jaccard index (see the fpc package). It also focuses on the relevant differences between clusters, allowing us to determine which aspects of a clustering are stable. For example, A and B may be well separated but A and C may not be, which is difficult to represent in a single stability measure for A. If our main interest lies in the A/B separation, we do not want to be overly pessimistic about the stability of A, even though it might not be well-separated from all other clusters.

Technically speaking, some mental gymnastics are required to compare the original and bootstrap clusters in this manner. After bootstrapping, the sampled cells represent distinct entities from the original dataset (otherwise it would be difficult to treat them as independent replicates) for which the original clusters do not immediately apply. Instead, we assume that we perform label transfer using a nearest-neighbors approach - which, in this case, is the same as using the original label for each cell, as the nearest neighbor of each resampled cell to the original dataset is itself.

Needless to say, bootstrapping will only generate replicates that differ by sampling noise. Real replicates will differ due to composition differences, variability in expression across individuals, etc. Thus, any stability inferences from bootstrapping are likely to be overly optimistic.

### Author(s)

Aaron Lun

### See Also

`quickCluster`, to get a quick and dirty function to use as `FUN`. It is often more computationally efficient to define your own function, though.

### Examples

    library(scater)
    sce <- mockSCE(ncells=200)
    bootstrapCluster(sce, FUN=quickCluster, min.size=10)

    # Defining your own function:
    sce <- logNormCounts(sce)
    sce <- runPCA(sce)
    bootstrapCluster(reducedDim(sce), transposed=TRUE, FUN=function(x) {
        kmeans(x, 2)$cluster
    })

[Package scran version 1.14.6 Index]