BioF3 组学数据分析

基础入门手册

BioF3 基础入门专题导出版

导出日期:2026年6月27日

01 组学数据分析入门

如果是第一次接触生物信息学,这篇文章帮你建立一个清晰的认知框架:组学数据为什么需要专门的分析方法、它的整体流程长什么样、第一步该走到哪里。

从一份数据开始

假设手上有一份单细胞 RNA 测序数据:10000 个细胞 × 20000 个基因的表达矩阵,2 亿个数据点。

要回答的问题可能是:

组学分析的核心问题就在这一刻浮现:怎么从这份海量、嘈杂、稀疏的数据里,把生物学意义提取出来

组学之间的关系

理解组学,先理解中心法则把它们分成的几个层次:

DNA  ────────►  RNA  ────────►  蛋白
(基因组)       (转录组)       (蛋白组)
层次 它告诉你 主要技术
基因组(Genomics) 这个个体有什么基因、有什么变异 WGS / WES / Panel 测序
转录组(Transcriptomics) 哪些基因正在表达、表达多少 bulk RNA-seq / scRNA-seq
蛋白组(Proteomics) 哪些蛋白真的被合成出来、丰度多少 质谱
表观组(Epigenomics) 哪些基因被"打开",调控状态如何 ATAC-seq / ChIP-seq / 甲基化

三个关键点:

把组学放进这个框架里,后面学的每一篇教程都能找到自己的位置。

组学数据的四个特点

每个特点都不只是一个描述,它决定了这条数据该怎么处理。

1. 数据量大 → 工具链整体是命令行 + 脚本

一次单细胞实验产生几十 GB 原始数据。Excel 打不开、记事本卡死,靠 GUI 工具点鼠标的工作流不再适用。学组学分析的前提是接受"工具链整体跑在命令行 + 脚本里"这件事。

2. 维度高 → PCA / UMAP 不是装饰,是必经之路

人类编码基因约 2 万,全转录组(含非编码 RNA)4-6 万。这意味着每个样本对应的向量有几万维。人脑无法在几万维里直接找规律,降维(PCA / UMAP / t-SNE)是把数据"翻译"成人能看的形式,不是为了好看。

3. 噪音多 → 永远看分布和重复,别看单点

生物学实验本身有变异(同一组织取两次切片不完全一样),测序技术也有误差(PCR 偏差、批次效应)。任何单一数据点都不可靠,下游分析要靠分布、重复、统计检验才能从噪音里捞出真信号。

4. 稀疏 → 单细胞要专门处理 dropout

单细胞数据里大量基因在大多数细胞中表达量为 0,部分是技术 dropout(基因实际表达但没测到),部分是真实未表达。对这种稀疏矩阵,普通线性方法(CPM / log)会失真,所以才有 SCTransform、scVI 这种专门的方法。

分析流程概览

一份组学项目从原始数据到结论,大致 9 步:

  1. 数据获取:从测序仪下机的 FASTQ 文件,或从 GEO/TCGA 等公共库下载
  2. 质量控制:检查测序质量、过滤低质量 reads(FastQC / MultiQC)
  3. 序列比对:把 reads 比对回参考基因组(Cell Ranger / STAR / BWA)
  4. 表达矩阵构建:统计每个基因在每个样本/细胞里的 reads 数
  5. 数据标准化:去掉测序深度差异(CPM / TPM / SCTransform)
  6. 降维 + 聚类:把高维数据投到 2D 看结构(PCA / UMAP),然后聚类
  7. 差异分析:比较组间表达差异,找标志基因
  8. 功能注释:用 GO / KEGG / GSEA 把基因列表翻译成生物学故事
  9. 可视化:热图、火山图、UMAP 等 — 让结果说话

这 9 步可以分成两段:

学习时这两段可以分开攻:先用现成矩阵跑通第 5-9 步(很多教程数据集自带矩阵),等对结果有感觉了再回头补 1-4 的数据工程。这样能更快建立成就感和判断力。

学习路径建议

第 1 阶段:能跑起来(2-4 周)

选一门主语言(推荐 R 起步,单细胞主流工具用 R),能完成最小可复现的小任务:

强烈建议先看一眼 AI 辅助编程与智能体工具,了解什么时候该让 AI 帮忙、什么时候不该。

第 2 阶段:跑通完整流程(4-8 周)

跟着教程从原始数据走到最终结果。先不深究每个参数为什么这么选,优先把流程跑通一次

推荐 单细胞实践 01-04

第 3 阶段:理解每一步在做什么(2-3 个月)

回过头来看每一步的原理,调参看效果变化,读相关文献和工具文档。

推荐 单细胞实践 05-10

第 4 阶段:独立做项目(持续)

用自己的或公开数据做完整分析。这一阶段标志是:遇到问题不再问"我该用什么工具",而是问"这个生物学问题最适合的方法是什么"。

常见误区

"工具越新越好"

新工具可能引用量很高但默认参数不一定稳。成熟工具(Seurat / DESeq2 / clusterProfiler)经过多年大量数据验证,先用它们建立基线再尝试新方法更稳妥。

"参数复杂 = 严谨"

绝大多数主流工具的默认参数已经是经过精心调过的。盲目调参可能把模型推到训练数据外的区域。理解参数含义比调参更重要

"p < 0.05 就是好结果"

p 值只是统计学显著性,不代表生物学意义。一个 padj=1e-50 但 log2FC=0.1 的基因,统计上极显著,生物学上几乎没区别。要 padj fold change 一起看。

"图越炫越有说服力"

清晰准确比炫酷重要。一张干净的散点图、火山图、热图比 3D 旋转图更能说服审稿人。把图当成证据,不是装饰。

持续学习

下一步

接着深入(按推荐顺序读下去):

  1. 编程基础 — 选定一门主语言,建立最小工作流
  2. 数据与环境准备 — 把后续脚本要的数据和包准备好,避免每次报错都查
  3. 单细胞实践 01:实践数据集与数据获取 — 第一个完整可跑的真实流程

横向延伸(任意时机看):

02 AI 辅助编程与智能体工具

AI 编程工具已经从"补全几行代码"发展到"阅读项目、修改文件、运行命令、检查结果"的智能体工作流。对组学数据分析来说,它们可以显著提高效率,但不能替代你对数据、统计方法和生物学问题的判断

这一篇不追工具热点,目的是建立一套可靠的使用框架:什么时候用 AI、怎么交付任务、如何检查结果、哪些数据不能交给外部服务。

先记住一句话

AI 帮你打字,不替你思考。

打字层面(写一段代码、改一份脚本、生成测试)AI 越来越快,但思考层面(这份数据该不该用、这个统计方法对不对、这条结论能不能写)必须人来。

下面所有内容都围绕这一句展开。

什么是 vibe coding

Vibe coding 指用自然语言描述目标,让 AI 快速生成原型代码或应用。它适合探索想法,例如:

它的代价也直白:模型默认很多假设,生成的代码看起来能跑,但不一定统计上正确、可重复或适合真实数据。

所以 vibe coding 在 BioF3 的语境里只是"快速草稿",后续必须补上:

