GSE16561数据集的文章图表复现,小众的illumina表达量芯片
1. 首先是下载数据
gset <- getGEO('GSE16561', destdir=".", AnnotGPL = F, getGPL = F)
下载完成后一看数据,
发现好多负值,应该是数据经过背景矫正,log2转换之后又经过scale的数据(z-score的)。也就是小洁老师上课时说的那种不能直接用来做DEG分析的芯片数据。心中顿时飞过一匹草泥马~
2. 登录GEO查看原始数据
没办法了,只能是亲自去GEO界面查看该数据集,果然,这个芯片从来没有听说过,应该是很小众了。GPL是Illumina 的 beadchip,GPL号还不在生信技能树大神整理的注释包列表中(http://www.bio-info-trainee.com/1399.html),不过有rio包,注释信息到方便解决,但是依然隐隐有种前途堪忧的预感。
不管三七二十一,先把能下下来的写着RAW的东东都下下来解压后检查一遍再说。
然而......让人难过的事情再次发生了....
定睛一看这个raw data的结构,和Jimmy大神的五年前的教程里的数据结构相去甚远(《用lumi包来处理illumina的bead系列表达芯片》 http://www.bio-info-trainee.com/1944.html )
另一个raw包里的芯片信息并没有提及rawdata是如何处理的,似乎对后续的数据分析毫无帮助......
3. 生命不止,折腾不息,查看soft和作者原文
但是,小白我并不想放弃这个GSE,就想看看这个rawdata是怎么处理的,基于生命不止,折腾不息的精神于是我又把soft文件下了下来,定睛一看:
似乎我们离真相又靠近了一点,起码知道这个rawdata大概经历了什么才变成了一开始看到的带了负值的scale数据。此外我还下载了该数据的SCI原文,里面的信息也和我的理解差不多。
4. 大胆假设,小心求证,不服就干,反正错了又不要钱
不过又有几个问题摆在了我的面前:
- 这个GeneSpring软件处理的背景矫正用的都是哪些探针?
- 我们看到的rawdata是经过背景矫正的么?
因为查不到具体的作为背景矫正用的control探针的信息,作为一个初生牛犊不怕虎的生信小白,我做出了一个大胆的决假设:假定我们之前看到的rawdata是经过背景矫正的,反正也是死马当活马医、错了也不要钱,不服就干......
一顿操作猛如虎,经过quantile normalization和log2转换后**,我终于画出了一张漂亮的boxplot......**
为了证实我的操作是否正确,我把这个图发给了Jimmy大神,在收到Jimmy大神的肯定之后,我欢快的进行了后续的DEG分析,当我满心欢喜的查看分析结果时,悲剧再次发生了,我的差异基因结果如下:
然而原作者的结果如下:
差别还是有些大......怀着忐忑的心情,我再次联系上了Jimmy大神,Jimmy大神尽然爽快的答应帮我看一看这个数据集,简直不敢相信大神肯出手相救,在这里请大神收下我的膝盖!
高效的Jimmy大神很快将他的结果和代码发给我了,大神就是大神,复现的结果和原作者基本相同(其中log的底数是e):
我仔细的拜读了一遍大神的代码,发现原来我只顾着进行quantile normalization和log2转换了,却忽略了小洁老师课里给我们讲的去除重复探针的操作。导致最终的结果与原作者相差甚远。这里附上Jimmy大神的代码(未经大神同意就po出大神的代码,还希望大神不要见怪):
b=read.table('GSE16561_RAW.txt',header = T)
b[1:4,1:4]
rownames(b)=b[,1]
b=b[,-1]
b=log(b+1)
boxplot(b,las=2)
dat=b
library(limma)
dat=normalizeBetweenArrays(dat)
boxplot(dat,las=2)
pd=pData(a)
colnames(dat)
library(stringr)
group_list= str_split(colnames(dat) ,'_',simplify = T)[,2]
table(group_list)
dat[1:4,1:4]
a
# 这个 AnnoProbe 包是jimmy大神为了拯救我们小白亲自开发的!
library(AnnoProbe)
ids=idmap('GPL6883',type = 'soft')
head(ids)
colnames(ids)=c('probe_id','symbol')
ids=ids[ids$symbol != '',]
ids=ids[ids$probe_id %in% rownames(dat),]
dat[1:4,1:4]
dat=dat[ids$probe_id,]
ids$median=apply(dat,1,median) #ids新建median这一列,列名为median,同时对dat这个矩阵按行操作,取每一行的中位数,将结果给到median这一列的每一行
ids=ids[order(ids$symbol,ids$median,decreasing = T),]
#对ids$symbol按照ids$median中位数从大到小排列的顺序排序,将对应的行赋值为一个新的ids
ids=ids[!duplicated(ids$symbol),]#将symbol这一列取取出重复项,'!'为否,即取出不重复的项,去除重复的gene ,保留每个基因最大表达量结果s
dat=dat[ids$probe_id,] #新的ids取出probe_id这一列,将dat按照取出的这一列中的每一行组成一个新的dat
rownames(dat)=ids$symbol#把ids的symbol这一列中的每一行给dat作为dat的行名
dat[1:4,1:4] #保留每个基因ID第一次出现的信息(median最大的那个)
save(dat,group_list,file = 'step1-output.Rdata')
经过大神的代码处理之后的rawdata再拿来跑一遍差异分析的流程,后续结果就令人十分满意了!
5. 小结
- 小白这次大胆的探索真的是歪打正着,在这里写下手账,希望可以给那些被类似数据困扰的小伙伴们提供一定的参考。
- 做rawdata处理的时候一定不要忘记去重!不要忘记去重!不要忘记去重!。
6. 致谢
本人临床背景,生信零基础,本着对生信的一腔热情,联系上了Jimmy大神,参加了生信技能树的学习班!特别感谢Jimmy大神的启发式引导、还有小洁老师精彩的R语言课程和时不时给我灌下的毒鸡汤!
因为个人的工作时间的调整问题,后半程郭老师和张老师的linux课程我大多数时候无法参加线上直播,但好在有回放可以看,这里要给两位老师说一声抱歉,因为不能参与到直播互动中来而浪费了你们精心备好的课!
总之,很荣幸能够找到生信技能树,向各位老师讨教学习,这真的是一段很棒的经历。
by:Jack Sparrow, 一个生信零基础的小白学员。
2020/08/01
- WebLogic XMLDecoder反序列化漏洞(CVE-2017-10271)漏洞复现&修复方案
- 如何在CDSW中使用R绘制直方图
- CTF学习交流群 第一期入群题writeup大放送
- 如何使用Hue创建Spark1和Spark2的Oozie工作流
- 【译】深入研究 Laravel 的依赖注入容器
- 一次XSS突破的探险
- 如何使用Hue创建Spark2的Oozie工作流(补充)
- 如何基于CDSW基础镜像定制Docker
- OVSDB介绍及在OpenDaylight中的调用
- 如何在CDH集群的非元数据库节点安装MySQL5.7.12
- PySpark数据类型转换异常分析
- SQLI-LABS 更新帖(二)
- 如何重置Hue用户密码
- 如何使用R连接Hive与Impala
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 「新手入门福利」一张脑图带你掌握Git命令
- LeetCode | 58.最后一个单词的长度
- 模拟面试,解锁大厂 ——从Android的事件分发说起
- scRepertoire||单细胞免疫组库分析:R语言应用(一)
- Docker体验(二) - 自建Image
- 小程序代码复用 - template
- 五. Spring Security 权限管理
- 文档驱动 —— 表单组件(五):基于Ant Design Vue 的表单控件的demo,再也不需要写代码了。 表单一 公司信息表单二 员工信息,简化版,只是为了演示表单的切换。以后会出
- 文档驱动 —— 查询组件:将查询功能做到极致!你说还有啥没包含进来?antdv + vue 3.0 全新体验 快捷查询个性化查询方案更换各种查询方式更多的查询条件meta 驱动封装基础
- ES6能干啥?
- JQuery中DOM对象
- ES6都有什么?
- 前端html换肤
- 纯CSS换肤
- JS模块化和使用