跳转至

生信项目管理与文档规范

一句话说明:好的项目管理让你的分析结果可复现、可交接、可追溯——半年后换个人也能从该项目目录里完整重跑出一样的结果。


一、为什么项目管理对生信工程师重要

生信工程师和纯开发不同,你的"产品"不是一个 App,而是分析结果和结论。如果别人(包括半年后的自己)拿到该项目目录:

  • 不知道哪个脚本对应哪一步分析
  • 不知道用的什么软件版本
  • 不知道原始数据从哪来的
  • 不知道参数为什么这么设
  • 重跑一遍结果不一样

那你的分析就是不可复现的,在学术上这是严重问题,在工业界这意味着无法通过质量审计。

白话说:项目管理 = 让你的分析经得起检验。面试官问"你怎么保证分析的可重复性",这一章就是标准答案。


二、项目目录结构规范

一个规范的生信项目目录应该一看就知道每个文件夹放什么:

project_name/                 # 项目根目录(用有意义的名字,如 t2d_metagenome)
├── README.md                # 项目说明书(最重要的文件!)
├── CHANGELOG.md             # 版本变更记录
├── LICENSE                  # 开源许可证(如果要公开)
├── data/                    # 数据目录
│   ├── raw/                 # 原始数据(只读!绝对不能修改原始数据)
│   │   ├── sample1_R1.fastq.gz
│   │   └── sample_metadata.tsv
│   ├── processed/           # 中间处理结果
│   │   ├── clean_reads/
│   │   └── assemblies/
│   ├── reference/           # 参考数据库(或用软链接指向公共数据库)
│   │   └── silva_138/ -> /db/silva_138/
│   └── external/            # 外部数据(文献中下载的、合作方提供的)
├── scripts/                 # 分析脚本
│   ├── 01_qc.sh            # 按步骤编号,一看就知道顺序
│   ├── 02_assembly.sh
│   ├── 03_binning.sh
│   ├── 04_taxonomy.sh
│   ├── 05_statistics.R
│   └── utils/               # 工具函数、辅助脚本
│       └── common.sh
├── results/                 # 最终结果(图表、表格、报告)
│   ├── figures/             # 发表级图片
│   │   ├── fig1_diversity.pdf
│   │   └── fig2_heatmap.pdf
│   ├── tables/              # 结果表格
│   │   └── diff_abundance.tsv
│   └── reports/             # 分析报告
│       └── analysis_report.html
├── docs/                    # 文档
│   ├── methods.md           # 方法描述(论文 Methods 节草稿)
│   ├── notebook.md          # 分析日志/实验记录
│   └── references/          # 参考文献
├── envs/                    # 环境配置
│   ├── environment.yml      # conda 环境文件
│   ├── requirements.txt     # Python 依赖(如果用 pip)
│   └── Dockerfile           # 容器化配置(可选)
├── config/                  # 配置文件
│   ├── params.yaml          # 分析参数(集中管理)
│   └── sample_list.tsv      # 样本信息表
├── logs/                    # 运行日志
│   ├── 01_qc.log
│   └── 02_assembly.log
├── Makefile                 # 流程管理(或 Snakefile/nextflow.config)
└── .gitignore               # Git 忽略规则

关键原则

原则说明
原始数据只读data/raw/ 里的文件绝对不修改,设成只读权限 chmod 444
脚本编号01_02_ 前缀标明执行顺序
结果与过程分离results/ 放最终结果,data/processed/ 放中间文件
环境可复现envs/ 下有完整的环境配置文件
配置集中参数不硬编码在脚本里,统一放 config/

.gitignore 模板

# 大文件不入库
data/raw/
data/processed/
*.fastq.gz
*.bam
*.sam
*.fasta

# 日志
logs/

# 系统文件
.DS_Store
__pycache__/
*.pyc

# 编辑器临时文件
*.swp
*~
.vscode/

三、README 怎么写

README.md 是项目的"门面",别人打开该项目第一个看的就是它。

模板

# T2D 肠道菌群宏基因组分析

## 项目简介
基于 2 型糖尿病(T2D)患者与健康对照的肠道宏基因组数据,
分析菌群组成差异、功能通路富集和潜在生物标志物。

## 数据来源
- 原始数据:NCBI SRA PRJNA123456(30 例 T2D + 30 例对照)
- 参考数据库:SILVA 138.1, KEGG 2025-01

## 环境配置
```bash
conda env create -f envs/environment.yml
conda activate t2d_meta

分析流程

  1. 质控:bash scripts/01_qc.sh(fastp v1.3.3)
  2. 组装:bash scripts/02_assembly.sh(MEGAHIT v1.2.9)
  3. 分箱:bash scripts/03_binning.sh(MetaBAT2 v2.15)
  4. 物种注释:bash scripts/04_taxonomy.sh(GTDB-Tk v2.3)
  5. 统计分析:Rscript scripts/05_statistics.R

或者一键运行:make all

目录结构

(见上方结构图)

结果概要

  • 发现 12 个在 T2D 组显著富集的 MAGs
  • KEGG 通路富集分析显示丁酸合成通路在对照组显著升高
  • 详见 results/reports/analysis_report.html

作者

  • [用户],XX 大学生物信息学专业,[届别]

引用

如使用本项目代码或结果,请引用:[论文信息]

### 每段的作用

| 段落 | 作用 | 白话 |
|---|---|---|
| 项目简介 | 30 秒内让读者知道这是干啥的 | 电梯演讲 |
| 数据来源 | 数据可追溯 | 原始数据在哪下载的 |
| 环境配置 | 一条命令复现环境 | 换台电脑也能装好 |
| 分析流程 | 怎么跑、跑哪些步骤 | 操作手册 |
| 目录结构 | 文件在哪找 | 地图 |
| 结果概要 | 关键发现 | 不想看代码的人直接看结论 |

---

## 四、分析报告规范

### R Markdown 报告模板

```r
---
title: "T2D 肠道菌群多样性分析报告"
author: "[用户]"
date: "`r Sys.Date()`"           # 自动插入日期
output:
  html_document:
    toc: true                    # 自动生成目录
    toc_float: true              # 目录悬浮在侧边
    code_folding: hide           # 代码默认折叠(点击展开)
    theme: flatly                # 主题样式
params:
  data_path: "results/tables/"   # 参数化路径(可复用)
---

# 1. 分析概述
本报告分析 30 例 T2D 患者和 30 例健康对照的 16S rRNA 测序数据...

# 2. 数据概况
```{r load-data}
# 加载必要的包
library(phyloseq)   # 微生物组分析
library(ggplot2)    # 绑图

# 读取数据
ps <- readRDS(file.path(params$data_path, "phyloseq_object.rds"))
cat("样本数:", nsamples(ps), "\n")
cat("物种数:", ntaxa(ps), "\n")

3. Alpha 多样性

plot_richness(ps, x = "Group", measures = c("Shannon", "Simpson"))

4. 软件版本

sessionInfo()   # 记录所有 R 包版本
### Jupyter Notebook 报告模板

```python
# 第一个 cell:环境信息
import sys
import pandas as pd
import matplotlib.pyplot as plt

print(f"Python: {sys.version}")       # 记录 Python 版本
print(f"pandas: {pd.__version__}")    # 记录包版本

# 导出为 HTML:jupyter nbconvert --to html report.ipynb


五、代码注释规范

注释类型

# ========== 1. 文件级注释(docstring) ==========
"""
模块名: diversity_analysis.py
功  能: 计算 alpha/beta 多样性指标
作  者: [用户]
日  期: 2026-05-01
依  赖: scikit-bio>=0.5.8, pandas>=1.5
"""

# ========== 2. 函数级注释 ==========
def calculate_shannon(abundance_table):
    """
    计算 Shannon 多样性指数。

    Parameters
    ----------
    abundance_table : pd.DataFrame
        物种丰度表,行=样本,列=物种,值=reads数

    Returns
    -------
    pd.Series
        每个样本的 Shannon 指数

    Examples
    --------
    >>> shannon = calculate_shannon(otu_table)
    >>> print(shannon.mean())
    """
    # 3. 行内注释(解释"为什么",而非"做了什么")
    # 加伪计数避免 log(0)(零丰度物种会导致数学错误)
    table = abundance_table + 1e-10
    proportions = table.div(table.sum(axis=1), axis=0)
    return -(proportions * np.log(proportions)).sum(axis=1)

Shell 脚本注释

# ========== 函数说明 ==========
# 功能:检查 FASTQ 文件是否完整(行数应为 4 的倍数)
# 参数:$1 = fastq 文件路径
# 返回:0=完整,1=不完整
check_fastq_integrity() {
    local fastq_file="$1"
    local line_count
    line_count=$(zcat "$fastq_file" | wc -l)   # 统计行数(解压后)
    # FASTQ 每条 read 占 4 行,所以总行数必须能被 4 整除
    if (( line_count % 4 != 0 )); then
        return 1    # 不完整
    fi
    return 0
}

TODO / FIXME 标记

# TODO: 后续版本添加 Beta 多样性的 PERMANOVA 检验
# FIXME: 当样本数 < 10 时 bootstrap 会报错,需要加判断
# HACK: 临时绕过 phyloseq 的 bug,等上游修复后删除
# NOTE: 这里用 Bray-Curtis 而非 UniFrac 是因为没有进化树
# DEPRECATED: 这个函数在 v2.0 中将被 calculate_diversity() 替代

六、版本管理策略

语义化版本(SemVer)

v1.2.3
 │ │ └── Patch:修 bug(不影响接口)
 │ └──── Minor:加功能(向后兼容)
 └────── Major:重大变更(可能不兼容)

# 生信项目示例:
# v0.1.0 - 初始版本,完成质控流程
# v0.2.0 - 新增组装和分箱步骤
# v0.2.1 - 修复 MEGAHIT 内存参数错误
# v1.0.0 - 完整流程,论文投稿版本
# v1.1.0 - 审稿人建议新增功能注释分析

CHANGELOG.md 模板

# Changelog

## [v1.1.0] - 2026-05-03
### Added
- 新增 KEGG 功能注释分析步骤(scripts/05_kegg.sh)
- 新增差异丰度分析的 Volcano Plot

### Changed
- MEGAHIT 最小 contig 长度从 500bp 改为 1000bp

### Fixed
- 修复 MetaBAT2 在单样本模式下崩溃的问题

## [v1.0.0] - 2026-04-20
### Added
- 完整的宏基因组分析流程(QC → Assembly → Binning → Taxonomy)
- R Markdown 分析报告
- conda 环境配置文件

Git 标签管理

# 给当前提交打标签
git tag -a v1.0.0 -m "论文投稿版本"   # -a 创建带注释的标签
git push origin v1.0.0                 # 推送标签到远程

# 查看所有标签
git tag -l                             # 列出所有标签

# 查看某个标签的详情
git show v1.0.0

七、实验记录本(Electronic Lab Notebook)

ELN(电子实验记录本)记录你每天做了什么分析、为什么做、结果如何。这和 Git commit message 不一样——commit 记录"改了什么代码",ELN 记录"为什么做这个分析、看到了什么现象"。

简易 Markdown ELN 模板

# 分析日志

## 2026-05-03

### 目的
探索 T2D 组和对照组在 Shannon 多样性上是否有显著差异

### 操作
1. 用 phyloseq 计算 Shannon 指数
2. Wilcoxon 秩和检验比较两组差异
3. 绘制箱线图

### 参数
- 稀释深度:10000 reads/样本
- 检验方法:Wilcoxon rank-sum test(非正态分布)

### 结果
- T2D 组 Shannon 指数均值 2.31 ± 0.45
- 对照组 Shannon 指数均值 3.12 ± 0.38
- p = 0.003(显著)

### 决策
多样性确实降低,继续做 Beta 多样性(PCoA)看组间分离情况

### 相关文件
- 脚本:scripts/05_statistics.R(第 42-78 行)
- 图:results/figures/fig1_alpha_diversity.pdf

八、可重复性清单

每个项目交付或论文投稿前,对照检查:

检查项怎么做达标标准
数据来源README 中记录 SRA/GEO 编号或合作方信息第三方能找到原始数据
软件版本conda list > envs/versions.txtenvironment.yml精确到小版本号
参数记录统一放 config/params.yaml 或脚本注释头每个工具的关键参数都有
随机种子代码中 set.seed(42) / --seed 42涉及随机的步骤都固定种子
环境文件conda env export > environment.yml一条命令重建环境
执行顺序README 或 Makefile 说明运行顺序按说明能跑通
中间文件关键中间结果有保留或可重新生成不依赖消失的临时文件
代码入库git status 没有未提交的变更代码和结果对应的版本一致

一键导出环境

# conda 环境导出
conda env export --no-builds > envs/environment.yml
# --no-builds 去掉编译哈希,跨平台兼容性更好

