Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
社区首页 >专栏 >都是FPKM进行差异分析,为啥差异感觉这么大呢?

都是FPKM进行差异分析,为啥差异感觉这么大呢?

作者头像
生信菜鸟团
发布于 2023-01-05 13:04:23
发布于 2023-01-05 13:04:23
6.9K10
代码可运行
举报
文章被收录于专栏:生信菜鸟团
运行总次数:0
代码可运行

缘起

上周我们比较了FPKM与count分别进行差异分析的区别,发现两者差异分析的结果基本一致。恰巧曾老师叫我好好看看一篇发表在frontiers in Molecular Neuroscience的文章,他的转录组数据处理使用的就是FPKM矩阵。那这周的推文的话,我们就来看看我们的流程分析结果与作者有何不同。当然,强调一下哈,有count还是尽量用count为好。

探究

今天,我们使用2020年发表在frontiers in Molecular Neuroscience杂志上,文献名称为Differential Gene Expression Patterns Between Apical and Basal Inner Hair Cells Revealed by RNA-Seq的转录组FPKM数据(附表4)进行差异分析,感兴趣的小伙伴也可以自身下载一下下面的上游数据定量,同上一篇推文一样,比较两种数据类型进行差异分析的异同。

转录组数据集介绍

该数据集提交在ENA官网,项目号是PRJNA593359,如有小伙伴想看上游,链接见https://www.ebi.ac.uk/ena/browser/view/PRJNA593359 。该数据集组别上分为两组,一组是Basal组,一组是Apical组,每组均有三个样本。

正式分析

1.利用fpkm值进行差异分析

进行差异分析时,阈值按照文章的选法,FC为2,p<0.001

代码语言:javascript
代码运行次数:0
复制
# 1.下载文中的补充数据集table 4.xlsx
rm(list=ls())
library(openxlsx)
library(stringr)
a=read.xlsx('table 4.xlsx',colNames = T) # 提取表达矩阵
class(a)
## [1] "data.frame"
colnames(a)=a[1,]
a=a[-1,]
table(duplicated(a$`Feature ID`))
## 
## FALSE  TRUE 
## 15307     1
a=a[!duplicated(a$`Feature ID`),]
rownames(a)=a$`Feature ID`
a=a[,-1]
keep <- rowSums(a>0) >= floor(0.5*ncol(a))
expMatrix <- a[keep,] #获得filter_count矩阵
#(防止0值影响FPKM转换为TPM)

# 2.FPKM值转换为TPM值
fpkmToTpm <- function(fpkm)
{
  exp(log(fpkm) - log(sum(fpkm)) + log(1e6))
}

class(expMatrix)
## [1] "data.frame"
expMatrix=na.omit(expMatrix)
numer=function(x){as.numeric(x)}
expMatrix=apply(expMatrix, 1, numer) 
#必须将矩阵中的字符类型由向量型改为字符型
expMatrix=t(expMatrix)
tpms <- apply(expMatrix,2,fpkmToTpm) 
tpms[1:3,]
##                    [,1]       [,2]     [,3]      [,4]     [,5]       [,6]
## 0610007P14Rik  47.67969 145.695029 22.27847   0.00000 117.7912  80.804891
## 0610009B22Rik 156.09341 300.652882 96.91044 104.00990 252.0514 224.045029
## 0610009L18Rik  30.88343   8.785541 39.00099  30.98678  10.0835   5.584516
colSums(tpms)
## [1] 1e+06 1e+06 1e+06 1e+06 1e+06 1e+06
colnames(tpms)=c("Apical1","Apical2","Apical3","Basal1","Basal2","Basal3")