智能体工具和普通聊天的区别

普通聊天工具只回答问题。智能体工具可以连接代码环境,做更完整的开发动作:

权限越大,风险越高。第一次接入新工具时,先让它只读:让它解释项目结构、提出修改计划,确认无误后再允许它真的改文件。

常见工具类型

1. IDE 内置助手

嵌入编辑器,适合日常写代码、解释局部文件、生成函数和查看 diff。

常见形态:

适合做:解释当前脚本 / 补全函数 / 重构局部代码 / 修复语法错误 / 模仿现有风格写一段相似代码。

不适合做:没有上下文的大型分析决策 / 未确认就批量改整个项目 / 直接处理敏感临床数据。

2. Codex

Codex 是 OpenAI 的编码智能体,可以在终端、本地开发环境或相关产品界面中使用。适合读项目、改文件、运行命令、做代码审查和处理多文件任务。

codex

可以让它做:

梳理这个 Docusaurus 项目的目录结构,指出教程内容、静态资源和部署脚本分别在哪里。
检查 docs/single-cell/module02.md 里的 R 代码块,找出可能无法直接运行的地方,只给建议,不要修改文件。

使用建议:

3. Claude Code

Claude Code 是 Anthropic 的编码智能体,可以在终端、IDE、桌面应用和浏览器中使用。能读代码库、编辑文件、运行命令,并和开发工具集成。

claude

适合做:解释陌生代码库 / 根据报错追踪问题 / 编写测试 / 批量修复 lint 或格式 / 整理项目文档 / 通过 CLAUDE.md 固定项目规则。

在生信项目中,可以这么用:

阅读这个 R 脚本,解释每一步在单细胞分析流程中的作用,并指出哪些参数需要根据数据集调整。

4. opencode

opencode 是开源的 AI 编码智能体,主打终端工作流,也提供桌面和 IDE 形态。可以连接不同模型供应商,适合希望掌控工具栈和模型来源的开发者。

opencode

适合做:本地项目问答 / 生成修改计划 / 实施局部功能 / 维护项目级 AGENTS.md / 在多个模型之间切换。

特别注意:API key 千万不要写进仓库,不要提交 .env

5. Kiro

Kiro 是偏"规格驱动开发"的 AI IDE。先把需求、设计、任务拆清楚,再让智能体执行。相比纯 vibe coding,它更适合把原型推进到可维护项目。

核心概念:

适合做:从想法生成需求说明 / 把功能拆成可检查任务 / 生成实现计划和测试计划 / 维护中大型项目的一致性。

如果只是临时画一张图,Kiro 偏重;如果要长期维护一个网站、分析平台或工作流,它的规格驱动思路有价值。

6. API 中转站和模型聚合服务

很多用户会接触到"中转站"、"转发站"或"模型聚合服务"。它们提供统一 API,把请求转发到不同模型供应商。

优点:一个接口访问多个模型 / 支付和额度管理可能更方便 / 有些服务提供兼容 OpenAI 格式的接口。

风险:

建议:能用官方 API 或企业账号时优先用 / 不把真实患者数据、访问密钥、服务器密码交给不明中转服务 / 如必须使用中转,先做脱敏和小样本测试 / 在项目文档中记录模型、供应商、日期和关键参数。

生信分析中的安全边界

AI 工具擅长写代码,但不理解真实实验约束。下面这些事情必须由人来确认:

对涉及人类样本、临床数据、未公开项目的数据,先默认不能上传到外部 AI 服务。至少要做:

推荐工作流

学习阶段:把 AI 当解释器,不是代写器

用初学者能理解的方式解释这段 Seurat 代码。请逐行说明输入、输出和关键参数。
我不理解 NormalizeData、FindVariableFeatures、ScaleData 的区别。请结合单细胞表达矩阵解释。

分析阶段:AI 出草稿,保留人工审查

根据这个数据框结构,写一段 ggplot2 代码画不同细胞类型的基因表达小提琴图。请不要假设不存在的列名。
下面是报错信息和 sessionInfo。请判断最可能的原因,先给排查步骤,不要直接改代码。

项目维护阶段:让 AI 做重复劳动

检查 docs/basics 目录下的教程,找出标题层级不一致、图片路径可能错误、代码块语言未标注的问题。
为这个分析脚本生成 README,说明输入文件、输出文件、依赖包和运行命令。

提示词模板

解释代码

请解释下面这段代码。要求:
1. 说明每一步的目的
2. 标出输入和输出
3. 指出可能需要根据数据修改的参数
4. 不要重写代码,除非发现明确错误

生成分析脚本

请写一个可复现的 R 脚本完成以下任务:
- 输入:counts.csv 和 metadata.csv
- 输出:QC 图、标准化后的对象、marker 基因表
- 要求:固定随机种子,记录 sessionInfo,所有输出写入 results/
- 不要使用不存在的列名;如果需要列名,请先向我确认

审查结果

请作为代码审查者检查这段分析流程:
1. 是否有统计学问题
2. 是否有不可复现的步骤
3. 是否有硬编码路径
4. 是否遗漏中间结果保存
5. 是否需要补充图注或方法说明

常见坑

坑 1:AI 编出"看起来对"的列名

让 AI 写一段处理 metadata.csv 的代码,它经常猜列名("sample"、"group"、"condition"),生成看似可运行的代码,跑起来 Error in $: object 'group' not found

避免:把真实列名(或 head() 输出)一起喂给 AI,明确告诉它"不要假设不存在的列名"。

坑 2:AI "幻觉"出不存在的函数 / 包

特别在跨语言(R ↔ Python)翻译时,AI 会编出根本不存在的函数。代码看起来很对,跑起来 could not find function

避免:每次拿到 AI 写的代码,先把所有 library() / import 列出来核对一遍,再跑。

坑 3:把临床数据原文贴进对话

学生最常见的事故。"老师让我分析这份病人数据",复制粘贴整张表到 ChatGPT,姓名、住院号、确诊日期一并送出。

避免:在做任何分析前,先脱敏一份"开发用样例",所有 AI 交互只针对样例。真实数据只在本地分析。

坑 4:把 API key 写进代码,提交到 git

# 错误示范
client <- httr2::request("https://api.openai.com/v1/...") |>
  httr2::req_headers(Authorization = "Bearer sk-xxxxxxxxxxxx")

提交 git → 推到 GitHub → 公开 repo → key 被爬虫扫到 → 余额清零。

避免:所有 key 放 .env 或环境变量,.env 加进 .gitignore

坑 5:让 AI "一次性写完整套分析"

提示词:"写一个完整的单细胞 RNA-seq 分析脚本,包括 QC、标准化、聚类、注释、差异分析、富集"。AI 真的会给你 200 行代码,但每一步都用了它"觉得最常用"的参数 / 阈值 — 不一定适合你的数据

避免:拆成"按一步一步"。每一步:先让 AI 解释这一步在做什么,再让它写代码,再人工跑一下,看输出。然后才进下一步。

工具选择建议

