CellChat是先识别出高表达的配体受体,并识别这些高表达的配体-受体相互作用,并为每个相互作用分配一个概率值,并且采用并行计算的方法,去推断具有生物学意义的细胞间通讯网络。
从生物学角度来看,比如患病的组织相比于没有患病的组织,一定有一部分细胞当中的某些配体和受体,一定是有更高表达了的(或者更低表达了的),于是我们要采用统计学方法去计算各个配体和受体之间相互作用的概率,然后用可视化去展现出来。
核心原理
CellChat通过两个关键机制推断有生物学意义的细胞间通讯:
- 为每个互作分配概率值
- 执行置换检验验证统计显著性
它结合基因表达数据和已知的信号配体、受体及其辅助因子之间的互作先验知识,使用质量作用定律建模细胞间通讯概率。
关键参数选择
平均基因表达计算方法
代码强调了平均基因表达计算方法对结果的重要影响:
- 默认方法:
triMean
(统计学上稳健的平均值方法)- 产生较少但更强的互作
- 近似于25%截断平均值(如果一个细胞群中表达细胞<25%,平均表达为零)
- 替代方法:
truncatedMean
(可以设置截断比例)- 设置
trim = 0.1
使用10%截断平均值 - 产生更多的互作,适合探索已知但未被默认方法检测到的通路
- 设置
为了确定合适的trim值,CellChat提供了一个函数computeAveExpr,可以检查某段信号基因的平均表达。如果在一个已知的信号通路未被检测到,我们可以尝试使用更低的trim值,去重新计算每个cell group平均基因表达量。
当分析未经细胞分选的单细胞转录组时,CellChat可以考虑细胞比例的影响:
- 基于假设:丰富细胞群体倾向发送集体更强信号
- 通过设置
population.size = TRUE
启用 - 这样就可以在概率计算中考虑到每个细胞群中细胞比例的影响
一、计算通信概率并推断细胞通讯网络
ptm = Sys.time()
cellchat <- computeCommunProb(cellchat, type = "triMean")
#> triMean is used for calculating the average gene expression per cell group.
#> [1] ">>> Run CellChat on sc/snRNA-seq data <<< [2024-02-14 00:32:35.767285]"
#> [1] ">>> CellChat inference is done. Parameter values are stored in `object@options$parameter` <<< [2024-02-14 00:33:13.121225]"
这里可以选择参数为triMean或者truncatedMean,即选择一个基因平均表达的计算方法。
如果选择truncatedMean,那么可以采用下面的方法,即还需要确定trim值。
computeAveExpr(cellchat, features = c("CXCL12","CXCR4"), type = "truncatedMean", trim = 0.1)
cellchat <- filterCommunication(cellchat, min.cells = 10)
这一步过滤掉了细胞数量不足的细胞群之间的通讯,默认要求每个细胞群至少有10个细胞。
二、数据提取与通路级推断(将细胞通信网络提取为一个数据框)
df.net <- subsetCommunication(cellchat) # 所有配体/受体级别的通讯
df.net <- subsetCommunication(cellchat, slot.name = "netP") # 通路级别的通讯
df.net <- subsetCommunication(cellchat, sources.use = c(1,2), targets.use = c(4,5)) # 特定细胞群体间的通讯
df.net <- subsetCommunication(cellchat, signaling = c("WNT", "TGFb")) # 特定信号通路的通讯
三、在信号通路水平上推断细胞间的通讯
通路级别的计算通过汇总与每个信号通路相关的所有配体-受体互作的通讯概率来完成:
cellchat <- computeCommunProbPathway(cellchat)
四、细胞通讯网络分析与可视化
CellChat通过计数链接数或汇总通讯概率来计算聚合的细胞间通讯网络:
cellchat <- aggregateNet(cellchat)
execution.time = Sys.time() - ptm
print(as.numeric(execution.time, units = "secs"))
#> [1] 38.73308
可视化聚合网络的两种方式:
- 展示任意两个细胞群体之间的互作数量
- 展示总互作强度(权重)
ptm = Sys.time()
groupSize <- as.numeric(table(cellchat@idents))
par(mfrow = c(1,2), xpd=TRUE)
netVisual_circle(cellchat@net$count, vertex.weight = groupSize, weight.scale = T, label.edge= F, title.name = "Number of interactions")
netVisual_circle(cellchat@net$weight, vertex.weight = groupSize, weight.scale = T, label.edge= F, title.name = "Interaction weights/strength")
这段代码创建了两张并排的圆形图,展示全局细胞通讯网络:
- 左图:展示细胞群体间的互作数量
cellchat@net$count
矩阵包含每对细胞群体之间的互作数量
- 右图:展示细胞群体间的互作强度
cellchat@net$weight
矩阵包含每对细胞群体之间通讯信号的总强度
两图共同参数:
vertex.weight = groupSize
:节点大小反映各细胞群体的细胞数量weight.scale = T
:根据互作强度/数量比例缩放边的宽度label.edge = F
:不显示边的标签,使图更清晰
mat <- cellchat@net$weight
par(mfrow = c(3,4), xpd=TRUE)
for (i in 1:nrow(mat)) {
mat2 <- matrix(0, nrow = nrow(mat), ncol = ncol(mat), dimnames = dimnames(mat))
mat2[i, ] <- mat[i, ]
netVisual_circle(mat2, vertex.weight = groupSize, weight.scale = T, edge.weight.max = max(mat), title.name = rownames(mat)[i])
}
这段代码创建了一个3×4的图表网格,展示每个细胞群体作为信号发送者的情况:
- 循环遍历每个细胞群体(行)
- 创建一个仅包含该特定细胞群体发送信号的矩阵
- 可视化该细胞群体向其他所有细胞群体发送的信号
关键参数:
edge.weight.max = max(mat)
:统一所有子图的边缘权重最大值,使不同细胞群体间的信号强度可直接比较title.name = rownames(mat)[i]
:每个子图的标题是相应细胞群体的名称
第一段代码提供了细胞通讯网络的整体视图,可以快速识别主要的通讯渠道和信号强度
第二段代码提供了细胞通讯网络的发送者分解视图,帮助理解每个细胞群体在整体通讯网络中的特定贡献