# 3.差异分析
group_list=c(rep('Apical',3),rep('Basal',3))
## 强制限定顺序
group_list <- factor(group_list,levels = c("Apical","Basal"),ordered = F)
#表达矩阵数据校正
exprSet <- tpms
boxplot(exprSet,outline=FALSE, notch=T,col=group_list, las=2)
代码语言:javascript
代码运行次数:0
复制
library(limma) 
head(exprSet)
##                 Apical1    Apical2  Apical3       Basal1    Basal2     Basal3
## 0610007P14Rik  47.67969 145.695029 22.27847   0.00000000 117.79116  80.804891
## 0610009B22Rik 156.09341 300.652882 96.91044 104.00989902 252.05143 224.045029
## 0610009L18Rik  30.88343   8.785541 39.00099  30.98678285  10.08350   5.584516
## 0610009O20Rik  70.01261  83.931085 46.90684   0.00000000  35.58989  11.294728
## 0610010B08Rik  10.48073  14.035653 27.61583   0.06863075  10.89523   1.544271
## 0610010F05Rik  13.90093  11.348727 14.68230   0.00000000  90.48093   0.000000
exprSet=normalizeBetweenArrays(exprSet)
boxplot(exprSet,outline=FALSE, notch=T,col=group_list, las=2)
代码语言:javascript
代码运行次数:0
复制
#判断数据是否需要转换
exprSet <- log2(exprSet+1)
range(exprSet)
## [1]  0.00000 14.31486
#差异分析:
dat <- exprSet
design=model.matrix(~factor( group_list ))
fit=lmFit(dat,design)
fit=eBayes(fit)
options(digits = 4)
topTable(fit,coef=2,adjust='BH')
##          logFC AveExpr       t   P.Value adj.P.Val     B
## Adam8    5.364   2.682  13.180 4.176e-06   0.03458 4.131
## Ocm     -5.603   8.401 -12.813 5.033e-06   0.03458 4.018
## Nwd1     4.124   2.062   9.869 2.756e-05   0.06021 2.856
## Gm4869   3.901   1.951   9.800 2.882e-05   0.06021 2.823
## Rubcnl   3.858   1.929   9.769 2.942e-05   0.06021 2.807
## Igsf10   3.885   1.943   9.293 4.048e-05   0.06021 2.563
## Igfals   3.617   1.811   9.198 4.324e-05   0.06021 2.512
## Gm13547  3.582   1.791   9.123 4.556e-05   0.06021 2.471
## Bbox1    4.626   2.313   9.080 4.693e-05   0.06021 2.448
## Mmp23   -4.935   4.383  -9.050 4.794e-05   0.06021 2.431
bp=function(g){
  library(ggpubr)
  df=data.frame(gene=g,stage=group_list)
  p <- ggboxplot(df, x = "stage", y = "gene",
                 color = "stage", palette = "jco",
                 add = "jitter")
  #  Add p-value
  p + stat_compare_means()
}
deg=topTable(fit,coef=2,adjust='BH',number = Inf)
head(deg) 
##         logFC AveExpr       t   P.Value adj.P.Val     B
## Adam8   5.364   2.682  13.180 4.176e-06   0.03458 4.131
## Ocm    -5.603   8.401 -12.813 5.033e-06   0.03458 4.018
## Nwd1    4.124   2.062   9.869 2.756e-05   0.06021 2.856
## Gm4869  3.901   1.951   9.800 2.882e-05   0.06021 2.823
## Rubcnl  3.858   1.929   9.769 2.942e-05   0.06021 2.807
## Igsf10  3.885   1.943   9.293 4.048e-05   0.06021 2.563
#save(deg,file = 'deg.Rdata')

# 4.FPKM转换为TPM后,再利用limma进行差异分析

## 不同的阈值,筛选到的差异基因数量就不一样,后面的超几何分布检验结果就大相径庭。
if(T){
  logFC_t=1
  deg$g=ifelse(deg$P.Value>0.01,'stable',
               ifelse( deg$logFC > logFC_t,'UP',
                       ifelse( deg$logFC < -logFC_t,'DOWN','stable') )
  )
  table(deg$g)
  head(deg)
  
}
##         logFC AveExpr       t   P.Value adj.P.Val     B    g
## Adam8   5.364   2.682  13.180 4.176e-06   0.03458 4.131   UP
## Ocm    -5.603   8.401 -12.813 5.033e-06   0.03458 4.018 DOWN
## Nwd1    4.124   2.062   9.869 2.756e-05   0.06021 2.856   UP
## Gm4869  3.901   1.951   9.800 2.882e-05   0.06021 2.823   UP
## Rubcnl  3.858   1.929   9.769 2.942e-05   0.06021 2.807   UP
## Igsf10  3.885   1.943   9.293 4.048e-05   0.06021 2.563   UP
fpkm_deg=deg

2.绘制文章的两张图

代码语言:javascript
代码运行次数:0
复制
#  01复现第一张图,fpkm>1的Veen图,可以看看组别独有的基因
# 绘制思路:分别获得针对两个组别fpkm>1的基因,取个交集即可