场景 更适合的工具
解释一段代码 ChatGPT、Claude、IDE 助手
修改本地项目多个文件 Codex、Claude Code、opencode
快速原型 Codex、Claude Code、Cursor、Kiro
规范化长期项目 Kiro、Codex、Claude Code
多模型切换 opencode、模型聚合服务
敏感数据分析 本地部署的开源模型(Ollama 等)/ 企业合规服务 / 完全离线工具

下一步

接着深入(按推荐顺序):

  1. 编程基础:R / Python / Bash — 把 AI 帮你写的代码看懂、改对,前提是你自己会一点
  2. 数据与环境准备 — 先把环境装好,AI 写的代码才能在你机器上跑

横向延伸

参考资料

03 编程基础:R / Python / Bash

做组学数据分析,编程不是目标,而是工具。目标不是成为程序员,是能:

这一篇给出 BioF3 推荐的最小学习路径。

为什么必须学编程

组学数据有三个特点,让点鼠标的工作流彻底失效:

光靠点鼠标,下面这些问题答不出来:

编程的价值就是把分析过程写下来,让它可以检查、重复、修改、共享。

BioF3 推荐工具栈

R:单细胞分析和统计可视化主力

BioF3 的单细胞实践主要用 R 生态。先学 R 是最直接的路径。

常见场景:

最低要求:

Python:数据处理、机器学习和 Scanpy 生态

Python 适合处理大规模数据、机器学习、工程化流程。

常见场景:

最低要求:

Bash:服务器和生信流程的入口

很多生信工具只有命令行版本。不会 Bash,就用不稳服务器和高通量流程。

常见场景:

最低要求:

AI:助教 + 排错助手 + 草稿生成器

适合让 AI 做的:解释陌生代码 / 把报错翻译成排查步骤 / 生成脚本草稿 / 改写重复代码 / 生成 README / 检查路径和变量名。

不适合完全交给 AI 的:决定实验分组 / 决定统计检验 / 判断 marker gene / 解释疾病机制 / 处理未脱敏临床数据 / 编造软件版本和文献依据。

更完整的工具介绍和提示词模板见 AI 辅助编程与智能体工具

学习顺序

组学入门 的 4 阶段呼应,编程层面这样切:

第 1 阶段(搭配 overview 第 1 阶段):能跑、能改

新手最容易陷入"先系统学完整门语言"的误区。优先目标是能跑通别人写的脚本

能做到这几件事就够:

练习:

拿一份 BioF3 教程脚本,把输入文件路径改成自己的目录,
把输出目录改成 results/,跑一遍,确认产出在该出现的位置。

第 2 阶段(搭配 overview 第 2 阶段):R 入门到可用

先掌握基础数据结构:

# 向量
genes <- c("TP53", "BRCA1", "EGFR")
expr  <- c(5.2, 3.8, 7.1)

# 数据框
gene_data <- data.frame(gene = genes, expression = expr)

# 看一眼数据
head(gene_data)
str(gene_data)
summary(gene_data)

# 基础筛选
high_expr <- gene_data[gene_data$expression > 5, ]

再学 dplyr 风格:

library(dplyr)

gene_data <- gene_data %>%
  mutate(log_expression = log2(expression + 1)) %>%
  arrange(desc(expression))

最后 ggplot2:

library(ggplot2)

ggplot(gene_data, aes(x = gene, y = expression)) +
  geom_col(fill = "#3B82F6") +
  labs(x = "Gene", y = "Expression") +
  theme_classic()

R 阶段目标不是语法完美,是能读懂 Seurat 教程里的对象、函数、参数

第 3 阶段(搭配 overview 第 2-3 阶段):Python 入门到可用

Python 先从 pandas 开始:

import pandas as pd
import numpy as np

data = pd.DataFrame({
    "gene": ["TP53", "BRCA1", "EGFR"],
    "expression": [5.2, 3.8, 7.1],
})

data["log_expression"] = np.log2(data["expression"] + 1)
high_expr = data[data["expression"] > 5]
print(data["expression"].mean())

画图先掌握 matplotlib + seaborn:

import seaborn as sns
import matplotlib.pyplot as plt

sns.barplot(data=data, x="gene", y="expression", color="#3B82F6")
plt.xlabel("Gene")
plt.ylabel("Expression")
plt.tight_layout()
plt.show()

Python 阶段目标是能处理表格数据、看懂 Scanpy / AnnData 对象、能写小型自动化脚本。

第 4 阶段(搭配 overview 第 3-4 阶段):Bash 入门到可用

文件和目录:

pwd
ls -lh
mkdir -p results/qc
cp data/sample.csv results/

查看文件:

head expression.tsv
tail -n 20 run.log
wc -l expression.tsv
less run.log

批量处理:

mkdir -p qc_results

