knitr::opts_chunk$set( message = FALSE, warning = FALSE, collapse = TRUE, fig.align = "center", comment = "#>", crop = NULL )
clustifyr
?Single cell transcriptomes are difficult to annotate without extensive knowledge of the underlying biology of the system in question. Even with this knowledge, accurate identification can be challenging due to the lack of detectable expression of common marker genes defined by bulk RNA-seq, flow cytometry, other single cell RNA-seq platforms, etc.
clustifyr
solves this problem by providing functions to automatically annotate single cells or clusters using bulk RNA-seq data or marker gene lists (ranked or unranked). Additional functions allow for exploratory analysis of calculated similarities between single cell RNA-seq datasets and reference data.
To install clustifyr
BiocManager must be installed.
install.packages("BiocManager") BiocManager::install("clustifyr")
In this example, we take a 10x Genomics 3' scRNA-seq dataset from peripheral blood mononuclear cells (PBMCs) and annotate the cell clusters (identified using Seurat
) using scRNA-seq cell clusters assigned from a CITE-seq experiment.
library(clustifyr) library(ggplot2) library(cowplot) # Matrix of normalized single-cell RNA-seq counts pbmc_matrix <- clustifyr::pbmc_matrix_small # meta.data table containing cluster assignments for each cell # The table that we are using also contains the known cell identities in the "classified" column pbmc_meta <- clustifyr::pbmc_meta
To identify cell types, the clustifyr()
function requires several inputs:
input
: an SingleCellExperiment or Seurat object or a matrix of normalized single-cell RNA-seq countsmetadata
: a meta.data table containing the cluster assignments for each cell (not required if a Seurat object is given)ref_mat
: a reference matrix containing RNA-seq expression data for each cell type of interestquery_genes
: a list of genes to use for comparison (optional but recommended)When using a matrix of scRNA-seq counts clustifyr()
will return a matrix of correlation coefficients for each cell type and cluster, with the rownames corresponding to the cluster number.
# Calculate correlation coefficients for each cluster (spearman by default) vargenes <- pbmc_vargenes[1:500] res <- clustify( input = pbmc_matrix, # matrix of normalized scRNA-seq counts (or SCE/Seurat object) metadata = pbmc_meta, # meta.data table containing cell clusters cluster_col = "seurat_clusters", # name of column in meta.data containing cell clusters ref_mat = cbmc_ref, # matrix of RNA-seq expression data for each cell type query_genes = vargenes # list of highly varible genes identified with Seurat ) # Peek at correlation matrix res[1:5, 1:5] # Call cell types res2 <- cor_to_call( cor_mat = res, # matrix correlation coefficients cluster_col = "seurat_clusters" # name of column in meta.data containing cell clusters ) res2[1:5, ] # Insert into original metadata as "type" column pbmc_meta2 <- call_to_metadata( res = res2, # data.frame of called cell type for each cluster metadata = pbmc_meta, # original meta.data table containing cell clusters cluster_col = "seurat_clusters" # name of column in meta.data containing cell clusters )
To visualize the clustifyr()
results we can use the plot_cor_heatmap()
function to plot the correlation coefficients for each cluster and each cell type.
# Create heatmap of correlation coefficients using clustifyr() output plot_cor_heatmap(cor_mat = res)
clustifyr
also provides functions to overlay correlation coefficients on pre-calculated tSNE embeddings (or those from any other dimensionality reduction method).
# Overlay correlation coefficients on UMAPs for the first two cell types corr_umaps <- plot_cor( cor_mat = res, # matrix of correlation coefficients from clustifyr() metadata = pbmc_meta, # meta.data table containing UMAP or tSNE data data_to_plot = colnames(res)[1:2], # name of cell type(s) to plot correlation coefficients cluster_col = "seurat_clusters" # name of column in meta.data containing cell clusters ) plot_grid( plotlist = corr_umaps, rel_widths = c(0.47, 0.53) )
The plot_best_call()
function can be used to label each cluster with the cell type that gives the highest corelation coefficient. Using the plot_dims()
function, we can also plot the known identities of each cluster, which were stored in the "classified" column of the meta.data table. The plots below show that the highest correlations between the reference RNA-seq data and the 10x Genomics scRNA-seq dataset are restricted to the correct cell clusters.
# Label clusters with clustifyr cell identities clustifyr_types <- plot_best_call( cor_mat = res, # matrix of correlation coefficients from clustifyr() metadata = pbmc_meta, # meta.data table containing UMAP or tSNE data do_label = TRUE, # should the feature label be shown on each cluster? do_legend = FALSE, # should the legend be shown? cluster_col = "seurat_clusters" ) + ggtitle("clustifyr cell types") # Compare clustifyr results with known cell identities known_types <- plot_dims( data = pbmc_meta, # meta.data table containing UMAP or tSNE data feature = "classified", # name of column in meta.data to color clusters by do_label = TRUE, # should the feature label be shown on each cluster? do_legend = FALSE # should the legend be shown? ) + ggtitle("Known cell types") plot_grid(known_types, clustifyr_types)
The clustify_lists()
function allows cell types to be assigned based on known marker genes. This function requires a table containing markers for each cell type of interest. Cell types can be assigned using several statistical tests including, hypergeometric, Jaccard, Spearman, and GSEA.
# Take a peek at marker gene table cbmc_m # Available metrics include: "hyper", "jaccard", "spearman", "gsea" list_res <- clustify_lists( input = pbmc_matrix, # matrix of normalized single-cell RNA-seq counts metadata = pbmc_meta, # meta.data table containing cell clusters cluster_col = "seurat_clusters", # name of column in meta.data containing cell clusters marker = cbmc_m, # list of known marker genes metric = "pct" # test to use for assigning cell types ) # View as heatmap, or plot_best_call plot_cor_heatmap( cor_mat = list_res, # matrix of correlation coefficients from clustify_lists() cluster_rows = FALSE, # cluster by row? cluster_columns = FALSE, # cluster by column? legend_title = "% expressed" # title of heatmap legend ) # Downstream functions same as clustify() # Call cell types list_res2 <- cor_to_call( cor_mat = list_res, # matrix correlation coefficients cluster_col = "seurat_clusters" # name of column in meta.data containing cell clusters ) # Insert into original metadata as "list_type" column pbmc_meta3 <- call_to_metadata( res = list_res2, # data.frame of called cell type for each cluster metadata = pbmc_meta, # original meta.data table containing cell clusters cluster_col = "seurat_clusters", # name of column in meta.data containing cell clusters rename_prefix = "list_" # set a prefix for the new column )
SingleCellExperiment
objectsclustifyr
can also use a SingleCellExperiment
object as input and return a new SingleCellExperiment
object with the cell types added as a column in the colData.
res <- clustify( input = sce_small, # an SCE object ref_mat = cbmc_ref, # matrix of RNA-seq expression data for each cell type cluster_col = "cell_type1", # name of column in meta.data containing cell clusters obj_out = TRUE # output SCE object with cell type inserted as "type" column ) SingleCellExperiment::colData(res)[1:10,c("type", "r")] #> DataFrame with 10 rows and 2 columns #> type r #> <character> <numeric> #> AZ_A1 CD34+ 0.557678024919381 #> AZ_A10 CD34+ 0.624777701661225 #> AZ_A11 CD4 T 0.695067885340303 #> AZ_A12 CD34+ 0.624777701661225 #> AZ_A2 CD4 T 0.602804908958642 #> AZ_A3 CD34+ 0.557678024919381 #> AZ_A4 CD34+ 0.557678024919381 #> AZ_A5 CD34+ 0.645378073051508 #> AZ_A6 CD4 T 0.695067885340303 #> AZ_A7 CD34+ 0.671644883893203
seurat
v2 and v3 objectsclustifyr
can also use a Seurat
object as input and return a new Seurat
object with the cell types added as a column in the meta.data.
res <- clustify( input = s_small, # a Seurat object ref_mat = cbmc_ref, # matrix of RNA-seq expression data for each cell type cluster_col = "res.1", # name of column in meta.data containing cell clusters obj_out = TRUE # output Seurat object with cell type inserted as "type" column ) res@meta.data[1:10, ] #> nGene nUMI orig.ident res.0.8 res.1 type r #> ATGCCAGAACGACT 47 70 SeuratProject 0 0 Memory CD4 T 0.7047302 #> CATGGCCTGTGCAT 52 85 SeuratProject 0 0 Memory CD4 T 0.7047302 #> GAACCTGATGAACC 50 87 SeuratProject 0 0 Memory CD4 T 0.7047302 #> TGACTGGATTCTCA 56 127 SeuratProject 0 0 Memory CD4 T 0.7047302 #> AGTCAGACTGCACA 53 173 SeuratProject 0 0 Memory CD4 T 0.7047302 #> TCTGATACACGTGT 48 70 SeuratProject 0 0 Memory CD4 T 0.7047302 #> TGGTATCTAAACAG 36 64 SeuratProject 0 0 Memory CD4 T 0.7047302 #> GCAGCTCTGTTTCT 45 72 SeuratProject 0 0 Memory CD4 T 0.7047302 #> GATATAACACGCAT 36 52 SeuratProject 0 0 Memory CD4 T 0.7047302 #> AATGTTGACAGTCA 41 100 SeuratProject 0 0 Memory CD4 T 0.7047302
In its simplest form, a reference matrix is built by averaging expression (also includes an option to take the median) of a single cell RNA-seq expression matrix by cluster. Both log transformed or raw count matrices are supported.
new_ref_matrix <- average_clusters( mat = pbmc_matrix, metadata = pbmc_meta$classified, # or use metadata = pbmc_meta, cluster_col = "classified" if_log = TRUE # whether the expression matrix is already log transformed ) head(new_ref_matrix) # For further convenience, a shortcut function for generating reference matrix from `SingleCellExperiment` or `seurat` object is used. new_ref_matrix_sce <- object_ref( input = sce_small, # SCE object cluster_col = "cell_type1" # name of column in colData containing cell identities ) new_ref_matrix_v2 <- seurat_ref( seurat_object = s_small, # seuratv2 object cluster_col = "res.1" # name of column in meta.data containing cell identities ) new_ref_matrix_v3 <- seurat_ref( seurat_object = s_small3, # SeuratV3 object cluster_col = "RNA_snn_res.1" # name of column in meta.data containing cell identities ) tail(new_ref_matrix_v3)
# There's also the option to pull UCSC cell browser data. get_ext_reference(cb_url = "http://cells.ucsc.edu/?ds=kidney-atlas%2FFetal_Immune", cluster_col = "celltype")
More reference data, including tabula muris, and code used to generate them are available at https://github.com/rnabioco/clustifyrdata
Also see list for individual downloads at https://rnabioco.github.io/clustifyr/articles/download_refs.html
Additional tutorials at https://rnabioco.github.io/clustifyrdata/articles/otherformats.html
sessionInfo()
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.