apical=exprSet[,1:3]
apical=as.data.frame(apical)
apical$mean=apply(apical,1,mean)

basal=exprSet[,4:6]
basal=as.data.frame(basal)
basal$mean=apply(basal,1,mean)

# 韦恩图取个交集
Apical <- rownames(apical[apical$mean>1,])
Basal <- rownames(basal[basal$mean>1,])
library(ggvenn)
deg<-list(`Apical`=Apical,
          `Basal`=Basal)
p1 <- ggvenn(deg,
             show_percentage = F,
             stroke_color = "white",
             fill_color = c("#b2d4ec","#d3c0e2"),
             set_name_color = c("#ff0000","#4a9b83"))
p1 #30FDR分析的差异基因全在利用P值分析的差异基因里
代码语言:javascript
代码运行次数:0
复制

## 02差异基因箱线图
# 绘制箱线图
table(fpkm_deg$g=="UP")
## 
## FALSE  TRUE 
## 13454   287
table(fpkm_deg$g=="DOWN")
## 
## FALSE  TRUE 
## 13560   181
data=data.frame(c(287,181),row.names = c("up","down"))
colnames(data)=c("deg_number")
p2 <- ggplot(data,aes(x=rownames(data),y=deg_number,fill=rownames(data)))+
  geom_boxplot(width=0.6,alpha=0.8)
p3 <- p2+scale_y_continuous(breaks = seq(0,800,200),
                            limits=c(0,800))+theme_classic()
p3

3.用作者提出来的上调与下调基因在我的结果中验证

图就不修了哈,火山图的绘制很简单前面已经画了很多遍了,由于作者没有提供差异基因列表,我们就简单地针对其在文中提到的几个基因进行验证吧

代码语言:javascript
代码运行次数:0
复制
cg=c("Prkd1","Sncg","Nme2","Fbxo32")
deg_fc=fpkm_deg[cg,]
head(deg_fc)
##          logFC AveExpr      t  P.Value adj.P.Val      B      g
## Prkd1  -1.1511   5.959 -2.853 0.025267    0.4069 -3.381 stable
## Sncg   -2.0205   5.932 -4.412 0.003308    0.1865 -1.377   DOWN
## Nme2    0.8174   7.355  1.333 0.225381    0.7532 -5.430 stable
## Fbxo32  1.3724   6.863  2.908 0.023378    0.4002 -3.305 stable

# 此处重点看logFC,再与文章

以上我们对该篇文章的FPKM数据集进行了处理,还绘制了文章的两幅结果图以及运用了文中的几个基因进行验证。韦恩图中可能是由于我设置了过滤参数导致我们的结果有一定区别。但是与原文相比,我们的上调差异基因有287个,下调差异基因有181个。与文章的644个上调,45个下调在数量上存在显著不同,这点就很值得咀嚼。

