在多组空间转录组数据的研究中,如何有效挖掘细胞间通信是个关键问题。🙋♀️
CellChat
是一个专门用于分析细胞间通信的强大工具,现在也是支持空间转录组的分析了。🧐
今天写的是多组数据的分析!~😜
不得不说的是,这个示例数据真难找啊,原作者也没上传完全啊!~😰
rm(list = ls())
library(tidyverse)
library(CellChat)
library(patchwork)
library(Seurat)
seu1 <- readRDS("./Cellchat_spatial_multi/Spatial_A1_adult_with_predictions.RDS")
seu2 <- readRDS("./Cellchat_spatial_multi/Spatial_A2_adult_with_predictions.RDS")
# assign label to each spot based on the maximum predicted probabilities
assignLabels <- function(object, prediction = "predictions") {
pred <- object[[prediction]]@data
pred <- pred[1:(nrow(pred)-1), ]
# label each spot based on the maximum prediction probability
labels = rownames(pred)[apply(pred, 2, which.max)]
names(labels) <- colnames(pred)
object$labels <- factor(labels)
Idents(object) <- "labels"
return(object)
}
seu1 <- assignLabels(seu1, prediction = "adult.predictions")
seu2 <- assignLabels(seu2, prediction = "adult.predictions")
可视化一下!~😏
# show the image and annotated spots
color.use <- scPalette(nlevels(seu1)); names(color.use) <- levels(seu1)
p1 <- Seurat::SpatialDimPlot(seu1, label = F, label.size = 3, cols = color.use)
color.use <- scPalette(nlevels(seu2)); names(color.use) <- levels(seu2)
p2 <- Seurat::SpatialDimPlot(seu2, label = F, label.size = 3, cols = color.use) + NoLegend()
p1 + p2
# Prepare input data for CelChat analysis
data.input1 = Seurat::GetAssayData(seu1, slot = "data", assay = "SCT") # normalized data matrix
data.input2 = Seurat::GetAssayData(seu2, slot = "data", assay = "SCT")
选取共同基因!~🧬
genes.common <- intersect(rownames(data.input1), rownames(data.input2))
colnames(data.input1) <- paste0("A1_", colnames(data.input1))
colnames(data.input2) <- paste0("A2_", colnames(data.input2))
data.input <- cbind(data.input1[genes.common, ], data.input2[genes.common, ])
定义metadata
,区分数据来源。😘
meta1 = data.frame(labels = Idents(seu1), samples = "A1") # manually create a dataframe consisting of the cell labels
meta2 = data.frame(labels = Idents(seu2), samples = "A2")
meta <- rbind(meta1, meta2)
rownames(meta) <- colnames(data.input)
meta$labels <- factor(meta$labels, levels = levels(Idents(seu1)))
meta$samples <- factor(meta$samples, levels = c("A1", "A2"))
unique(meta$labels) # check the cell labels
unique(meta$samples) # check the sample labels
定义空间坐标!~💪
# load spatial transcriptomics information
spatial.locs1 = Seurat::GetTissueCoordinates(seu1, scale = NULL, cols = c("imagerow", "imagecol"))
spatial.locs2 = Seurat::GetTissueCoordinates(seu2, scale = NULL, cols = c("imagerow", "imagecol"))
spatial.locs <- rbind(spatial.locs1, spatial.locs2)
rownames(spatial.locs) <- colnames(data.input)
# Scale factors of spatial coordinates
scalefactors1 = jsonlite::fromJSON(txt = file.path("./Cellchat_spatial_multi/", 'A1_scalefactors_json.json'))
spot.size = 65 # the theoretical spot size (um) in 10X Visium
conversion.factor1 = spot.size/scalefactors1$spot_diameter_fullres
spatial.factors1 = data.frame(ratio = conversion.factor1, tol = spot.size/2)
scalefactors2 = jsonlite::fromJSON(txt = file.path("Cellchat_spatial_multi/", 'A2_scalefactors_json.json'))
conversion.factor2 = spot.size/scalefactors2$spot_diameter_fullres
spatial.factors2 = data.frame(ratio = conversion.factor2, tol = spot.size/2)
spatial.factors <- rbind(spatial.factors1, spatial.factors2)
rownames(spatial.factors) <- c("A1", "A2")
cellchat <- createCellChat(object = data.input, meta = meta, group.by = "labels",
datatype = "spatial", coordinates = spatial.locs, spatial.factors = spatial.factors)
cellchat
CellChatDB <- CellChatDB.human # use CellChatDB.human if running on human data
# use a subset of CellChatDB for cell-cell communication analysis
CellChatDB.use <- subsetDB(CellChatDB, search = "Secreted Signaling", key = "annotation") # use Secreted Signaling
# set the used database in the object
cellchat@DB <- CellChatDB.use
# subset the expression data of signaling genes for saving computation cost
cellchat <- subsetData(cellchat) # This step is necessary even if using the whole database
future::plan("multisession", workers = 4)
cellchat <- identifyOverExpressedGenes(cellchat)
cellchat <- identifyOverExpressedInteractions(cellchat)
计算通信概率并推断细胞通讯网络!~🛜
cellchat <- computeCommunProb(cellchat, type = "truncatedMean", trim = 0.1,
distance.use = FALSE, interaction.range = 250, scale.distance = NULL,
contact.dependent = TRUE, contact.range = 100)
过滤细胞间通信。默认情况下,阈值设置为10
。🙃
cellchat <- filterCommunication(cellchat, min.cells = 10)
CellChat
通过汇总与每个信号通路相关的所有配体-受体相互作用的通信概率来计算信号通路级别的通信概率。🙊
推断出的每个配体-受体对和每个信号通路的细胞间通信网络分别存储在net
和netP
中,大家可以根据这个数据进行DIY
。😘
cellchat <- computeCommunProbPathway(cellchat)
我们可以通过计算link
数量或汇总通讯概率来计算叠加的
细胞间通讯网络。
cellchat <- aggregateNet(cellchat)
可视化一下!~😇
groupSize <- as.numeric(table(cellchat@idents))
par(mfrow = c(1,2), xpd=TRUE)
netVisual_circle(cellchat@net$count, vertex.weight = rowSums(cellchat@net$count), weight.scale = T, label.edge= F, title.name = "Number of interactions")
netVisual_circle(cellchat@net$weight, vertex.weight = rowSums(cellchat@net$weight), weight.scale = T, label.edge= F, title.name = "Interaction weights/strength")
热图展示!~ 😏
netVisual_heatmap(cellchat, measure = "count", color.heatmap = "Blues")
netVisual_heatmap(cellchat, measure = "weight", color.heatmap = "Blues")
这里我们以一条信号通路为例。所有显示重要通讯的信号通路可通过cellchat@netP$
找到。
pathways.show <- c("EGF")
# Circle plot
par(mfrow=c(1,1), xpd=TRUE)
netVisual_aggregate(cellchat, signaling = pathways.show, layout = "circle")
# Spatial plot
par(mfrow=c(1,1))
netVisual_aggregate(cellchat, signaling = pathways.show, sample.use = "A1", layout = "spatial", edge.width.max = 2, vertex.size.max = 1, alpha.image = 0.2, vertex.label.cex = 0)
计算并可视化网络中心性分数!~🦀
# Compute the network centrality scores
cellchat <- netAnalysis_computeCentrality(cellchat, slot.name = "netP") # the slot 'netP' means the inferred intercellular communication network of signaling pathways
# Visualize the computed centrality scores using heatmap, allowing ready identification of major signaling roles of cell groups
par(mfrow=c(1,1))
netAnalysis_signalingRole_network(cellchat, signaling = pathways.show, width = 8, height = 2.5, font.size = 10)
par(mfrow=c(1,1))
netVisual_aggregate(cellchat, signaling = pathways.show, sample.use = "A1", layout = "spatial", edge.width.max = 2, alpha.image = 0.2, vertex.weight = "incoming", vertex.size.max = 6, vertex.label.cex = 0)
计算每个配体-受体对整个信号通路的贡献!~🙊
netAnalysis_contribution(cellchat, signaling = pathways.show)
使用spatialFeaturePlot
可视化具体基因的表达!~🐶
# Take an input of a few genes
spatialFeaturePlot(cellchat, features = c("AREG","EGFR"), sample.use = "A1", point.size = 0.8, color.heatmap = "Reds", direction = 1)
spatialFeaturePlot(cellchat, features = c("AREG","EGFR"), sample.use = "A2",point.size = 0.8, color.heatmap = "Reds", direction = 1)
使用spatialFeaturePlot
可视化具体受体-配体对的表达!~🐶
spatialFeaturePlot(cellchat, pairLR.use = "AREG_EGFR", sample.use = "A1", point.size = 0.5, do.binary = FALSE, cutoff = 0.05, enriched.only = F, color.heatmap = "Reds", direction = 1)
使用spatialFeaturePlot
可视化具体受体-配体对的表达!~🐶(这里是0
和1
的关系。😜)
# Take an input of a ligand-receptor pair and show expression in binary
spatialFeaturePlot(cellchat, pairLR.use = "AREG_EGFR", sample.use = "A1", point.size = 1.5, do.binary = TRUE, cutoff = 0.05, enriched.only = F, color.heatmap = "Reds", direction = 1)