
简介这是一份癌症基因组图谱数据库TCGA使用教程的PDF电子书面向生物医学研究者、生信入门学生以及需要借助公共癌症数据开展课题的分析人员解决从数据获取、筛选到结果解析的全流程问题。资源仅包含1个PDF文件压缩包只有12.75兆下载后方便在任意设备上阅读。教程系统梳理了TCGA的分层数据结构包括病例、样本、样本类型与分子数据帮助读者理解不同样本之间的关系重点演示如何查询特定基因的突变信息比如单核苷酸变异和插入缺失还能比较肿瘤组织与正常组织的基因表达差异快速锁定潜在的关键驱动基因。同时教程还涉及拷贝数变异、甲基化、蛋白质表达与磷酸化等多层次组学数据的下载与整合思路指导学习者在数据平台中按癌症类型、样本类型、突变类型等条件进行高级搜索并安全下载经脱敏处理的科研数据为构建多维癌症模型奠定基础。该教程至今已有1150人学习既是初学者的系统入门指南也可供有经验的研究者随时查阅操作要点。1. TCGA数据库到底在解决什么问题从“没有自己的测序数据”说起如果你做肿瘤相关研究手头没有自己的测序样本却想验证某个基因在癌组织中高不高表达、跟患者预后有没有关系TCGA数据库几乎是绕不开的第一站。它把上万例癌症患者的转录组、突变、拷贝数、甲基化数据和临床随访信息集中在同一个公开平台上让“用公开数据发文章”这件事从想法变成了常见操作。不少人下载教程后卡在同一个位置数据是拿到了但不知道哪些文件该用、怎么整理成能分析的表。这篇笔记就把 TCGA 从数据模型、下载方式到整理成表达矩阵和生存分析数据的完整路径讲一遍新手能照着做熟手可以跳着看边界和坑。2. 从零看懂TCGA的数据模型数据类型与下载选型2.1 先分清四类常用数据表达谱、突变、拷贝数与临床打开 TCGA 的官方 GDC 门户第一眼看到的是按“项目Project—样本Case—文件File”组织的三层结构。一个项目对应一个癌种比如我们常说的某癌种项目每个项目下有几百到上千个样本每个样本又挂着一批数据文件。很多人第一次进去被文件列表吓到其实常用的就四类。数据类型常见文件内容典型用途转录组表达谱STAR-Counts 的基因计数、FPKM、TPM 矩阵差异表达、预后基因筛选、表达与临床关联体细胞突变突变注释文件MAF 格式突变图谱、高频突变基因、肿瘤突变负荷拷贝数变异基因水平的拷贝数估计文件扩增/缺失事件、CNA 与表达联动分析临床数据临床表格含生存时间、分期、年龄等生存分析、分组比较、多因素 Cox 回归以转录组表达谱为例同一个样本在 GDC 里可能出现“STAR - Counts”“STAR - FPKM”“STAR - TPM”等不同文件。它们的区别在于定量口径Counts 是原始计数适合做差异表达DESeq2、edgeRFPKM/TPM 是归一化后的表达量适合做基因间比较和展示。我一般建议把 Counts 作为分析主文件FPKM/TPM 留到画热图和展示时再用。如果是刚接触 TCGA我通常会先明确一个问题你到底要做什么分析只验证一个基因的表达就下表达谱要做突变与预后的关系才需要 MAF 文件只做生存分析的话临床表格加表达谱就够了。下载之前把分析目标定清楚能省掉一大半无用功。2.2 网页版下载适合小样本快速取数的完整路径当需要某个癌种全部样本的表达谱时网页版下载其实是足够高效的。具体路径是这样走的第一步进入 GDC 门户后切到 Files 页面左侧过滤器找到“Data Category”勾选“Transcriptome Profiling”再在“Workflow Type”里选“STAR - Counts”。这一步的作用是把文件清单缩小到我们真正需要的基因计数文件。第二步在左侧继续找“Experimental Strategy”勾选“RNA-Seq”。如果你只想要某一个癌种在“Projects”里勾选对应项目。注意有些项目会有多个批次的数据文件列表里会出现同一个样本在不同批次下的多个记录这时候按“最新数据版本”过滤。第三步把过滤后的文件全部加入购物车。GDC 提供两种下载方式直接下载压缩包或者生成 manifest 清单文件。文件数量在几十个以内时直接下载压缩包没问题文件数量达到几百个以上建议选 manifest配合 GDC 客户端下载。需要注意一个细节勾选“STAR - Counts”时GDC 会同时列出基因水平的 counts 文件和转录本水平的 counts 文件。前端默认展示的是基因水平文件文件名里通常带 gene 字样别选成转录本版本否则后面合并矩阵时行名会变成转录本 ID处理起来很别扭。2.3 GDC客户端批量下载清单文件过滤与参数说明当你要下载一个项目的全部表达谱文件上千个文件时浏览器直接下载几乎必然中断。我的习惯是网页上生成 manifest 文件然后用 GDC 客户端在本地批量拉取。这个过程绕不开命令行但需要的命令其实很短。gdc-client download -m manifest.txt -d ./tcga_data上面这条命令的意思是按照 manifest.txt 中列出的文件 ID把数据下载到当前目录下的 tcga_data 文件夹。client 会自动为每个文件建立以文件 UUID 命名的子目录原始文件和解压后的文件都放在里面。常用参数我一般这样设-m指定 manifest 文件路径这个文件在网页购物车里导出-d指定下载根目录建议单独建一个目录不要跟脚本混在一起--retry-amount设置重试次数网络波动大时我会设成 10--n-processes设置并行下载进程数默认 4 到 8 之间比较稳妥开太多容易触发服务端限流。下载完成后不要急着删 manifest它记录了文件 UUID 与文件名的对应关系后续整理文件时可以用来反向查错。如果下载中断了重新执行同一条命令client 会跳过已经完整下载的文件只补齐缺失的部分。3. 把下载的原始文件整理成可分析矩阵从命名规则到表达矩阵3.1 读懂TCGA的文件与样本命名条形码与样本类型下载下来的文件目录是 UUID 命名的看不出样本信息。真正的样本标识藏在两个地方一个是从网页下载的 metadata JSON另一个是每个文件内部的样本条形码barcode。TCGA 的样本条形码有固定格式比如 TCGA-XX-YYYY-01A-11R-A33Z-07。这里最关键的是第四段也就是“01”“11”这些数字。01 表示原发肿瘤10 表示正常组织癌旁06 表示转移灶。在做肿瘤与正常对照的差异分析时必须靠这段数字来分组而不能靠文件名判断。很多人拿到数据后直接把所有样本放一起跑差异分析结果正常样本和肿瘤样本混在一起分组全乱。此外条形码第五段的字母表示样本分析类型比如 A 表示 DNA 分析、R 表示 RNA 分析。后续合并临床信息和表达矩阵时要保证两边用的是同一个样本条形码的完整版本不要只取前半截做匹配否则同一患者可能因为多次测序记录而匹配出多个条目。3.2 用Python合并STAR-Counts为表达矩阵每个下载文件夹里都有一个后缀为.counts.tsv的文件里面是多列制表符格式。分别是基因 ID、基因名、基因类型以及不同方向的计数列。合并表达矩阵的原理很简单遍历所有样本文件夹读取每个 counts 文件取其中的 unstranded 列作为该样本的表达量最后把各样本的列拼到一起行名用基因 ID。import pandas as pd import glob import os sample_files glob.glob(./tcga_data/*/*.counts.tsv) expr_dict {} for f in sample_files: # 从文件路径中解析出样本条形码 barcode os.path.basename(f).split(.)[0] df pd.read_csv(f, sep\t, comment#, low_memoryFalse) # 只保留基因水平记录gene_type 列通常不为空 df df[df[gene_type].notna()] # 提取基因 ID 和 unstranded 表达量 expr_dict[barcode] df.set_index(gene_id)[unstranded] expr_matrix pd.DataFrame(expr_dict) # 过滤掉全零基因保留在至少 20% 样本中表达量大于 10 的基因 keep (expr_matrix 10).sum(axis1) (expr_matrix.shape[1] * 0.2) expr_matrix expr_matrix.loc[keep] print(expr_matrix.shape)这段代码有几个值得注意的地方。读取时用了comment#因为 counts 文件头部有若干行以#开头的元数据不用这个参数会把表头解析错。取列时只取unstranded这是 STAR 比对后未区分链方向的计数TCGA 官方推荐用于常规表达分析。过滤条件是经验值全零基因和极低表达基因建议直接去掉否则后续差异分析会产生大量无意义的低表达噪声。合并完成后行名是 ENSG 开头的基因 ID比如 ENSG00000000003不方便阅读。我习惯再映射一列基因名用文件自带的gene_name列构建映射表。这里要注意一个 ENSG ID 可能对应多个基因名版本映射时建议保留第一次出现的对应关系避免重复行。3.3 临床信息合并从clinical.tsv提取生存时间与分组TCGA 的临床数据同样可以从网页按项目下载通常是clinical.tsv格式。这个表格列非常多但真正用于生存分析的核心变量就几个vital_status、days_to_death、days_to_last_follow_up、age_at_index、ajcc_pathologic_stage等。clin pd.read_csv(clinical.tsv, sep\t, dtypestr) # 计算总生存时间死亡患者用 days_to_death存活患者用最后随访时间 clin[OS_time] clin.apply( lambda r: float(r[days_to_death]) if r[vital_status] Dead else float(r[days_to_last_follow_up]), axis1 ) clin[OS_event] (clin[vital_status] Dead).astype(int)这段逻辑是整个生存分析的基础。很多初学者直接把days_to_death当作生存时间结果所有存活患者的生存时间变成缺失值样本量骤减。正确做法是死亡患者用死亡时间存活患者用最后随访时间再把事件列标成 0 和 1。OS_event等于 1 表示发生了终点事件死亡0 表示删失。删失的意思不是患者没死而是我们不知道他后来什么时候死的统计上按“到随访结束时仍然活着”处理。临床表格里的样本 ID 通常是患者在 TCGA 中的案例 IDcase ID格式跟样本条形码不同。合并时要先通过 GDC 提供的样本-案例对应关系做一次映射或者直接用条形码的前十二位TCGA-XX-YYYY作为连接键因为同一个患者的多个样本共享前十二位。4. TCGA使用避坑指南样本命名、版本差异与数据缺失的三个翻车现场4.1 样本数对不上把“癌”和“癌旁”混进同一组了现象明明下载了某癌种 500 多个样本的表达谱整理后却发现样本量比预期多或者少差异分析结果也跟文献对不上。原因TCGA 项目里除了肿瘤样本还包含一部分癌旁正常样本和转移样本。过滤条件选了整个项目后所有样本都会混进来。如果不按条形码第四段分组肿瘤和正常的对比就完全失去意义。解决拿到表达矩阵后第一时间用条形码第四段做分组标记。01 归为肿瘤组11 归为正常组06 单独剔除或标记为转移组。在后续分析中始终带着这个分组列不要靠文件名猜。4.2 同一基因在两个版本文件里表达量差十倍工作流没选对现象某同学在一个项目里下载了部分样本的 FPKM 文件又下载了另一部分样本的 Counts 文件合并后同一个基因在样本间的表达量差异极大画出来的热图一塌糊涂。原因Counts 是原始文库计数受测序深度影响数值通常从几十到几万FPKM/TPM 做了长度和深度归一化数值一般从 0 到几百。两者混合在一起本质上就不是同一个度量。解决一个分析里只用同一种工作流的数据。做差异表达统一用 STAR - Counts做展示统一用 TPM。如果确实需要跨平台合并先对 Counts 做 TMM 或 DESeq2 的归一化处理不要直接拿原始值比较。4.3 临床信息丢掉一半样本样本条形码没有对齐到正确层级现象临床表格里明明有 500 行记录跟表达谱合并后只剩 200 多行大量样本匹配不上。原因临床表格的样本标识是 case ID而表达谱列名是 sample barcode。这两者不在同一个粒度上一个患者可能有多个样本肿瘤和正常各一个直接按全条形码匹配自然对不上。解决构建两列映射表一列是 case ID一列是 sample barcode。合并时先把临床表按 case ID 去重通常一个患者保留一条临床记录再去关联表达矩阵的样本列。我一般会保留一份从 GDC 页面导出的样本-案例映射文件这个文件在项目页面里可以直接生成。4.4 生存分析事件全为0把随访时间当成了生存时间现象跑 KM 曲线时发现所有患者的事件列都是 0生存曲线变成一条水平线分组比较没有意义。原因临床表格里days_to_last_follow_up和days_to_death是两列互斥字段。直接用days_to_last_follow_up填所有样本死亡患者的生存时间就变成了最后一次随访时间事件也错标成了删失。解决按前一章的方式用vital_status做条件判断死亡取死亡时间存活取随访时间。写完这段逻辑后立刻检查事件为 1 的样本比例一般在 30% 到 70% 之间如果比例低于 10%说明事件构造大概率出了问题。4.5 下载中断后从头再来manifest没有保留现象大规模下载时网络断了重跑 gdc-client 命令后发现之前下载的文件被重新下载一遍时间和流量都白费。原因GDC 客户端确实支持断点续传但前提是 manifest 文件不变、下载目录不变。有人换了目录名或重新导出了 manifest客户端就把所有文件当作新任务。解决manifest 文件固定放在下载根目录外面重新执行命令时保持参数完全一致。客户端检测到已有完整文件会自动跳过。另外不建议手动移动 uuid 命名的子目录目录结构变了也会触发重新下载。5. 用TCGA数据快速验证一个基因的预后价值从表达分箱到KM曲线的完整脚本拿到整理好的表达矩阵和临床表之后最常见的落地场景是验证某个基因是否跟患者生存有关。这一节给出一个可以完整运行的套路取基因表达量按中位数把样本分成高低两组然后做 KM 曲线和 log-rank 检验。这里用lifelines库实现。import pandas as pd from lifelines import KaplanMeierFitter from lifelines.statistics import logrank_test # expr_matrix: 行为基因, 列为样本条形码 # clin: 包含 OS_time 与 OS_event, 索引为样本条形码 gene GENE_SYMBOL df pd.DataFrame({ expr: expr_matrix.loc[gene].values, sample: expr_matrix.columns }).merge(clin, left_onsample, right_indexTrue) # 中位数组别 median_val df[expr].median() df[group] (df[expr] median_val).astype(int) kmf KaplanMeierFitter() for g in [0, 1]: mask df[group] g kmf.fit( durationsdf.loc[mask, OS_time], event_observeddf.loc[mask, OS_event], labelfGroup{g} ) kmf.plot_survival_function() result logrank_test( df.loc[df[group] 0, OS_time], df.loc[df[group] 1, OS_time], df.loc[df[group] 0, OS_event], df.loc[df[group] 1, OS_event], ) print(p-value:, result.p_value)这段脚本的核心是中位数分组策略。它不假设表达量和风险之间存在线性关系只是把样本分成高表达和低表达两类所以对样本量要求相对宽松。但中位数组别也有局限如果表达量分布严重偏斜中位数可能把很多低表达样本和中等表达样本混在一起这时可以改用上下三分位数分组只保留前 30% 和后 30% 的样本。多基因联合分析时我一般会给每个基因单独跑一遍这段流程输出 p 值列表再挑出 p 值较小的基因做多因素 Cox 回归。单基因 KM 曲线适合快速筛选多因素模型才是最终发文章时拿得出手的证据。另外建议在跑正式分析前先做一次数据体检检查表达矩阵是否存在全零列临床表是否有空值两个表的样本交集数量是否正确。这三项检查花不了两分钟却能避免大量返工。真实项目里我最深的体会是TCGA 的坑大多不在统计方法上而在数据整理的第一步。样本标识没对齐、度量类型混用、生存时间构造错误这三个问题占了失败案例的绝大部分。希望这些步骤能帮你少走一段弯路。本文还有配套的精品资源点击获取