for file in data/*.fastq.gz; do
  echo "Processing $file"
  fastqc "$file" -o qc_results/
done

远程服务器:

ssh aliyun
scp results/report.html aliyun:/opt/project/results/

Bash 阶段目标是能在服务器上找到文件、运行工具、检查日志、批量处理样本

一个最小可复现项目结构

从第一个项目开始,就用固定结构组织文件:

project/
├── data/
│   ├── raw/          # 原始数据,永远不动
│   └── processed/    # 中间产物
├── scripts/
│   ├── 01_qc.R
│   ├── 02_normalize.R
│   └── 03_plot.R
├── results/
│   ├── figures/      # 图
│   └── tables/       # 表
├── logs/             # 运行日志
└── README.md         # 顺序、版本、参数

为什么这种结构值得:

常见坑

坑 1:报错只看最后一行

R / Python 报错通常很长,新手习惯只看最后一行的红字,结果定位不到真实问题。真实原因往往在 traceback 中段

避免:完整复制整段报错,从下往上读,找到第一个你自己代码的位置(不是 library 内部的)。

坑 2:路径写绝对路径,换机器就崩

read.csv("/Users/zhangsan/data/sample.csv") — 自己电脑能跑,发给同事就 file not found

避免:用相对路径 read.csv("data/sample.csv"),配合 setwd() 或 RStudio Project 固定项目根目录。

坑 3:包版本不固定,半年后跑不出来

Seurat v4 → v5 函数签名大改,跑不动同一个脚本。

避免:每个项目里跑 sessionInfo()pip freeze 把版本记进 README,关键时候用 renv(R)或 conda env(Python)锁版本。

坑 4:循环里改变量名重复了

for (i in 1:length(samples)) {
  i <- samples[i]   # i 既是循环变量又是值,下次循环就崩
  ...
}

避免:循环变量和值用不同名字。for (idx in seq_along(samples)) { sample <- samples[idx]; ... }

坑 5:把数据变量名跟函数名重叠

data <- read.csv("foo.csv")    # data 是 R 内置函数,被覆盖了
mean <- mean(data$expr)         # mean 也是函数,再覆盖

后面再调 data()mean() 就会困惑。

避免:用更具体的名字 — expr_dataexpr_meanpbmc_counts 等。

常见问题

没有基础,先学 R 还是 Python?

如果目标是尽快进入单细胞分析,先学 R。BioF3 单细胞主线工具用 R / Seurat。Python 可以等学到 Scanpy、机器学习、自动化时再补。

Bash 一定要学吗?

最基础的部分要学。不需要成为 Linux 专家,但要能在服务器上找到文件、运行命令、查看日志。否则很多上游流程(Cell Ranger、STAR)直接卡住。

可以全靠 AI 写代码吗?

不行。AI 可以写草稿,但必须人工确认输入数据、列名、统计方法、输出结果和生物学解释。涉及临床数据和未公开项目时,原始数据不要直接上传给外部 AI 服务。详见 AI 辅助编程与智能体工具 的"安全边界"和"5 个常见坑"。

报错时怎么处理?

按这个顺序:

  1. 完整复制报错(不只看最后一行)
  2. 确认对象是否存在、路径是否正确、包是否加载
  3. 用小数据集复现问题
  4. 搜索错误信息
  5. 让 AI 根据代码、报错、环境信息给排查步骤
  6. 修复后把原因记进 README 或 commit message

学到什么程度可以开始跑单细胞教程?

能做到这几件事就够:

下一步

接着深入(按推荐顺序读下去):

  1. 数据与环境准备 — 先把环境装好,避免每次跑教程脚本都报"找不到包"
  2. R 数据整理与 ggplot2 可视化 — R 阶段最值得先精通的两件事
  3. 单细胞实践 01:实践数据集与数据获取 — 用真实流程检验你学到的语法

横向延伸

编程能力不是背语法背出来的,是在真实任务里出来的。最快的开始方式:拿一张表,完成"读 → 筛 → 画 → 存"四件事。

04 Jupyter 与交互式分析环境

组学分析的第一个工程问题是:在哪里写下可以重复运行的分析过程?

Jupyter Notebook 是最常见的答案。它把代码、说明、图表和运行结果放在一份文档里,适合探索性分析和教学演示。

但 Notebook 不是万能的。这一篇把它的用法和边界都说清楚 — 哪些事 Notebook 该做、哪些事必须用脚本。

Notebook 是什么、不是什么

适合 Notebook 做的事

不适合 Notebook 做的事

核心判断:Notebook 是"探索 + 记录"载体,不是"执行 + 部署"载体。稳定下来的步骤应该整理到 .R / .py 脚本里。

四种常见环境

1. Jupyter Notebook(经典界面)

适合初学者起步。文件 .ipynb,内部保存代码单元、Markdown 文本、输出结果。

pip install notebook
jupyter notebook

2. JupyterLab(推荐)

更完整的工作界面:Notebook + 终端 + 文本编辑器 + 文件浏览器一体。真实项目里基本都用 JupyterLab

pip install jupyterlab
jupyter lab

3. Google Colab(云端,临时用)

打开浏览器就能跑 Python。免费用户也能用 GPU。

适合:快速试代码 / 课堂演示 / 共享小型 Notebook / 临时用 GPU 跑一下深度学习。

不适合:

4. 服务器 Notebook(真实项目首选)

数据在服务器上时,把 JupyterLab 起在服务器,浏览器通过 SSH 端口转发访问。

服务器端:

ssh aliyun
cd /path/to/project
conda activate sc-env
jupyter lab --no-browser --port 8888

本地终端:

ssh -L 8888:localhost:8888 aliyun
# 然后浏览器打开 http://localhost:8888

注意权限、数据路径、端口安全(不要把 8888 直接暴露公网)。

在 R 里也能用 Notebook

.ipynb 不只是 Python 的。装一个 IRkernel,就能在 Jupyter 里跑 R。

install.packages("IRkernel")
IRkernel::installspec()

之后启动 JupyterLab,新建 Notebook 时能选 R 内核。Seurat / DESeq2 / ggplot2 都能直接在里面跑,输出图也能内嵌。

备选:很多 R 用户直接用 RStudio + R Markdown / Quarto,效果跟 Notebook 类似。单纯做 R 分析不一定非要 Jupyter。Jupyter 的优势在 Python 重,或者多语言混合的项目。

Notebook 的基本结构

每个 Notebook 由一组**单元(cell)**组成,主要两种:

Markdown 单元 — 写说明

## 质量控制

本步骤过滤低质量细胞:

- `nFeature_RNA < 200`:基因数太少的可能是空 droplet
- `percent.mt > 20`:线粒体比例高的可能是死细胞或破损

Code 单元 — 跑代码

import pandas as pd

metadata = pd.read_csv("data/metadata.csv")
metadata.head()

输出(表 / 图 / 错误信息)会显示在单元下方,并保存进 .ipynb 文件。

把环境记下来

每个 Notebook 跑完都建议在最后加一个版本记录单元:

Python:

import sys, pandas as pd, numpy as np
print(sys.version)
print(pd.__version__, np.__version__)

R:

sessionInfo()

这一段救过无数"半年前的我跑得动,现在跑不出来"的事故。

从 Notebook 走向脚本

Notebook 的价值不是"把所有分析塞在一个文件里"。稳定下来的部分应该走出 Notebook

判断"该不该走"的几条原则:

推荐结构:

project/
├── notebooks/        # 探索性 + 教学 Notebook
├── scripts/          # 稳定可复现脚本
├── data/
└── results/

常见坑

坑 1:Notebook 里的代码跑顺序乱了

Notebook 允许任意顺序运行单元,变量状态不一定跟你看到的顺序一致。新手常常跑出"看着都跑过但结果不对"的玄学情况。

避免:定期点 "Restart Kernel & Run All",确保从头到尾顺次跑下来还是同样结果。这是 Notebook 可复现性的核心保证。

坑 2:把 .ipynb 提交进 git,diff 一片乱码

.ipynb 是 JSON 格式,包含 base64 编码的图片输出。每次重跑都生成不同 metadata,git diff 完全不可读。

避免

坑 3:把临床数据载进 Notebook,输出嵌进文件,提交 git

直接违规。患者数据原文进了 Notebook 输出,再随手 git push,敏感信息泄漏到公开仓库。

避免:临床 / 未脱敏数据永远不在 Notebook 里直接展示原文。脱敏到样例数据,分析跑在样例上;真实数据只在合规环境处理,输出不嵌进 .ipynb

坑 4:依赖 Notebook 里 !pip install,环境没固定

调试时图省事,在 Notebook 里 !pip install scanpy 装包。当时能跑,几个月后版本不一致跑不出。

避免:用项目级环境(environment.yml / requirements.txt / renv.lock),Notebook 只 import,不在里面装包。

坑 5:Notebook 越写越长,最后跑一次要 30 分钟

探索性分析很容易越写越长,跑一次几十分钟,每改一处都要全跑。

避免:定期把"这一段已经稳了"的部分搬到 scripts/,Notebook 只保留当前在调的部分。或者把中间产物 pickle / saveRDS 存到磁盘,下次直接加载。

下一步

接着深入

  1. 数据与环境准备 — 在 Notebook 里 import seurat 之前,先把环境搭好
  2. R 数据整理与 ggplot2 可视化 — Notebook 里画图的能力直接决定它有多好用
  3. 单细胞实践 01 — 第一个完整可跑的真实流程,是 Notebook 还是脚本看自己习惯

横向延伸

参考资源

05 公共数据库与数据检索

组学分析常常不从自己测序开始,而是先用公开数据练手 / 验证假设 / 做对照。

这一篇回答两个问题:

  1. 从哪里找数据 — 主流公开库有哪些、各自擅长什么
  2. 怎么判断数据合不合适 — 不是任何编号能下到的数据都能用

先看你需要什么类型的数据

不同数据库的产出形态完全不同:

你需要 优先看哪里
找某篇论文的配套表达矩阵 GEO
下载原始 FASTQ SRA / ENA
浏览已注释的单细胞数据 CELLxGENE
找人类细胞参考图谱 HCA Data Portal
查某个基因在哪些组织表达 Expression Atlas
找癌症基因组 + 临床数据 TCGA / GDC
找表观调控(peak / motif)数据 ENCODE
找人类群体遗传变异 1000 Genomes / gnomAD

下文每一个都有最低限度介绍。先确定需求、再选库。"先去 GEO 搜搜"是浪费时间的常见做法。

常见 accession 编号

公开数据通过 accession 编号追踪。每个库有自己的编号体系:

编号 含义 示例
GSE GEO Series,一个研究 GSE12345
GSM GEO Sample,一个样本 GSM123456
GPL GEO Platform,测序平台 GPL16791
SRP SRA Study SRP123456
SRX SRA Experiment SRX123456
SRR SRA Run,真正能下载 reads 的层级 SRR1234567
ERP / ERX / ERR ENA 对应 SRA ERR1234567
TCGA-XX-XXXX TCGA case barcode TCGA-A1-A0SK
ENCSR ENCODE Series ENCSR000AAA

最常见的坑:拿到 GSE 直接找 FASTQ 下不到。FASTQ 在 SRR 层级,需要顺着 GSE → GSM → SRX → SRR 追。

主要数据库

GEO(Gene Expression Omnibus)

NCBI 维护,覆盖功能基因组学最广。论文发表时强制要求把数据上传 GEO,所以"找论文配套数据"几乎必经此处。

检索关键词模板

关键词 + 物种 + 技术 + 组织/疾病

例:

single cell RNA-seq human liver fibrosis
PBMC scRNA-seq healthy donor

SRA / ENA(原始测序数据)

需要 FASTQ 时基本都到这两家。NCBI 的 SRA 和 EBI 的 ENA 内容是镜像的,下载时哪个快用哪个。

下载工具:

# SRA Toolkit(NCBI 官方)
conda install -c bioconda sra-tools

prefetch SRR1234567
fasterq-dump SRR1234567 --split-files -O data/raw/

# 或 ENA 的 ascp / aria2 直接拉 .fastq.gz

注意:

CELLxGENE Discover(单细胞已注释)

CZI(Chan Zuckerberg Initiative)维护,专注单细胞数据的可视化浏览。

适合:

Human Cell Atlas(HCA Data Portal)

国际合作的人类细胞图谱项目,目标是给所有人体组织 / 器官生成参考图谱。

适合:

Expression Atlas / Single Cell Expression Atlas

EMBL-EBI 的基因表达查询库。适合"查一个基因",不适合"下大数据集"

适合:

TCGA / GDC(癌症基因组图谱)

NCI 主导的癌症大队列。包含 33 种癌症约 11000 个样本的基因组、转录组、甲基化、临床信息。

适合:

注意 dbGaP 限制 — 部分数据需要授权。

ENCODE(表观调控元件百科全书)

DOE / NIH 主导,主要提供 ChIP-seq / ATAC-seq / DNase-seq / RNA-seq 等 functional 数据。

适合:

1000 Genomes / gnomAD(人类变异)

群体遗传 / GWAS / 临床变异解读绕不开的两个库。

适合:

怎么判断一个数据集合不合适

下载前先用这份清单过一遍,比下完发现不能用强:

1. 物种和参考版本

2. 实验设计

3. 测序深度和数据规模

4. 元数据完整度

5. 数据是原始还是处理过的

6. License 和使用限制

常见坑

坑 1:拿到 GSE 直接找 FASTQ

GSE 层级常常没有直接的 FASTQ 链接。需要顺着 GSE → GSM → SRX → SRR 找到 run 层级才能下。

避免:在 GEO 页面找 "SRA" 链接,跳到 SRA Run Selector,下载所有 SRR 列表,再批量下。

坑 2:把原始 reads 当成 counts 用

有些教程把 GEO 上的 *_counts.txt.gz 当作可直接喂 DESeq2 的输入。但 GEO 上传的"counts"可能是:raw counts / TPM / RPKM / 已 batch correct / 已 quantile normalize。

避免:每个数据集先看 README 和原始论文,确认是什么形态。DESeq2 要 raw integer counts,不是 TPM。

坑 3:参考基因组版本不一致

下了 GSE 的 BAM 文件,发现是 hg19 比对的;自己的新数据是 hg38。坐标对不上,下游 region 注释全错。

避免:下载前看清版本。需要时用 liftOver 转换,或重新比对原 FASTQ 到一致版本。

坑 4:元数据匹配不上

GEO 元数据里的样本顺序和表达矩阵列名顺序不一致。直接合并会把 sample A 的处理标签贴到 sample B 上。

避免:每次合并元数据和表达矩阵前,显式 join by sample ID,不要依赖默认顺序。

坑 5:忽略数据上传日期

2014 年的 PBMC 单细胞数据用的是 SMART-seq2,跟现在的 10x Chromium 不能直接比。十年前的 ChIP-seq 没有 input control 是常见情况。

避免:注意数据生成年份和当时的技术状态。老数据值得参考但不一定能直接整合。

AI 辅助检索

让 AI 帮你做:解析复杂检索结果 / 把 GSE 元数据整理成表 / 写下载脚本草稿。

不让 AI 做:判断数据集质量 / 决定研究问题 / 替你看论文摘要里的实验细节。

详见 AI 辅助编程与智能体工具

下一步

接着深入

  1. 数据与环境准备 — 下载下来的数据放哪、用什么环境跑
  2. 单细胞实践 01:实践数据集与数据获取 — 第一个真实流程,配套用 PBMC 3k 公开数据

横向延伸

参考资源

速答

Q: 生信分析必须学 R 吗? A: 不是必须,但强烈推荐。Seurat(单细胞)、DESeq2(差异分析)、clusterProfiler(富集)等核心包都是 R 生态。Python 有 Scanpy 等替代,但 R 在统计可视化和 Bioconductor 生态上仍占优。

Q: ggplot2 的图层语法核心是什么? A: data + aesthetic + geometry 三件套。数据映射到美学属性(x/y/color),再叠加几何图层(点/线/柱)。图层之间用 + 连接,可以无限叠加。

Q: dplyr 最常用的 5 个函数? A: filter()(筛选行)、select()(选列)、mutate()(新增列)、group_by() + summarize()(分组汇总)、arrange()(排序)。覆盖 90% 日常数据整理需求。

06 R 数据整理与 ggplot2 可视化

R 在组学分析中最常用的场景有两个:整理表格数据,画出能解释结果的图。对 BioF3 来说,本章不是追求完整覆盖 R 语言,而是让你掌握最常用、最容易迁移到真实项目的能力。

本章所有图表都来自公开数据集 10x Genomics PBMC 3k。它包含一名健康供体外周血单个核细胞的真实单细胞 RNA-seq 表达矩阵。

R 在 BioF3 中承担什么角色

R 不是唯一选择,但它在生信里非常重要:

学习 R 的重点不是背语法,而是知道数据对象长什么样、函数需要什么输入、结果如何保存。

准备真实 PBMC 3k 数据

先读取真实表达矩阵。完整脚本会自动下载数据;这里保留核心逻辑,方便你理解后续对象从哪里来。

library(Matrix)
library(dplyr)
library(tidyr)
library(ggplot2)
library(scales)

data_dir <- file.path(path.expand("~"), "biof3-data", "pbmc3k")
matrix_dir <- file.path(data_dir, "filtered_gene_bc_matrices", "hg19")

pbmc_url <- paste0(
  "https://cf.10xgenomics.com/samples/cell-exp/1.1.0/pbmc3k/",
  "pbmc3k_filtered_gene_bc_matrices.tar.gz"
)
pbmc_tar <- file.path(data_dir, "pbmc3k_filtered_gene_bc_matrices.tar.gz")

dir.create(data_dir, recursive = TRUE, showWarnings = FALSE)

if (!file.exists(pbmc_tar)) {
  download.file(pbmc_url, destfile = pbmc_tar, mode = "wb")
}

if (!file.exists(file.path(matrix_dir, "matrix.mtx"))) {
  untar(pbmc_tar, exdir = data_dir)
}

counts <- readMM(file.path(matrix_dir, "matrix.mtx"))
genes <- read.delim(file.path(matrix_dir, "genes.tsv"), header = FALSE)
barcodes <- read.delim(file.path(matrix_dir, "barcodes.tsv"), header = FALSE)

rownames(counts) <- make.unique(genes[[2]])
colnames(counts) <- barcodes[[1]]
counts <- as(counts, "CsparseMatrix")

把矩阵整理成几张常用表:

mt_genes <- grepl("^MT-", rownames(counts))

qc <- data.frame(
  cell = colnames(counts),
  nCount_RNA = as.numeric(colSums(counts)),
  nFeature_RNA = as.numeric(colSums(counts > 0)),
  percent_mt = as.numeric(colSums(counts[mt_genes, , drop = FALSE]) / colSums(counts) * 100)
)

gene_summary <- data.frame(
  gene = rownames(counts),
  total_counts = as.numeric(rowSums(counts)),
  detected_cells = as.numeric(rowSums(counts > 0))
) %>%
  mutate(mean_counts = total_counts / ncol(counts))

marker_genes <- c("IL7R", "CCR7", "S100A8", "S100A9", "MS4A1", "CD79A", "NKG7", "GNLY", "PPBP")
marker_genes <- marker_genes[marker_genes %in% rownames(counts)]

marker_long <- bind_rows(lapply(marker_genes, function(gene) {
  data.frame(
    cell = colnames(counts),
    gene = gene,
    counts = as.numeric(counts[gene, ]),
    log_counts = log1p(as.numeric(counts[gene, ]))
  )
}))

这几张表分别回答不同问题:

最小 R 基础

向量

向量是 R 中最基础的数据结构。这里的基因名来自 PBMC 3k 矩阵中真实存在的 marker 基因。

genes <- marker_genes[1:4]
expression <- gene_summary$total_counts[match(genes, gene_summary$gene)]

genes[1]
expression > median(expression)
mean(expression)

数据框

数据框类似表格,是生信分析中最常见的数据形态。

gene_data <- gene_summary %>%
  filter(gene %in% marker_genes) %>%
  select(gene, total_counts, detected_cells, mean_counts)

head(gene_data)
str(gene_data)
summary(gene_data)

访问列:

gene_data$gene
gene_data[["total_counts"]]

筛选行:

high_detection <- gene_data[gene_data$detected_cells > 100, ]

列表

很多 R 包会把复杂结果放在列表里。Seurat 对象、差异分析结果和富集分析结果都可能包含多层信息。

analysis_result <- list(
  counts = counts,
  qc = qc,
  marker_expression = marker_long
)

analysis_result$qc

dplyr:表格整理的基本动作

先加载包:

library(dplyr)

用真实基因汇总表练习筛选、排序和新增列:

top_genes <- gene_summary %>%
  filter(!grepl("^MT-|^RPL|^RPS", gene)) %>%
  filter(detected_cells > 50) %>%
  arrange(desc(total_counts)) %>%
  mutate(
    log_total_counts = log10(total_counts + 1),
    detection_rate = detected_cells / ncol(counts)
  ) %>%
  slice_head(n = 10)

分组汇总可以用在 marker 基因上。例如按基因统计非零表达细胞比例:

marker_summary <- marker_long %>%
  group_by(gene) %>%
  summarise(
    mean_log_counts = mean(log_counts),
    expressing_cells = sum(counts > 0),
    expressing_rate = expressing_cells / n(),
    .groups = "drop"
  ) %>%
  arrange(desc(expressing_rate))

在真实项目中,大部分绘图问题都先是数据整理问题。图画不好,常常不是 ggplot2 不会用,而是表格没有整理成合适的长格式。

ggplot2 的核心思想

ggplot2 使用"图形语法"。你可以把一张图理解成几层:

最小示例:

ggplot(top_genes, aes(x = reorder(gene, total_counts), y = total_counts)) +
  geom_col(fill = "#0f766e") +
  coord_flip() +
  scale_y_continuous(labels = comma) +
  labs(x = NULL, y = "Total UMI counts") +
  theme_classic()

Bar plot - PBMC 3k top expressed genes

图 1:柱状图展示 PBMC 3k 中总 UMI 数最高的一组真实基因。这里过滤了线粒体和核糖体基因,避免它们占据整个图。

生信常用图表

散点图:看两个变量的关系

ggplot(qc, aes(x = nCount_RNA, y = nFeature_RNA, color = percent_mt)) +
  geom_point(alpha = 0.7, size = 1.2) +
  scale_x_continuous(labels = comma) +
  scale_y_continuous(labels = comma) +
  scale_color_gradient(low = "#0f766e", high = "#dc2626") +
  labs(
    x = "Total UMI counts",
    y = "Detected genes",
    color = "Mitochondrial %"
  ) +
  theme_classic()

Scatter plot - PBMC 3k QC relationship

图 2:每个点是一个真实细胞条形码。散点图适合观察总 UMI 数、检测基因数和线粒体比例之间的关系。

箱线图:比较分组分布

box_data <- marker_long %>%
  filter(gene %in% marker_genes[1:4])

ggplot(box_data, aes(x = gene, y = log_counts, fill = gene)) +
  geom_boxplot(width = 0.6, outlier.shape = NA, alpha = 0.82) +
  labs(x = NULL, y = "log1p(UMI counts)") +
  theme_classic() +
  theme(legend.position = "none")

Box plot - PBMC 3k marker genes

图 3:箱线图展示真实 PBMC marker 基因在全部细胞中的表达分布。单细胞数据里零值很多,所以图注必须说明归一化或转换方式。

直方图:看整体分布

ggplot(qc, aes(x = nCount_RNA)) +
  geom_histogram(bins = 55, fill = "#2563eb", color = "white") +
  geom_vline(xintercept = median(qc$nCount_RNA), linetype = "dashed", color = "#f59e0b") +
  scale_x_continuous(labels = comma) +
  labs(x = "Total UMI counts per cell", y = "Number of cells") +
  theme_classic()

Histogram - PBMC 3k count distribution

图 4:直方图适合观察真实测序计数、基因表达、QC 指标等连续变量的分布。

小提琴图:看分布形状

ggplot(box_data, aes(x = gene, y = log_counts, fill = gene)) +
  geom_violin(trim = FALSE, alpha = 0.72) +
  geom_boxplot(width = 0.12, fill = "white", outlier.shape = NA) +
  labs(x = NULL, y = "log1p(UMI counts)") +
  theme_classic() +
  theme(legend.position = "none")

Violin plot - PBMC 3k marker distributions

图 5:小提琴图适合展示大量细胞的分布形状。单细胞表达图常用小提琴图,但要注意零值、归一化方式和细胞类型混合带来的解释边界。

分面图:同时比较多个基因或分组

facet_data <- marker_long %>%
  filter(gene %in% marker_genes[1:6])

ggplot(facet_data, aes(x = log_counts)) +
  geom_histogram(bins = 35, fill = "#0f766e", color = "white") +
  facet_wrap(~ gene, scales = "free_y", ncol = 3) +
  labs(x = "log1p(UMI counts)", y = "Cells") +
  theme_bw()

Facet plot - PBMC 3k marker distributions

图 6:分面图适合在同一套样式下比较多个真实基因。这里每个小面板都是一个 marker 基因在 PBMC 3k 细胞中的表达分布。

一个小型表达分析流程

下面用 PBMC 3k 的真实 marker 基因演示从矩阵到长表、再到可视化的完整流程。

marker_expression <- counts[marker_genes, , drop = FALSE]

gene_long <- as.data.frame(as.matrix(marker_expression)) %>%
  tibble::rownames_to_column("gene") %>%
  pivot_longer(
    cols = -gene,
    names_to = "cell",
    values_to = "counts"
  ) %>%
  mutate(log_counts = log1p(counts))

可视化表达分布:

ggplot(gene_long, aes(x = gene, y = log_counts, fill = gene)) +
  geom_violin(trim = FALSE, alpha = 0.72) +
  geom_boxplot(width = 0.1, fill = "white", outlier.shape = NA) +
  labs(x = NULL, y = "log1p(UMI counts)") +
  theme_classic() +
  theme(
    legend.position = "none",
    axis.text.x = element_text(angle = 30, hjust = 1)
  )

Expression distribution

图 7:表达量分布图可以快速检查不同 marker 基因的稀疏性和表达范围。它不是差异分析结果,不能直接推断细胞类型比例或显著性。

基因检出、丰度和热图

火山图通常需要两类信息:

PBMC 3k 这一章还没有建立分组差异分析模型,所以这里不画"正式火山图"。如果没有真实分组、真实 log2FC 和校正后的 p 值,就不要把图包装成火山图。我们改用真实基因层面的检出细胞数和总 UMI 数,观察哪些 marker 基因在矩阵中更常被检测到。

gene_detection <- gene_summary %>%
  filter(detected_cells > 0) %>%
  mutate(marker = if_else(gene %in% marker_genes, "Marker gene", "Other gene"))

ggplot(gene_detection, aes(x = detected_cells, y = total_counts, color = marker)) +
  geom_point(alpha = 0.45, size = 1) +
  scale_x_log10(labels = comma) +
  scale_y_log10(labels = comma) +
  labs(
    x = "Cells with detected expression",
    y = "Total UMI counts",
    color = NULL
  ) +
  theme_classic()

Gene detection and abundance

图 8:这不是火山图,而是 PBMC 3k 真实基因的"检出细胞数 vs 总 UMI 数"散点图。它保留了原文件名以兼容网站旧链接。

热图适合展示一组基因在多个样本或细胞中的模式。常见注意点:

Gene expression heatmap

图 9:热图展示 PBMC 3k marker 基因在一组真实细胞中的表达模式。热图适合展示模式,而不是替代统计检验。

保存图片

建议所有图都显式保存,避免只留在 Notebook 或 RStudio 窗口里。

ggsave(
  filename = "results/figures/pbmc3k_marker_distribution.png",
  width = 7,
  height = 5,
  dpi = 300
)

保存前确认:

AI 辅助改图

AI 可以帮你把"能画出来的图"改成"更清楚的图":检查坐标轴、图例、颜色和图注,或者把宽表改成适合 ggplot2 的长表。具体提示词和安全边界详见 AI 辅助编程与智能体工具

但下面这些事情必须自己判断:

常见坑

坑 1:宽表直接喂 ggplot

新手最常见的报错。手里一份"基因 × 样本"宽表,想画图直接 ggplot(data, aes(...)),发现 ggplot 不认。

避免:ggplot2 要长表(long format),用 tidyr::pivot_longer() 把宽表转成长表再画。

wide <- data.frame(gene = c("A","B"), s1 = 5, s2 = 10)
long <- tidyr::pivot_longer(wide, cols = -gene,
                            names_to = "sample", values_to = "expr")

坑 2:对数轴上展示包含 0 的数据

UMI counts 包含大量 0,直接 scale_y_log10() 会把 0 的样本静默扔掉。看图以为没 0 值,其实是被 ggplot 滤掉了。

避免:先做 log1p()(log(x+1))转换再画,或显式把 0 替换成一个小值并加图注说明。

坑 3:颜色映射用了连续变量但其实是分类

把"分组"列存成数字(1, 2, 3)而不是 factor,ggplot 会用渐变色画,逻辑混乱。

避免:分类变量明确转 factor — data$group <- factor(data$group)

坑 4:图保存出来文字模糊

直接 ggsave("plot.png") 默认 dpi=300 但宽高没指定,画出来字小到看不清。

避免:每次保存都明确 width = 7, height = 5, dpi = 300,论文用图至少 600 dpi。

坑 5:用 RColorBrewer 时类别超过调色板上限

scale_color_brewer(palette = "Set1") 最多 9 色,画 12 个细胞类型就报 warning,部分类别会变灰。

避免:超过 9 类时用 scale_color_manual() + 自己定义颜色,或用 ggsci / viridis 包的扩展调色板。

下载资源

module02_complete_sci.R
17 KB
下载图表生成脚本

下一步

基础入门到这里告一段落 — 接下来是用真实流程练习。

接着深入

  1. 单细胞实践 01:实践数据集与数据获取 — 把本篇练的 R + ggplot2 用在真实单细胞数据获取流程上
  2. 单细胞实践 03:质量控制、聚类与细胞类型注释 — 第一个完整的 scRNA-seq 分析,全程用 R
  3. bulk RNA-seq overview — 想做转录组而不是单细胞的话从这里进

横向延伸

参考资源

07 数据与环境准备

BioF3 的每一章都配有可直接运行的 R 脚本。这一篇统一说明:每个脚本要什么数据、数据放在哪、怎么一次性装好所需的 R 包。

数据目录约定

所有脚本默认去同一个数据根目录里找数据,避免每个项目再重新下载:

~/biof3-data/
├── pbmc3k/              # 单细胞 module01~07 用
├── pbmc5k-citeseq/      # 单细胞 module07(CITE-seq 真实示例)用
└── pbmc10k-scatac/      # 单细胞 module10(scATAC-seq 真实示例)用

脚本里读这个路径的方式:

data_root <- Sys.getenv("BIOF3_DATA_DIR",
                        file.path(path.expand("~"), "biof3-data"))
pbmc_dir  <- file.path(data_root, "pbmc3k")

怎么换位置

# 临时:当次运行覆盖
BIOF3_DATA_DIR=/mnt/shared/biof3-data Rscript scripts/single-cell/sc03_qc_cluster_sci.R

# 长期:写进 shell 配置
echo 'export BIOF3_DATA_DIR=/mnt/shared/biof3-data' >> ~/.zshrc

数据清单

需要下载的数据

这三份数据由 10x Genomics 提供,前两份可以在笔记本上跑,scATAC 数据大一点、磁盘占用需要留意:

数据集 用在哪 体积 说明
PBMC 3k 单细胞 01 ~ 0706 配套脚本07 配套脚本 ~35 MB 10x Genomics 第一代示例,贯穿 scRNA-seq 主线
PBMC 5k CITE-seq 单细胞 07 CITE-seq 真实示例 ~75 MB RNA + 32 个抗体的 TotalSeq-B panel
PBMC 10k scATAC v2 单细胞 10 scATAC-seq 真实示例 ~200 MB peak matrix + singlecell.csv(不含 fragments)

脚本会在首次运行时自动下载,之后缓存。如果想先一次性把三份都下好、之后离线跑,用下面的一键准备脚本。

用 Bioconductor 内置数据的模块

下面这些模块不需要手工下载任何数据,装好对应的 Bioconductor 包就能跑:

模块 用的数据包
单细胞 08 TCR/BCR scRepertoire(自带 contig_listscRep_example
单细胞 09 空间转录组 SeuratData::stxBrain(首次 InstallData 一次,本地缓存)
bulk 02 DESeq2 / 03 富集 / 04 可视化 / 07 多工具对比 airway
bulk 05 LRT 时间序列 fission
bulk 06 批次效应 bladderbatch + airway

一键准备脚本

配套脚本 biof3_prepare_data.R 一次性完成:

  1. 检查 R 版本(推荐 R ≥ 4.3)
  2. 从 CRAN + Bioconductor 装所有脚本用到的 R 包
  3. 下载 PBMC 3k / 5k / 10k 三份数据到 ~/biof3-data/
  4. 加载 SeuratData 的 stxBrain(空间转录组)
Rscript scripts/biof3_prepare_data.R

默认会把数据放在 ~/biof3-data/。换目录:

BIOF3_DATA_DIR=/mnt/shared/biof3-data Rscript scripts/biof3_prepare_data.R

脚本里每一步都是幂等的:装过的包、下过的数据不会重复下载。

biof3_prepare_data.R
12 KB
下载一键准备脚本

R 包清单

按脚本粗分:

单细胞主线(module01~07)SeuratSeuratObjectMatrixggplot2dplyrpatchworkRColorBrewer

单细胞专题

bulk RNA-seqDESeq2edgeRlimmaairwayfissionbladderbatchsvaclusterProfilerorg.Hs.eg.dbenrichplotDOSEggrepelpheatmapEnhancedVolcanoapeglm

biof3_prepare_data.R 会把这些全部装好。如果只跑某几章,按需装对应包即可。

国内网络的注意事项

几个国内环境下常见的坑,解决办法:

1. Bioconductor 主站直连有时慢

BiocManager::install() 默认用 Bioconductor 官方源。如果下载很慢,临时手动指定镜像:

options(
  repos = c(
    BioCsoft = "https://bioconductor.org/packages/3.22/bioc",
    BioCann  = "https://bioconductor.org/packages/3.22/data/annotation",
    BioCexp  = "https://bioconductor.org/packages/3.22/data/experiment",
    CRAN     = "https://mirrors.tuna.tsinghua.edu.cn/CRAN"
  ),
  timeout = 600
)
install.packages("DESeq2")

上面这段写死了 BioC 版本(3.22 对应 R 4.5),也是 biof3_prepare_data.R 内置的 fallback。装完之后回到默认 BiocManager 继续用。

2. CellChat 不在 CRAN / BioC

GitHub 直接装:

# CRAN 上装依赖
install.packages(c("sna", "ggnetwork", "collapse"))

# GitHub 装 CellChat
if (!requireNamespace("devtools", quietly = TRUE)) install.packages("devtools")
devtools::install_github("jinworks/CellChat")

如果 devtools::install_github 连不上,从 https://codeload.github.com/jinworks/CellChat/tar.gz/HEAD 下 tarball 手动 R CMD INSTALL 也可以。

3. SeuratData 和 msigdbr 的数据服务器在海外

目录结构总览

把上面这些合起来,一个完整的学习环境长这样:

~/biof3-data/                     # 数据(脚本共用)
├── pbmc3k/
├── pbmc5k-citeseq/
└── pbmc10k-scatac/

~/BioF3/                          # 代码(git clone 或者直接下脚本)
├── scripts/
│   ├── biof3_prepare_data.R
│   ├── single-cell/
│   │   ├── sc01_data_sci.R
│   │   └── ...
│   ├── bulk-rnaseq/
│   │   ├── bulk02_deseq2_sci.R
│   │   └── ...
└── static/scripts/               # 和 scripts/ 内容一致,供下载使用

~/R/x86_64-apple-darwin20/4.3/    # R 包库(自动管理)
├── Seurat/
├── DESeq2/
└── ...

数据根目录和代码根目录完全分开,数据集换机器 / 换项目都能共享。

常见问题

Q:脚本一直在下载同一份数据

A:检查 ~/biof3-data/ 目录是否存在。脚本会用 file.exists() 检测是否已下载;如果你换了路径、删了缓存,它就会重新下。

Q:磁盘不够,能不能把数据放在外置硬盘

A:可以,把外置硬盘路径写进 BIOF3_DATA_DIR 即可,脚本会跟着去找。

Q:装一个包失败,整个脚本断了

A:biof3_prepare_data.R 每装一个包都用 tryCatch 包着,失败会打印 warning 但不会中断。装完最后会报告哪些包失败。

下一步

环境装好之后,直接进真实流程:

接着深入

  1. 单细胞实践 01:实践数据集与数据获取 — 用刚下好的 PBMC 3k 走第一个 scRNA-seq 流程
  2. bulk RNA-seq overview — 想做转录组的话从这里进,airway 数据已经装好
  3. 单细胞实践 03:质量控制、聚类与细胞类型注释 — 第一个完整的 scRNA-seq 分析

横向延伸

参考资源