Running PCA
PCA is calculated on the scale.data slot of an assay using calculate_pca(). The result is stored in dataset@reduction under the name PCA.<assay> by default. Make sure to run scale_dataset() first (see feature transformation and scaling).
Features with any NA values are automatically excluded. A warning is raised listing how many were removed.
Other arguments:
use_irlba: useirlba::prcomp_irlba()instead ofprcomp(). This is switched on automatically whenpc.nis set.recenter/rescale: re-center and/or re-scale the slot to mean 0 and variance 1 before the PCA.calculate_pca()does not center or scale itself and assumesscale.dataalready has mean 0 and variance 1. This is not true after modified z-score scaling (scale.method="median"), so set both toTRUEin that case.ret.prcomp=TRUE: store the fullprcompobject in@object. The loadings are in$rotation, with features as rows.
Clustering cells
Clustering is performed on a PCA reduction using calculate_clustering(), which builds a k-nearest neighbour graph and applies Louvain or Leiden community detection. Cluster labels are added as new columns in dataset@meta under the name <col.out>res_<resolution>.
The k argument controls the number of nearest neighbours used to build the graph (default 10). Higher k tends to produce larger, coarser clusters. pc.n sets how many PCs are used (default: all PCs in the reduction).
By default an approximate nearest neighbour (Annoy-based) is used for speed. For exact kNN, set exact.nn=TRUE.
The method argument can be "louvain" (default) or "leiden".
igraph::cluster_leiden() is called with its default objective, the Constant Potts Model (CPM), not modularity. Resolution values that work for Louvain do not carry over and usually give far too many clusters. Re-tune the resolution for Leiden. On tglow_example, resolution=0.2 gives several hundred clusters, while resolution=0.01 gives 14.
Graph cache
The kNN graph is cached in dataset@graph and reused when k, reduction and exact.nn match the cached graph. Other arguments are not part of the cache key. In particular, changing pc.n reuses the old graph. To force a rebuild, remove the graph first:
Subsetting a TglowDataset by objects drops the graph (with a warning), so it is rebuilt on the next call.
Running UMAP
UMAP is calculated from an existing PCA reduction using calculate_umap(). The result is stored in dataset@reduction under the name UMAP.PCA.<assay> by default.
pc.n (default 30) sets how many PCs are used: the UMAP is run on the first pc.n columns of the reduction. It must be less than or equal to the number of PCs in the reduction, so if you ran calculate_pca(..., pc.n=20), also pass pc.n=20 (or lower) here. When the PCA is calculated automatically, pc.n PCs are computed.
Additional arguments are passed through to uwot::umap(), so hyperparameters such as n_neighbors, min_dist and spread can be tuned via ....
For very large datasets, a random subsample can be used to compute the UMAP embedding. The output still has one row per object, but the rows that were not sampled are NA:
downsample can also be a vector of row indices to use.
Visualizing reductions
The tglow_dimplot() function plots any two-dimensional reduction stored in dataset@reduction.
Feature clustering and eigenfeatures
Many image features are strongly correlated. Clustering the features and summarising each cluster into one eigenfeature reduces this redundancy, which makes marker testing and interpretation easier.
calculate_feature_clustering(dataset, assay, slot, ...)clusters features on their correlation.methodcan be"complete"(default),"ward.D","ward.D2","louvain"or"leiden". For hierarchical methods,resolutionis the height at which the tree is cut. With"complete",resolution=0.2means all features in a cluster have a correlation of at least 0.8 with each other.feature.groupclusters groups of features separately. The clusters are added to the assay@featuresslot asfcl_<method>_res_<resolution>.calculate_eigenfeatures(dataset, assay, slot, cluster.col)calculates the first PC of each feature cluster and stores it in a new assay<assay>_eigenfeatures(in thedataslot). Its@featuresslot holdsvar,var_tot,var_exp(fraction of the cluster variance explained),n_featureandfeatures(the features in the cluster). Eigenfeatures have an arbitrary sign, and no scaling is applied first, so use thescale.dataslot as input.find_markers_ttest()andfind_markers_lmm()find marker features for the classes inident.find_markers_lmm()withmethod="lmm"fits a mixed model and needscovariates(by default each covariate is a random intercept), for example the well.method="lm"fits a plain linear model.find_eigenmarkers()runs feature clustering (unlessfcl.colis given), eigenfeature calculation and marker testing in one go.methodis"lmm"(default),"lm"or"ttest"; other arguments go to the marker function.plot_eigenmarkers(markers, eigenmarkers)plots the mean effect size of the features in each cluster per class, using per-feature markers and the output offind_eigenmarkers().
Features with NA values give NA eigenfeatures, so this example first keeps only features without NA's in scale.data: