getClusteredPCs {scran} | R Documentation

## Use clusters to choose the number of PCs

### Description

Cluster cells after using varying number of PCs, and pick the number of PCs using a heuristic based on the number of clusters.

### Usage

    getClusteredPCs(
      pcs,
      FUN = NULL,
      ...,
      BLUSPARAM = NNGraphParam(),
      min.rank = 5,
      max.rank = ncol(pcs),
      by = 1
    )

### Arguments

`pcs` | A numeric matrix of PCs, where rows are cells and columns are dimensions representing successive PCs.
`FUN` | A clustering function that takes a numeric matrix with rows as cells and returns a vector containing a cluster label for each cell. Defaults to `clusterRows`.
`...` | Further arguments to pass to `FUN`. Ignored if `FUN=NULL`, use `BLUSPARAM` instead.
`BLUSPARAM` | A BlusterParam object specifying the clustering to use when `FUN=NULL`.
`min.rank` | Integer scalar specifying the minimum number of PCs to use.
`max.rank` | Integer scalar specifying the maximum number of PCs to use.
`by` | Integer scalar specifying what intervals should be tested between `min.rank` and `max.rank`.

### Details

Assume that the data contains multiple subpopulations, each of which is separated from the others on a different axis. For example, each subpopulation could be defined by a unique set of marker genes that drives separation on its own PC. If we had x subpopulations, we would need at least x-1 PCs to successfully distinguish all of them. This motivates the choice of the number of PCs provided we know the number of subpopulations in the data.

In practice, we do not know the number of subpopulations so we use the number of clusters as a proxy instead. We apply a clustering function `FUN` on the first d PCs, and only consider the values of d that yield no more than d+1 clusters. If we see more clusters with fewer dimensions, we consider this to represent overclustering rather than distinct subpopulations, as multiple subpopulations should not be distinguishable on the same axes (based on the assumption above).

We choose d that satisfies the constraint above and maximizes the number of clusters. The idea is that more PCs should include more biological signal, allowing `FUN` to detect more distinct subpopulations; until the point that the extra signal outweights the added noise at high dimensions, such that resolution decreases and it becomes more difficult for `FUN` to distinguish between subpopulations.

Any `FUN` can be used that automatically chooses the number of clusters based on the data. The default is a graph-based clustering method using `makeSNNGraph` and `cluster_walktrap`, where arguments in `...` are passed to the former. Users should not supply `FUN` where the number of clusters is fixed in advance, (e.g., k-means, hierarchical clustering with known `k` in `cutree`).

The identities of the output clusters are returned at each step for comparison, e.g., using methods like clustree.

### Value

A DataFrame with one row per tested number of PCs. This contains the fields:

`n.pcs`:

  Integer scalar specifying the number of PCs used.

`n.clusters`:

  Integer scalar specifying the number of clusters identified.

`clusters`:

  A List containing the cluster identities for this number of PCs.

The metadata of the DataFrame contains `chosen`, an integer scalar specifying the “ideal” number of PCs to use.

### Author(s)

Aaron Lun

### See Also

`runPCA`, to compute the PCs in the first place.

`clusterRows` and BlusterParam, for possible choices of `BLUSPARAM`.

### Examples

    library(scuttle)
    sce <- mockSCE()
    sce <- logNormCounts(sce)

    sce <- scater::runPCA(sce)
    output <- getClusteredPCs(reducedDim(sce))
    output

    metadata(output)$chosen

[Package scran version 1.22.1 Index]