# pip 环境导出
pip freeze > envs/requirements.txt

# R 环境记录
Rscript -e 'sessionInfo()' > envs/R_session_info.txt
# 或者用 renv
Rscript -e 'renv::snapshot()'

九、面试怎么答

Q1: 你怎么组织一个生信分析项目的目录?

我会按 data/scripts/results/docs/envs 的结构组织。data/raw 放原始数据且设为只读,scripts 里的脚本按步骤编号(01_qc.sh、02_assembly.sh),results 放最终图表和报告,envs 放 conda 的 environment.yml。项目根目录有 README 说明数据来源、运行方式和结果概要。这样任何人拿到项目就知道怎么跑。

Q2: 你怎么保证分析的可重复性?

四个层面:数据层面,记录 SRA 编号和下载日期,原始数据只读不改;软件层面,用 conda environment.yml 锁定所有软件版本;参数层面,关键参数集中在 config 文件或脚本注释里,随机步骤固定种子(如 set.seed(42));流程层面,用 Makefile 或 Snakemake 管理步骤依赖,确保执行顺序正确。

Q3: 你的代码注释习惯是什么?

我遵循"注释解释 Why,代码本身解释 What"的原则。文件头有模块说明和依赖列表,函数有 docstring 说明参数和返回值,行内注释解释不明显的设计决策。我还用 TODO/FIXME 标记待改进和已知 bug,方便后续追踪。Shell 脚本每一行都加中文注释,因为团队成员技术背景不同。

Q4: 你用过哪些工具来管理分析流程?

小项目用 Makefile,它自带依赖追踪和并行执行;中大项目用 Snakemake,它支持集群提交、conda 环境隔离和断点续跑;容器化用 Docker/Singularity 确保环境一致。版本管理用 Git,每个分析阶段打 tag(如 v1.0-submission)。重要决策和分析思路记在 Markdown 格式的实验记录本里。

Q5: 如何交接一个生信项目给新人?

首先确保 README 完整:数据在哪、怎么配环境、怎么跑流程、结果在哪看。其次提供 environment.yml 让新人一条命令建好环境。脚本有注释、有编号,配合 Makefile 或 Snakemake 可以一键重跑。最后是 CHANGELOG 记录了每个版本改了什么、为什么改。如果项目复杂,我还会写一份分析日志(notebook.md),记录关键决策的思考过程。


十、速查表

项目初始化命令

# 一键创建项目目录结构
mkdir -p myproject/{data/{raw,processed,reference,external},scripts/utils,results/{figures,tables,reports},docs,envs,config,logs}
touch myproject/{README.md,CHANGELOG.md,Makefile,.gitignore}
chmod -R 444 myproject/data/raw/   # 原始数据只读(有文件后设)

文件命名规范

规则正确示例错误示例
小写+下划线sample_metadata.tsvSample Metadata.tsv
日期用 ISO 格式2026-05-03_report.html05-03-2026_report.html
脚本编号01_quality_control.shqc.sh
版本号在文件名外Git tag v1.0script_v1_final_v2.sh

环境管理速查

任务命令
导出 conda 环境conda env export --no-builds > environment.yml
从文件建环境conda env create -f environment.yml
导出 pip 依赖pip freeze > requirements.txt
R 环境快照renv::snapshot()
查看 R 包版本sessionInfo()

Git 常用操作

任务命令
打版本标签git tag -a v1.0.0 -m "描述"
查看变更历史git log --oneline --graph
查看某次提交改了什么git show <commit_hash>
忽略已跟踪的大文件git rm --cached large_file.bam

十一、延伸资源

资源说明地址
Noble (2009) PLoS Comput Biol经典论文:计算生物学项目组织https://doi.org/10.1371/journal.pcbi.1000424
Cookiecutter Data Science数据科学项目模板https://drivendata.github.io/cookiecutter-data-science/
Snakemake 文档工作流管理工具https://snakemake.readthedocs.io
conda 环境管理环境导出与重建https://docs.conda.io/projects/conda/en/latest/user-guide/tasks/manage-environments.html
语义化版本规范SemVer 官方文档https://semver.org/lang/zh-CN/
renv(R 环境管理)R 项目依赖管理https://rstudio.github.io/renv/
Ten Simple Rules for Reproducible Research可重复性研究十条准则https://doi.org/10.1371/journal.pcbi.1003285