最近好几个做生信的朋友问我,想搞空间转录组或者原位测序的数据,怎么从GEO里把矩阵提出来?
这活儿听着简单,真上手时坑不少。
我折腾了半个月,把流程捋顺了。
今天就把这套geo数据库直接获取的表达矩阵的经验摊开说。
咱们不搞虚的。
直接说重点。
首先你得明确一点,GEO是个宝库。
但库太杂了。
你想找H562的SeqFISH,或者Visium的数据,光搜名字不够。
得会看元数据。
我有个朋友,刚入门时把RNA-seq当成了空间数据去拉。
结果跑了一天,算出来的聚类全是乱的。
后来才发现,样本类型根本没选对。
所以第一步,筛选要狠。
用Bioconductor包里的GEOquery,或者GEOparse都行。
但手动查GEO网站更直观。
先看“Supplementary File”那栏。
有没有叫matrix或者count的文件?
如果有.h5、.mtx或者.csv,那就有戏。
如果没有原始reads,那你得找处理好的矩阵。
这一步卡住人的很多。
记得看Accession Number,比如GPLxxx,那是平台探针。
不同平台,探针注释完全不一样。
这里有个细节,很多人忽略。
GEO里的“Data Table”有时只是展示用。
真正的数据在“Supplementary Files”里。
我上次帮学生调bug,发现他下载的是预览CSV。
数据只有前1000行。
跑出来的结果自然偏。
一定要下载完整的.tar.gz包。
解开后,看文件列表。
通常有一个big matrix。
格式可能是sparse matrix的mtx格式。
这时候,用R语言读入最方便。
我一般用blockMatrix包,或者直接Seurat。
Seurat的read.visium或者read.h5对象,能自动识别很多常见格式。
但注意,不同仪器导出的列头可能不同。
比如有的叫spot_id,有的叫barcode。
有的把行名做成cell_id,有的做成gene。
我遇到过最麻烦的,是一次Visium数据,行名是barcode,但顺序和坐标对不上。
查了半天官网文档,才发现坐标文件是单独的一个csv。
必须手动merge进去。
这个坑,不踩一下真的不知道有多痛。
所以,拿到矩阵后,第一件事是检查维度。
行是基因,列是细胞或斑点。
如果行是细胞,那必须转置。
很多人忘了转置,直接跑Seurat的整合。
最后报错,或者结果不对。
还有一个关键点,背景值处理。
GEO下载的数据,通常是没有QC的。
你要自己看分布。
画个小提琴图,或者箱线图。
看看有没有异常的零值或者高值。
如果是10x数据,空泡比例通常占大头。
这时候用Seurat的Dropouts过滤一下。
我一般设阈值:检出基因数大于200,总UMI大于2000。
当然,这个阈值因样本而异。
我做过一例肝癌患者,基质丰富,阈值就得放宽。
死搬硬套参数,是新手大忌。
回到正题,怎么高效批量获取?
我写了个小脚本,结合R和Python。
先扫描GEO系列,筛选特定平台。
自动下载补充文件。
解压,识别矩阵文件。
存入本地硬盘。
这样效率高很多。
但脚本要有容错机制。
比如某篇数据文件损坏,或者命名特殊。
脚本不能直接崩掉。
要记录日志,跳过异常,继续下一个。
我见过有人跑了一晚上,早上起来发现只处理了一半。
剩下的一半因为文件名带特殊字符,直接报错中断。
太可惜了。
所以,自动化不等于盲目。
逻辑要稳。
另外,版本控制很重要。
记录清楚,哪个数据集,用了哪个包版本。
环境用conda或者renv管理。
不然过了半年,复现不出结果。
那感觉比失恋还难受。
说回geo数据库直接获取的表达矩阵这个流程。
核心就是三点。
一是选对数据源。
二是解析文件结构。
三是标准化处理。
做到这三点,基本就成功了一半。
剩下的,就是跑分析算法了。
最后,提醒一句。
数据预处理的时间,有时比跑模型还长。
别嫌弃。
垃圾进,垃圾出。
数据底子不好,后面算法再高级也白搭。
我见过太多案例,算法换了几个,数据没动,结果依旧一团糟。
后来老老实实回去做QC,去掉异常样本,结果立刻清晰了。
这就是数据治理的魅力。
它不性感,但实用。
所以,下次遇到geo数据库直接获取的表达矩阵时。
别急着兴奋。
先冷静,查元数据,看文件,再动手。
稳,比快更重要。
希望这篇能帮到正愁眉苦脸的你。
如果还有卡壳的地方。
不妨多去论坛看看别人的踩坑记录。
往往能给你灵光一现。
共勉。