课前准备--大panel高精度空转(Xenium、seqFISH、CosMx等)依赖空间距离的细胞邻域通讯

作者,Evil Genius
我们的课程很快了,我也需要准备大量的内容,如果大家有兴趣并且有条件可以参加一下培训课程,链接在2025年单细胞空间系列课程https://links.jianshu.com/go?to=https%3A%2F%2F2.zoppoz.workers.dev%3A443%2Fhttps%2Fmp.weixin.qq.com%2Fs%2FkXQTRFpj8EFy1ra1AhUNvw%3Fpayreadticket%3DHKxi8uThyUrVvBospVLv94f8Kn0k1pZIwywHC_CHgbp0iBnT6D8QWqd3w5rrPOSbbRFP0ps,我们21号开始上第一课。
今天我们准备一下关于高精度空间细胞通讯相关的内容。

对于细胞通讯,无论是单细胞还是空间,都是分析重要的一环,就难度上而言,空间通讯因为要考虑细胞之间的空间位置关系,所以分析更为复杂一点,其中通过三角网络计算细胞间的物理距离和配体-受体相互作用分数是一种常用的方法。

其中构建细胞类型的空间关系,就分为以下几步。
1、将每个细胞视为空间中的一个点
2、构建网络连接邻近细胞
3、基于这些连接计算细胞间的相互作用
那么空间通讯的主要分析思路如下:
1、构建空间网络
2、确定配体-受体基因对
3、计算相邻细胞间的配体-受体相互作用分数。

相互作用分数计算原理
对于每对相邻细胞(i,j),相互作用分数计算通常考虑:
细胞i中配体基因的表达水平
细胞j中受体基因的表达水平
两者的乘积或更复杂的统计量
我们来实现一下
其中R脚本的传参与python是类似的,示例如下
# 创建参数解析器
parser <- ArgumentParser(description = "空间转录组配受体分析")

# 添加参数
parser$add_argument("--expression", type = "character", help = "表达矩阵文件路径")
parser$add_argument("--locations", type = "character", help = "细胞位置文件路径")
parser$add_argument("--output", type = "character", help = "输出目录路径")
parser$add_argument("--lr_pairs", type = "character", default = NULL, 
                    help = "自定义配体-受体对文件路径(可选)")
parser$add_argument("--n_cores", type = "integer", default = 4, 
                    help = "使用的CPU核心数")

# 解析参数
args <- parser$parse_args()
其中无论是哪种空间平台,都会有表达矩阵和空间坐标信息,只是放的位置可能不同,像CosMx就是单独给的,所以大家要灵活运用。
高精度平台的细胞注释,也是大家需要认真做的。
完整脚本如下,比较简单,cell_types为细胞注释的列。
#!/usr/bin/env Rscript
###zhaoyunfei
###20250417

suppressPackageStartupMessages({
  library(Giotto)
  library(data.table)
  library(ggplot2)
  library(argparse)
})


parser <- ArgumentParser(description = "空间转录组配受体分析")
parser$add_argument("--expression", type = "character", help = "表达矩阵文件路径")
parser$add_argument("--locations", type = "character", help = "细胞位置文件路径")
parser$add_argument("--output", type = "character", help = "输出目录路径")
parser$add_argument("--lr_pairs", type = "character", default = NULL, 
                    help = "自定义配体-受体对文件路径(可选)")
parser$add_argument("--n_cores", type = "integer", default = 4, 
                    help = "使用的CPU核心数")
args <- parser$parse_args()

if (!file.exists(args$expression)) {
  stop(paste("表达矩阵文件不存在:", args$expression))
}
if (!file.exists(args$locations)) {
  stop(paste("位置文件不存在:", args$locations))
}

if (!dir.exists(args$output)) {
  dir.create(args$output, recursive = TRUE)
}

cat("加载数据...\n")
expr_mat <- data.table::fread(args$expression)
loc_mat <- data.table::fread(args$locations)

if (!all(c("cell_ID", "x", "y") %in% colnames(loc_mat))) {
  stop("位置文件必须包含'cell_ID', 'x', 'y'列")
}

cat("创建Giotto对象...\n")
my_giotto_object <- createGiottoObject(
  expression = list(raw = as.matrix(expr_mat[, -1], rownames = expr_mat[[1]])),
  spatial_locs = as.matrix(loc_mat[, .(x, y)]),
  cell_metadata = data.frame(cell_ID = loc_mat$cell_ID),
  gene_metadata = data.frame(gene_ID = colnames(expr_mat)[-1])
)

cat("处理数据...\n")
my_giotto_object <- filterGiotto(gobject = my_giotto_object)
my_giotto_object <- normalizeGiotto(gobject = my_giotto_object)
my_giotto_object <- addStatistics(gobject = my_giotto_object)

cat("创建Delaunay空间网络...\n")
my_giotto_object <- createSpatialNetwork(gobject = my_giotto_object, 
                                        method = "Delaunay",
                                        name = "delaunay_network")

cat("进行配体-受体分析...\n")

if (!is.null(args$lr_pairs) && file.exists(args$lr_pairs)) {
  lr_pairs <- fread(args$lr_pairs)
} else {
  # 使用Giotto内置的配体-受体对
  lr_pairs <- Giotto::getLigandReceptors()
}

# 计算配体-受体分数
lr_scores <- exprCellCellcom(
  gobject = my_giotto_object,
  cluster_column = "cell_types", 
  spatial_network_name = "delaunay_network",
  random_iter = 100,
  gene_set_1 = lr_pairs$ligand,
  gene_set_2 = lr_pairs$receptor,
  cores = args$n_cores
)

cat("保存结果...\n")
fwrite(lr_scores, file.path(args$output, "ligand_receptor_scores.csv"))

cat("生成可视化...\n")

### 可视化空间网络
spatial_plot <- spatPlot(
  gobject = my_giotto_object,
  show_network = TRUE,
  network_color = "blue",
  spatial_network_name = "delaunay_network",
  point_size = 1.5,
  save_param = list(
    save_name = "spatial_network",
    save_dir = args$output
  )
)

# 可视化配体-受体相互作用热图
heatmap_plot <- heatmAPCellCellcom(
  gobject = my_giotto_object,
  comScores = lr_scores,
  save_param = list(
    save_name = "lr_interaction_heatmap",
    save_dir = args$output
  )
)

# 可视化特定配体-受体对的空间模式
if (nrow(lr_scores) > 0) {
  top_lr <- lr_scores[order(-LR_expr)][1:5, unique(LR_comb)]
  
  for (lr in top_lr) {
    lr_plot <- spatCellCellcom(
      gobject = my_giotto_object,
      comScores = lr_scores,
      selected_LR = lr,
      show_plot = FALSE,
      save_param = list(
        save_name = paste0("lr_interaction_", gsub(" ", "_", lr)),
        save_dir = args$output
      )
    )
  }
}

cat("分析完成! 结果保存在:", args$output, "\n")

生活很好,有你更好
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值