检查的几个差异基因源于文中的描述,如下。与3中我们的差异分析结果相比较,logFC大致是对应了,但是p值两者存在很大不同。为啥同一个数据,一样的阈值两者差异基因的数量相差如此显著,难道是统计方法的不同导致的差异基因在作者的分析结果与我的分析结果中存在不同吗?感兴趣的小伙伴们可以尝试尝试,欢迎点评哈

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2022-12-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 生信菜鸟团 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
1 条评论
热度
最新
我之前从一篇清华发的NC里扒出的数据,走了一遍limma后,发现他们文章中用校正P值筛出了198个下调的,我统计结果中全部校正P值都大于0.05。。。换成P值后才有个200来个下调的。。。就很迷
我之前从一篇清华发的NC里扒出的数据,走了一遍limma后,发现他们文章中用校正P值筛出了198个下调的,我统计结果中全部校正P值都大于0.05。。。换成P值后才有个200来个下调的。。。就很迷
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
转录组差异分析FPKM与count处理差别大吗
这些天来,我们一般都是处理上游定量好的count数据,然后进行下游的转录组分析。但是,我们查看GEO数据集时,会发现有些数据集并没有提供count数据,而仅仅提供了FPKM或者RPKM等格式的数据。那当数据集提供的是FPKM数据集时,我们还能处理吗。前面曾老师分享的推文中描述了FPKM的处理方式,具体见RNAseq数据,下载GEO中的FPKM文件后该怎么下游分析,评论区中有小伙伴谈到limma包的作者不推荐用limma处理FPKM数据,最好用原始数据进行分析。那用count与用FPKM去处理获得的差异基因具有巨大的差别吗?曾老师前两天提出了这个疑问,于是便有了今天的推文。接下来,我们就探索一下用count与用FPKM去处理获得的差异基因是否具有巨大差别吧?
生信菜鸟团
2023/01/05
11.6K1
转录组差异分析FPKM与count处理差别大吗
RNAseq数据 | 下载GEO中的FPKM文件后该怎么下游分析
Oncogenic lncRNA downregulates cancer cell antigen presentation and intrinsic tumor suppression不过不需要看文章,大家只需要做差异分析即可,这个时候需要注意的是,作者提供的是RPKM值表达矩阵!
生信技能树
2022/06/08
1.8K0
RNAseq数据 | 下载GEO中的FPKM文件后该怎么下游分析
RNAseq数据,下载GEO中的FPKM文件后该怎么下游分析
我们有很多学徒数据挖掘任务,已经完成的目录见:学徒数据挖掘专题半年目录汇总(生信菜鸟团周一见) 欢迎大家加入我们的学习团队,下面看FPKM文件后该怎么下游分析
生信技能树
2019/12/23
19.1K3
RNAseq数据,下载GEO中的FPKM文件后该怎么下游分析
差异分析及KEGG注释简介
原来的bulk-RNA差异分析一般需要比较处理组(例如有三个样本)和处理组(例如也有三个样本),这里对于单细胞来讲,每个细胞就是一个样本,于是有768个样本,但是还是不能直接进行差异分析,还是需要先分个组,看看哪些细胞离得更近,就划分为一组,最后对每个组进行比较
生信技能树jimmy
2020/03/30
1.6K0
三种转录组差异分析方法及区别你会了吗?
在做项目时,曾有小伙伴对我用edgeR进行差异分析筛选出的具体显著差异基因表示质疑,因为发表的文章清楚的说明某个基因是差异基因,但是我edgeR的分析结果并没有表明。在小伙伴的质疑下,我认真看了下文章,发现文章用的是DEseq2进行差异分析。值得注意的是该小伙伴关注的差异基因是一个离散比较大的基因,此处的离散较大可以理解为假定对照组为5,6,7;实验组则为14,13,3的情况。那为什么这个基因在edgeR分析下不是显著差异基因,然而在DEseq2的分析下是差异基因呢?这应该很大程度源于算法判定显著差异基因的区别。接着,我看了关于DEseq2与edgeR区别的描述,发现「edgeR与Deseq2都是基于负二项分布模型做的,两者处理同一组数据时,相同阈值处理大部分基因是一样的,但是也会有一部分基因会因为离散度不同导致差异不同」,如刚刚示例的基因离散度被DEseq2识别为差异,但是不被edgeR识别,所以两种算法获取的差异基因与数目是存在细微区别的。
生信菜鸟团
2022/10/31
5.7K1
三种转录组差异分析方法及区别你会了吗?
手动计算logFC(wilcoxon差异分析)
logFC是log fold change的缩写,也就是log之后的差异倍数。这个差异倍数意思是某个基因在A组表达量的平均值是B组表达量平均值的几倍。
医学和生信笔记
2023/09/12
1.4K0
手动计算logFC(wilcoxon差异分析)
转录组差异分析这样做能行吗?
前段时间,我们分享了转录组三种常见差异分析的推文以及单样本1V1进行差异分析的推文。对单个样本进行差异分析时,我们能获得相应的差异基因。在转录组三种常见差异分析的推文中,我们利用取交集的方式看了下三种方法获得共同差异基因的交集情况。曾老师提出了一个有趣的猜想,试想如果我们将3V3的样本拆分成3次1V1进行差异分析,是否会出现什么有趣的现象呢。为了让结果可比,我们就用上次的数据集GSE190114吧。此次,我们除了关注3次1V1差异分析上调与下调差异基因分别共同的交集情况之外,还将关注3种常见分析方法的上调与下调差异基因分别与拆分成3次1V1差异分析的上调与下调差异基因的共同交集情况,「用于探究是否能够拆分成3次1V1后进行差异分析」。话不多说,由于此次所使用的数据与上次一样,对此次的探究描述与数据集介绍感兴趣的小伙伴,请移驾至三种转录组差异分析方法及区别你会了吗?。
生信菜鸟团
2022/10/31
6440
TNBC数据分析-GSE27447-GPL6244
五月份的学徒专注于GEO数据库里面的表达量芯片数据处理,主要的难点是表达量矩阵获取和探针的基因名字转换,合理的分组后就是标准的差异分析,富集分析。主要是参考我八年前的笔记:
生信技能树
2021/08/25
2.5K0
TNBC数据分析-GSE27447-GPL6244
GEO数据挖掘4
这里需要使用差异比较用到的limma包,在使用这个包进行分析之前,需要准备三个矩阵 * 表达矩阵 * 分组矩阵 * 差异比较矩阵
火星娃统计
2020/09/15
1.1K0
GEO数据挖掘4
TNBC数据分析-GSE76275-GPL570
五月份的学徒专注于GEO数据库里面的表达量芯片数据处理,主要的难点是表达量矩阵获取和探针的基因名字转换,合理的分组后就是标准的差异分析,富集分析。主要是参考我八年前的笔记:
生信技能树
2021/08/25
2.4K0
TNBC数据分析-GSE76275-GPL570
limma差异分析,谁和谁比很重要吗?
新手在刚接触limma包做差异分析的时候,会碰到很多教程,有的教程写的是正常组比疾病组,有的是疾病组比正常组,他们都是对的,只有你凌乱了。
医学和生信笔记
2022/11/15
1.1K0
limma差异分析,谁和谁比很重要吗?
单基因差异分析并绘制火山图和热图
介绍下绘制火山图和热图的方法,如何在火山图或者热图中标记特定的基因,顺便学习下EnhancedVolcano包绘制火山图。
医学和生信笔记
2023/08/30
7200
单基因差异分析并绘制火山图和热图
生物信息数据分析教程视频——14-芯片数据的表达差异分析
视频地址:http://mpvideo.qpic.cn/0bc33iaakaaag4amkcjtmzrvbwwdaxnaabia.f10002.mp4? 参考文章: 生信入门第3课 | 了解基因芯片
DoubleHelix
2022/12/15
3990
单基因富集分析
前面给大家介绍了这么多的富集分析,其实主要就是两种:ORA和GSEA。通常都是需要一个基因集才可以做。
医学和生信笔记
2023/08/30
6030
单基因富集分析
根据分组信息做差异分析- 这个一文不够的
通过前面的讲解,我们顺利的了解了GEO数据库以及如何下载其数据,得到我们想要的表达矩阵,也成功的使用了GSEA这个分析套路。 历史目录: 解读GEO数据存放规律及下载,一文就够 解读SRA数据库规律一文就够 从GEO数据库下载得到表达矩阵 一文就够 GSEA分析一文就够(单机版+R语言版) 但最常用的其实是差异分析,下面我们来细细讲解: 提到表达量数据分析,不管是通过芯片技术还是高通量测序技术得到的表达量矩阵,我们都需要根据样本的分组信息来对所检测到的所有基因或者蛋白分子来做差异分析,想找到显著性变化的生
生信技能树
2018/03/29
4.5K0
根据分组信息做差异分析- 这个一文不够的
在学术不端的数据取舍上面反复横跳
然后马上这些策略就被应用到了单细胞转录组数据挖掘层面,因为反正也不需要自己产出数据了,过去三五年间单细胞的火热带动了海量的各种实验设计的公开的表达量矩阵。比如这个文献:《Lipid-related protein NECTIN2 is an important marker in the progression of carotid atherosclerosis: An intersection of clinical and basic studies》就是看了看两个分组的具体的基因的差异,在普通bulk转录组和单细胞转录组两个数据集里面,如下所示:
生信技能树
2024/01/11
2710
在学术不端的数据取舍上面反复横跳
玮瑜课程
1. gset <- getGEO("GSE149507",destdir = ".",getGPL = T)→gset[["GSE149507_series_matrix.txt.gz"]]@featureData@data
用户10803254
2024/01/10
2710
TCGA分析-数据整理2
素素
2023/10/31
3490
表达芯片数据分析3——基因差异分析绘制火山图及差异基因热图
Erics blog
2023/10/02
6681
limma对基因芯片数据基因差异表达分析
>suppressPackageStartupMessages(library(CLL))
黑妹的小屋
2020/08/06
1.1K0
相关推荐
转录组差异分析FPKM与count处理差别大吗
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 大模型知识引擎×DeepSeek实践征文
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验