---
title: "Meta-analysis Testing"
output: html_document
---
```{r}
# Load required libraries
library(SingleCellExperiment)
library(Seurat)
library(tidyverse)
library(MetaNeighbor)
```
```{r}
# Load the Seurat objects
hSeurat <- readRDS("hSeurat_annotated.rds")
vtSeurat <- readRDS("vtSeurat2_annotated.rds")
# Collapse the cell types in Han dataset
hmeta_copy <- hSeurat@meta.data %>%
select(Annotation)
dim(hSeurat@meta.data)
# read the cell types data frame
h_cell_types <- read.csv("Han Cell Types.csv") %>%
rename(Annotation = Annotations)
# use inner_join() on hmeta_copy and h_cell_types
df <- inner_join(hmeta_copy, h_cell_types)
# Check if the order is maintained
summary(df$Annotation == hmeta_copy$Annotation)
# add to meta.data
hSeurat$merged_annotation <- df$Merged
# Collapse the cell types in Han dataset
vtmeta_copy <- vtSeurat@meta.data %>%
select(Annotation)
# Do the same thing for the vtSeurat
vt_cell_types <- read.csv("VT Cell Types.csv") %>%
rename(Annotation = Annotations)
# use inner_join() on vtmeta_copy and vt_cell_types
df_vt <- inner_join(vtmeta_copy, vt_cell_types)
# Check if the order is maintained
summary(df_vt$Annotation == vtmeta_copy$Annotation)
# add to meta.data
vtSeurat$merged_annotation <- df_vt$Merged
# Change the Idents of the Seurat Objects
Idents(object = vtSeurat) <- "merged_annotation"
Idents(object = hSeurat) <- "merged_annotation"
```
```{r}
# Convert to SCE objects
hSCE <- as.SingleCellExperiment(hSeurat)
vtSCE <- as.SingleCellExperiment(vtSeurat)
# Create my_data
mydata <- list(hSCE = hSCE,
vtSCE = vtSCE)
# Check whether the gene information align between the two datasets
lapply(mydata, function(x) head(rownames(x), 3))
# cell-type information is labeled identically in all datasets
lapply(mydata, function(x) colnames(colData(x)))
# add the cell type information onto a new column name called "cell type"
mydata$hSCE$"cell type" <- mydata$hSCE$ident
mydata$vtSCE$"cell type" <- mydata$vtSCE$ident
# Check that count matrices stored in the assays slot, have identical names
lapply(mydata, function(x) names(assays(x)))
# Create a merged dataset by using mergeSCE, which takes a list of SCE objects
# as an input and outputs a single SCE object
fused_data <- mergeSCE(mydata)
dim(fused_data)
dim(hSCE)
dim(vtSCE)
head(colData(fused_data))
# To avoid having to recreate the merged object, save the R object to a file
# by using R's RDS format.
# saveRDS(fused_data, "merged_2_datasets.rds")
```
We notice that the fused data contains the cells from both datasets, as the # of columns is the sum of the two datasets.
```{r}
# Load RDS file
two_datasets <- readRDS("merged_2_datasets.rds")
# To obtain a cursory overview of cell-type composition by study, we cross-tabulate cell-type annotations by study IDs
table(two_datasets$"cell type", two_datasets$study_id)
# It is okay to have identical cell type names at this stage.
```
: Hierarchical cell-type replicability analysis
```{r, fig.height = 8, fig.width = 10}
# Picking the highly variable genes
global_hvgs <- variableGenes(dat = two_datasets,
exp_labels = two_datasets$study_id)
length(global_hvgs)
# MetaNeighborUS returns a cell-type-by-cell-type matrix containing cell-type similarities.
# This fast version should always be used on large datasets but can also be run on smaller datasets.
aurocs <- MetaNeighborUS(var_genes = global_hvgs,
dat = two_datasets,
study_id = two_datasets$study_id,
cell_type = two_datasets$"cell type",
fast_version = TRUE)
# Apparently, we can use this line of code as well.
MetaNeighbor::ggPlotHeatmap(aurocs, label_size = 10)
# To identify pairs of replicable cell types, run the following function
top_hits <- topHits(aurocs,
dat = two_datasets,
study_id = two_datasets$study_id,
cell_type = two_datasets$"cell type", threshold = 0.9)
top_hits
```
```{r fig.height = 8, fig.width = 10}
# When there is a clear structure in the data, we can refine AUROCs by
# splitting the data.
level1_split <- splitClusters(aurocs, k = 2)
level1_split
first_split <- level1_split[[1]]
first_split
# Repeat the MetaNeighbor analysis on immune cells only
full_labels <- makeClusterName(two_datasets$study_id,
two_datasets$`cell type`)
subdata <- two_datasets[, full_labels %in% first_split]
dim(subdata)
# To focus on variability specific to endocrine cells, re-pick highly variable genes
var_genes <- variableGenes(dat = subdata, exp_labels = subdata$study_id)
# recompute cell-type similarities and visualize AUROCs
aurocs <- MetaNeighborUS(var_genes = var_genes,
dat = subdata, fast_version = TRUE,
study_id = subdata$study_id,
cell_type = subdata$"cell type")
plotHeatmap(aurocs, cex = 0.7)
# Continue to zoom in as long as there are at least two cell types per dataset.
# Repeat steps 13-16
level2_split <- splitClusters(aurocs, k = 2)
level2_split
my_split <- level2_split[[1]]
my_split
subdata <- two_datasets[, full_labels %in% my_split]
var_genes <- variableGenes(dat = subdata, exp_labels = subdata$study_id)
length(var_genes)
aurocs <- MetaNeighborUS(var_genes = var_genes, dat = subdata,
fast_version = TRUE,
study_id = subdata$study_id,
cell_type = subdata$"cell type")
plotHeatmap(aurocs, cex = 1)
```
However, if we use one-vs-best AUROCs, MetaNeighbor can automatically identify the two closest matching cell types in each target dataset.
```{r fig.height = 10, fig.width = 10}
best_hits <- MetaNeighborUS(var_genes = global_hvgs,
dat = two_datasets,
study_id = two_datasets$study_id,
cell_type = two_datasets$"cell type",
fast_version = TRUE,
one_vs_best = TRUE, symmetric_output = FALSE)
plotHeatmap(best_hits, cex = 0.8)
```
```{r}
# Extracting cell types as meta-clusters
mclusters <- extractMetaClusters(best_hits, threshold = 0.7)
mcsummary <- scoreMetaClusters(mclusters, best_hits)
# scoreMetaClusters() function provides a good summary of meta-clusters
# Visualize the number of robust cell types, the replicability structure
# can be summarized as an Upset plot with plotUpset()
plotUpset(mclusters)
# Save the output as pdf.
pdf("meta_clusters.pdf")
plotMetaClusters(mclusters, best_hits)
while (!is.null(dev.list())) dev.off()
```
```{r fig.height = 6, fig.width = 8}
cluster_graph <- makeClusterGraph(best_hits, low_threshold = 0.3)
plotClusterGraph(cluster_graph, two_datasets$study_id,
two_datasets$"cell type", size_factor = 3)
# We can focus on a cluster of interest (coi).
# Take a closer look at 'hSCE|Dendritic cell', query its closest neighbors in the graph with extendClusterSet() and then zoom in on its subgraph with subsetClusterGraph()
coi <- "hSCE|Dendritic cell"
coi <- extendClusterSet(cluster_graph, initial_set = coi,
max_neighbor_distance = 2)
subgraph <- subsetClusterGraph(cluster_graph, coi)
plotClusterGraph(subgraph, two_datasets$study_id,
two_datasets$"cell type", size_factor = 5)
```