3. 环境搭建
做空间转录组分析,我最常被问到的一个问题是:“到底用R还是Python?”
我的回答很干脆:两个都要用。Seurat在R生态里是当之无愧的利器,Scanpy、Squidpy在Python生态里同样不可替代。数据预处理阶段你用R更顺手,下游分析又想切到Python做深度网络,这种场景我几乎在每个项目里都会遇到。所以这一章,咱们就把双栈环境彻底搭好,一步到位验证通过。
一、环境规划概览
我习惯把整个环境分为两个独立但仍可互通的轨道:
- R 栈:R ≥ 4.3,Seurat v5,SeuratData,其他辅助包(ggplot2, dplyr, patchwork)。
- Python 栈:Python ≥ 3.9,Scanpy,Squidpy,AnnData / h5py,交互式环境(Jupyter Lab / VS Code)。
核心验证点只有一个——分别加载库并跑通最小数据集。
下面这张图概括了整个搭建流程,你可以先瞄一眼再动手:
二、R 栈:Seurat 安装与验证
2.1 安装 R 与 RStudio(可选)
先去 https://www.r-project.org/ 下载对应操作系统的 R 4.3 以上版本。Win / Mac / Linux 都有预编译包。我建议不要用系统包管理器里的低版本 R,因为很多 Bioconductor 包对新版 R 有硬依赖。
RStudio 可装可不装,如果你习惯用控制台+脚本编辑器,装一个更顺心。
2.2 安装 Seurat 核心包
启动 R 会话,执行以下命令:
# 先安装 BiocManager(管理 Bioconductor 包)
if (!require("BiocManager", quietly = TRUE))
install.packages("BiocManager")
# 安装 Seurat(会自动拉取依赖)
BiocManager::install("Seurat")
# 安装 SeuratData(提供测试数据集)
install.packages("SeuratData")
# 常用辅助包
install.packages(c("ggplot2", "dplyr", "patchwork", "remotes"))
整个过程可能等几分钟,因为 Seurat 和它的依赖(如 Matrix、Rcpp)需要编译。我记得第一次安装时,Windows 上因为缺少 Rtools 编译工具链,报了一大片红错。解决方案很简单:去 CRAN 下载 Rtools 并安装,然后在 R 里运行 writeLines('PATH="${RTOOLS40_HOME}\\usr\\bin;${PATH}"', con = "~/.Renviron") 指定路径即可。
2.3 验证:跑通最小示例
运行以下代码,不报错即证明安装成功:
library(Seurat)
library(SeuratData)
# 加载 pbmc3k 测试数据
InstallData("pbmc3k")
pbmc <- LoadData("pbmc3k")
# 标准预处理流程
pbmc <- NormalizeData(pbmc)
pbmc <- FindVariableFeatures(pbmc)
pbmc <- ScaleData(pbmc)
pbmc <- RunPCA(pbmc)
pbmc <- FindNeighbors(pbmc)
pbmc <- FindClusters(pbmc)
pbmc <- RunUMAP(pbmc)
# 检查聚类结果
DimPlot(pbmc, reduction = "umap", label = TRUE)
如果看到 UMAP 图出来,恭喜你——R 栈环境搭建完毕。
reticulate::py_install("umap-learn")。或者简单点,把参数改成 RunUMAP(pbmc, umap.method = "uwot") 直接用 R 原生 uwot 实现。
三、Python 栈:Scanpy 与 Squidpy 安装验证
3.1 创建独立的 Conda 环境
我强烈建议用 Miniconda 来隔离环境。下面是我常用的环境创建命令:
# 创建 Python 3.10 环境(3.9 或 3.11 均可)
conda create -n st_env python=3.10 -y
conda activate st_env
# 安装必要的系统依赖(Linux 下可能需要)
# conda install -c conda-forge gxx_linux-64 libstdcxx-ng # 编译用
为什么单独建个环境?因为 Scanpy 和 Squidpy 对 numpy / scipy 版本有特定要求,放在 base 环境里容易和别的项目打架。你想想看,一旦 pip 把 numpy 降级了,其他机器学习库可能直接罢工。
3.2 安装 Scanpy 和 Squidpy
激活环境后,用 pip 安装核心包:
pip install scanpy[leiden] squidpy
# 如果想把图学相关的也都装上,加上:
pip install leidenalg louvain igraph python-igraph
3.3 验证 Scanpy 核心功能
在同一个终端里(确保 conda 环境激活),执行 Python 交互式验证:
python -c "
import scanpy as sc
print('Scanpy version:', sc.__version__)
sc.logging.print_header()
# 加载测试数据集
adata = sc.datasets.pbmc3k()
sc.pp.filter_cells(adata, min_genes=200)
sc.pp.filter_genes(adata, min_cells=3)
sc.pp.normalize_total(adata, target_sum=1e4)
sc.pp.log1p(adata)
sc.pp.highly_variable_genes(adata, n_top_genes=2000)
sc.pp.pca(adata)
sc.pp.neighbors(adata)
sc.tl.leiden(adata)
sc.tl.umap(adata)
print('Scanpy 预处理和聚类均成功!')
"
不报错、打印版本信息,就表示 Python 栈跑通了。
3.4 验证 Squidpy
Squidpy 有自己的一套测试数据集和可视化函数。运行下面代码看看是否正常:
python -c "
import squidpy as sq
print('Squidpy version:', sq.__version__)
# 加载内置数据集
adata = sq.datasets.visium_hne_adata()
sq.gr.spatial_neighbors(adata)
print('Squidpy 空间邻接图构建成功!')
"
如果打印出版本号且无报错,双栈全部就绪。
四、双栈协同配置
很多时候我们想在 R 中直接调用 Python 的对象,或者互相传递数据。这里给两个实用方案:
| 场景 | 方法 | 示例 |
|---|---|---|
| R 调用 Python | 使用 reticulate 包 | library(reticulate); use_condaenv("st_env"); sc <- import("scanpy") |
| 数据格式互转 | AnnData ↔ Seurat 对象 | 用 sceasy 包(R)或 anndata2ri(Python) |
| 文件中介 | 统一写 h5ad 文件 | Python 导出 h5ad,R 用 SeuratDisk 或 zellkonverter 读取 |
我个人比较喜欢 h5ad 作为交换格式,因为它对空间数据结构支持好,在大文件读写时也比 rds 快不少。
五、常见问题与避坑指南
问题1:安装 Seurat 时提示 “package ‘Matrix’ is not available”
- 原因:通常是因为 R 版本太旧,或者镜像源没有最新 Matrix。
- 解决:先运行
update.packages(ask = FALSE)升级所有基础包,然后再装 Seurat。我曾在 Ubuntu 20.04 上遇到过一次,更新之后就正常了。
问题2:conda 安装 scanpy 时出现 “libstdc++ 版本冲突”
- 原因:系统 gcc / libstdc++ 太老。
- 解决:在 conda 环境内安装
conda install -c conda-forge gxx_linux-64=11.2.0,或者直接改用 pip 安装 scanpy(它依赖的二进制 wheel 通常自带动态库)。我曾经在老旧集群上用过 pip 版本完美绕过编译。
问题3:RStudio 中运行 reticulate 找不到 Python 环境
- 解决:在 R 控制台里手动指定:
reticulate::use_condaenv("st_env", required = TRUE)。或者设置环境变量RETICULATE_PYTHON为你 conda 环境里的 python 绝对路径。
到这里,R 和 Python 双栈已经稳稳地跑在你的机器上了。后面章节的所有批本质控操作,都会基于这个环境展开。你可以保存一份环境快照(conda 的 export 和 R 的 sessionInfo()),方便后续复现或迁移。