环境搭建:R与Python双栈配置

做空间转录组分析,我最常被问到的一个问题是:“到底用R还是Python?”

我的回答很干脆:两个都要用。Seurat在R生态里是当之无愧的利器,Scanpy、Squidpy在Python生态里同样不可替代。数据预处理阶段你用R更顺手,下游分析又想切到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)。

核心验证点只有一个——分别加载库并跑通最小数据集。

小提示:我个人强烈建议为Python专门建一个独立的conda环境,避免与系统Python或者其他项目的包产生冲突。你想想看,一旦包冲突,定位问题的时间可能比安装本身还长。

下面这张图概括了整个搭建流程,你可以先瞄一眼再动手:

双栈环境搭建与验证流程 R 栈 安装 R ≥ 4.3 + RStudio BiocManager::install("Seurat") 安装 SeuratData / 辅助包 验证:library(Seurat) + 运行示例 Python 栈 创建 conda 环境 (py39-st) pip install scanpy squidpy 安装可选的 leidenalg / louvain 验证:import scanpy as sc; sc.logging.print_header() 共享磁盘(h5ad / rds) ✓ 通过验证即环境就绪

二、R 栈:Seurat 安装与验证

2.1 安装 R 与 RStudio(可选)

先去 https://www.r-project.org/ 下载对应操作系统的 R 4.3 以上版本。Win / Mac / Linux 都有预编译包。我建议不要用系统包管理器里的低版本 R,因为很多 Bioconductor 包对新版 R 有硬依赖。

曾经踩过的坑:在 CentOS 7 上用 yum 安装的 R 是 3.6,结果 Seurat v5 安装时报错说缺少 C++17 特性。最后老老实实从 CRAN 源码编译才解决。时间浪费了整整两个小时。

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 栈环境搭建完毕。

调试技巧:我第一次画 UMAP 时遇到报错“找不到 umap-learn”。这是因为 RunUMAP 默认调用 Python 的 umap-learn 包。安装方法:在 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
注意:Squidpy 有一些可选依赖(如 napari 用于交互式可视化)。如果你不需要图形界面,不装也不影响核心功能。我遇到过同事盲目装全部 optional 依赖,结果 napari 需要的 qt 库冲突,折腾半天。

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()),方便后续复现或迁移。