开启辅助访问
 找回密码
 立即注册

人人都要会的转录组(RNA-seq)下游分析.

yaxingit8899 回答数16 浏览数4266
目前转录组测个序大概是1000-2000块钱一台样,这个波动的范围取决于各个公司提供的服务,以及你们那个地区生信的普及程度。既然这么便宜,那么每个看到明确现象的实验团队都改尝试一下RNA-seq,说不定就给课题开了新的思路。
转录组测序的分析分为上游分析和下游分析,简单区分就是,你有没有服务器。如果有,那就把上游分析给包了,这在以前不可想象,但是因为生信技能树这样的团体存在,推动了我国生物信息技术的普及,让生物信息不在遥不可及,而这本是国之重器们该做的事情。
假如你没有服务器,也不要紧,Y叔的出现,使得下游分析变得十分简单。仅仅使用R语言,使用Y叔的神包clusterprofiler,坐在家里喝着咖啡,也可以搞定所有下游分析。
我们今天的任务就是展示一下这个过程,抛砖引玉。
首先,加载数据。

load(file = "expr_df.Rdata")
这个数据就是测序后的counts矩阵,跟公司要到这个数据就可以脱离服务器自个往下走。如果没有数据也不要紧,在TCGA的教程中,我们也获得过这样的数据。
从GDC下载TCGA肿瘤数据库的数据
把GDC下载的多个TCGA文件批量读入R
我们来看一看这个数据:


他由一列组成,第一列是ensemble的ID,剩下的6列是3Vs3的样本,也就是通常转录组需要的6个样本。(要确定一下这个数据的类型是data.frame,如果你喜欢用data.table::fread读入文件,那么读进来的是tibble,需要使用data.frame转换一下,要不然Deseq2会报错)
构建metadata文件

因为我们需要用Deseq2这个包来分析差异,那么就要先制作一台metadata文件指示分组信息,他是一台数据框,由两列组成
metadata <- data.frame(sample_id = colnames(expr_df)[-1])
sample <- rep(c("con","treat"),each=3)
metadata$sample <- relevel(factor(sample),"con")


构建dds对象

这一步由DESeqDataSetFromMatrix这个函数来完成,他需要输入我们的表达矩阵,制作好的metadata,还要制定分组的列,在这里是sample,最后一台tidy的意思是,我们第一列是基因ID,需要自动处理。
library(DESeq2)
## 第一列有名称,所以tidy=TRUE
dds <-DESeqDataSetFromMatrix(countData=expr_df,
                             colData=metadata,
                             design=~sample,
                             tidy=TRUE)
看一下有多少行呢?58734行
nrow(dds)
查看一下有行名么?有的,如果没有就不要往下做了,应该是你的数据不是data.frame格式
rownames(dds)
数据过滤

别看有这么多行,不是每一台就要都要表达的,如果一行基因在所有样本中的counts数小于等于1,我们就把他删掉,实际上,不做这一步,对差异分析的结果没有影响,可能会对GSEA的结果有影响。
dds <- dds[rowSums(counts(dds))>1,]
这时候我们再来看他的行数已经变成了27134
nrow(dds)
样本聚类

有时候,我们会把实验样本的的标签搞错,比如,明明是加药组,但是有一组没忘记加药,如果对他聚类,他会被划归为正常组,这个是需要我们知道的。
用vst来标化数据,实际上还有rlog方法,或者就是log2的方法,官网推荐< 30个样本用rlog,大于30个样本用vst,速度更快,这里我们不要计较那么多了,就用vst,因为真实的TCGA数据,样本往往大于30个。
vsd <- vst(dds, blind = FALSE)
再用dist这个函数计算样本间的距离
sampleDists <- dist(t(assay(vsd)))
用hclust来进行层次聚类
hc <- hclust(sampleDists, method = "ward.D2")
然后画图
plot(hc, hang = -1)


从图上看,两类样本分开了,不需要特殊处理, 这个图可能没什么用,但是如果要给老板呈现,我觉得态度要端正,可以尝试一下别的方法。

library(factoextra)
res <- hcut(sampleDists, k = 2, stand = TRUE)
# Visualize
fviz_dend(res,
          # 加边框
          rect = TRUE,
          # 边框颜色
          rect_border="cluster",
          # 边框线条类型
          rect_lty=2,
          # 边框线条粗细
          lwd=1.2,
          # 边框填充
          rect_fill = T,
          # 字体大小
          cex = 1,
          # 字体颜色
          color_labels_by_k=T,
          # 平行放置
          horiz=T)


Deseq2 计算

主程序是Deseq这个函数,里面顺序执行了一系列函数,每一步都可以单独运行。这一步,只有6个样本基本上就是10s以内,如果是1000个样本,小电脑跑不过去,跑过去也需要5个小时以上,很耗时间。
dds <- DESeq(dds)


得到dds之后,我们可以通过counts这个函数得到能作图的标注化后的counts数据,他矫正了样本间测序的深度,使得样本间可以直接比较。
normalized_counts <- as.data.frame(counts(dds, normalized=TRUE))


Deseq2内置了一台画图函数,可以省事地制定基因作图
plotCounts(dds, gene = "ENSG00000172183", intgroup=c("sample"))


这个功能本质上没有什么用,但是,可以提前确定实验的质量。比如,你的两组是敲减某个基因以及对照组,通过制定那个基因作图,就可以看出实验有没有成功,如果这个基因没有任何改变,也可以不用往下做了。回去重新做实验送样本吧。
我们说过,这种图自个看就可以,给老板看就算了,你得美化一下,那么他里面有个内置的参数returnData可以返回作图数据。
一旦返回数据,我们就可以用ggplot2自个简单画一下。
plotdata <- plotCounts(dds, gene = "ENSG00000172183", intgroup=c("sample"),returnData = T)
library(ggplot2)
ggplot(plotdata,aes(x=sample,y=count,col=sample))+
  geom_point()+
  theme_bw()


目前看起来平淡无奇,如果样本多,可以画出点图配boxplot,如果是匹配样本,那么还可以画出匹配的图。
有一点要强调一下,vst,以及log2的标准化,跟标准化的counts不是一台概念。前者是为了以后的聚类,热土,PCA分析,比如,我们计算样本间的距离就是用的vst 标化的数据,而标准化的counts是为了差异作图,你看纵坐标就会发现,他的数值一般很大。
LogFC的矫正

这一步,对于依赖logFC变化值的分析,很重要,比如GSEA分析。我们画一台MAplot图,看图说话
contrast <- c("sample", "treat", "con")
dd1 <- results(dds, contrast=contrast, alpha = 0.05)
plotMA(dd1, ylim=c(-2,2))


MA-plot上的点是每一台基因。横坐标是标准化后的counts平均值,纵坐标是log后的变化值。红色的点是p.adjust的值小于0.05的基因,由counts函数中的alpha 参数指定。
我们发目前左侧,有很多counts很小的基因,发生了很大的变化,但是没有明显意义。类似于从(1,3,9)变成了(20,12,3)他们的counts很小,波动性很大,对logFC产生了很大的影响。
GSEA分析中,排序就是按照logFC来进行的。按照这个结果往下做,GSEA那里,富集不到任何条目。
那就需要矫正。用的函数是lfcShrink,有很多参数,我们只演示一种
dd2 <- lfcShrink(dds, contrast=contrast, res=dd1)
plotMA(dd2, ylim=c(-2,2))


这样,原先那些波动性很大的基因,就被矫正了。而此时有LogFC以,红色的点为主。
差异分析的结果

这个结果实际上已经通过counts函数获得了,我们不在担心,处理组和对照组完全相反这种情况,因为他内置了参数设定比较组。比如,我们有5个处理组,我们不需要做5次Deseq,我们在results中指定即可。
用summary这个函数,可以看到差异分析的结果,高表达和低表达的比例。低丰度基因所占的比例。
summary(dd2, alpha = 0.05)


再把差异分析的结果转化成data.frame的格式
library(dplyr)
library(tibble)
res <- dd2 %>%
  data.frame() %>%
  rownames_to_column("gene_id")


基因ID转换

以前我们从gtf文件转换的, 但是我们需要gtf文件来提取mRNA以及lncRNA,就顺手做了ID转换,而且,mRNA和lncRNA是分别做的Deseq2,这从原理上来讲,是有问题的,Deseq2矫正了测序的深度,而这个深度应该是所有基因算在一起的深度,不应该分开来算。
TGCA数据的标准化以及差异分析
用两个包来转换,得到ENTREZID用于后续分析,得到SYMBOL便于识别。
library(AnnotationDbi)
library(org.Hs.eg.db)
res$symbol <- mapIds(org.Hs.eg.db,
                     keys=res$gene_id,
                     column="SYMBOL",
                     keytype="ENSEMBL",
                     multiVals="first")
res$entrez <- mapIds(org.Hs.eg.db,
                     keys=res$gene_id,
                     column="ENTREZID",
                     keytype="ENSEMBL",
                     multiVals="first")


有了这个文件,里面有logFC,p值,还有基因名称,我们可以完成GO,KEGG,热图,火山图所有操作。这一部分内容参考
最有诚意的GEO数据库教程
这个帖子目前已经有接近4000次访问,这在我们这样一台小号是不容易的,靠的是真诚。
制作geneList

我们在那个帖子里面并没有讲GSEA分析,今天来展示一下。原理略过。我们这里或是用Y叔的神包clusterprofier,神包虽好,记得引用。
使用这个包做GSEA,要制作一台genelist,这个是一台向量,他的内容是排序后的logFC值,他的名称是ENTREZID,而这两个我们都是不缺的,在上一步得到的差异结果中。
library(dplyr)
gene_df <- res %>%
  dplyr::select(gene_id,log2FoldChange,symbol,entrez) %>%
  ## 去掉NA
  filter(entrez!="NA") %>%
  ## 去掉重复
  distinct(entrez,.keep_all = T)


制作genelist的三部曲
## 1.获取基因logFC
geneList <- gene_df$log2FoldChange
## 2.命名
names(geneList) = gene_df$entrez
## 3.排序很重要
geneList = sort(geneList, decreasing = TRUE)
看一下这个genelist,增加感性的理解
head(geneList)


GSEA分析

完成KEGG的GSEA分析
library(clusterProfiler)
## 没有富集到任何数据
gseaKEGG <- gseKEGG(geneList     = geneList,
                    organism     = 'hsa',
                    nPerm        = 1000,
                    minGSSize    = 20,
                    pvalueCutoff = 0.05,
                    verbose      = FALSE)
作图展示富集分布图
library(ggplot2)
dotplot(gseaKEGG,showCategory=12,split=".sign")+facet_grid(~.sign)


这时候,我们看到有一些通路是被激活的,有一些通路是被抑制的。比如Cell cycle是被抑制的,我们可以选取单个通路来作图。

把富集的结果转换成data.frame,找到Cell cycle的通路ID是hsa04110
gseaKEGG_results <- gseaKEGG@result


使用gseaplot2把他画出来
library(enrichplot)
pathway.id = "hsa04110"
gseaplot2(gseaKEGG,
          color = "red",
          geneSetID = pathway.id,
          pvalue_table = T)


也可以画出一台激活的
pathway.id = "hsa04060"
gseaplot2(gseaKEGG,
          color = "red",
          geneSetID = pathway.id,
          pvalue_table = T)


pathview 展示

我们目前知道cell cycle是被抑制的,如果还想看一下这个通路里面的基因是如何变化的,应该如何办呢,pathview 可以帮到我们。
library(pathview)
pathway.id = "hsa04110"
pv.out <- pathview(gene.data  = geneList,
                   pathway.id = pathway.id,
                   species    = "hsa")


改变一下参数,可以得到另外一种构图
library(pathview)
pathway.id = "hsa04110"
pv.out <- pathview(gene.data  = geneList,
                   pathway.id = pathway.id,
                   species    = "hsa",
                   kegg.native = F)


一眼看过去,都是绿的,说明这个通路确实是被抑制了,还可以在图上缕一缕,哪些是核心分子,一般说来,越往上游越核心。
总结

写到这里,GEO的分析,TCGA的基本分析,RNA-seq的基本分析都写完了。这几个帖子可以把大部分的培训班给搞定。里面的内容,只要会一点R语言,就可以重复。说到底,R语言的培训,最应该培训的是基本技能。
但是你有没有发现,虽然图做的这么好看,我们总觉得还欠缺了些什么。这也是目前生物信息分析和实验结合的痛点。
我如果开题,你这一通分析,或是没有让我确定要研究的核心基因。
而这个,是一篇帖子,或者普通培训班不能给予的。
如果未来的生信培训要出点什么彩,这个一定是个方向。
生信技术是通用的,优点就是可被重复,可以被写成教程,但是挖掘能做实验可发文章的核心基因,目前并没有系统教程,类似于玄学。这需要我们长年累月地积累,才能有点感觉,而我觉得这是科研人员做生信分析的核心技能。在这方面,我也是个初学者。
否则,我们就是个能做实验会做分析的技术人员,谈不上一台独立的科研人。
tlerbao | 来自北京
写的太好了,让人热血沸腾
用Deepseek满血版问问看
回复
使用道具 举报
wycctqxl | 来自北京
请问一下做GO分析的code有吗,我看了很多文章你是唯一一个做kegg图的时候能把上调和下调通路区分开的,所以想问一下GO分析能不能也这么做
回复
使用道具 举报
weikaijun | 未知
请教一下,为什么差异基因分析的结果里pvalue和p.adjust会有那么多NA值?感觉不太对啊
回复
使用道具 举报
wmwm | 未知
咨询一个小问题,关于聚类中使用计算两类聚类的方法,我看我们这里是选择的ward方法,这里的选择依据或是标准是什么?能不能选择single、 average 、median、complete 等方法呢?
回复
使用道具 举报
szit | 来自北京
想请假一下,要完成您文章里这些分析流程,对电脑配置的要求高吗?
回复
使用道具 举报
yzk12 | 来自北京
同问
回复
使用道具 举报
xiaoxianyu | 来自北京
我目前也刚学DESeq2,你这个问题我读到过。DESeq2包原文是这么解释的“The results function of the DESeq2 package performs independent filtering by default using the mean of normalized counts as a filter statistic. A threshold on the filter statistic is found which optimizes the number of adjusted p values lower than a significance level alpha (we use the standard variable name for significance level, though it is unrelated to the dispersion parameter α). The theory behind independent filtering is discussed in greater detail below. The adjusted p values for the genes which do not pass the filter threshold are set to NA.”出处:Analyzing RNA-seq data with DESeq2。有NA是正常的,这些pvalue,p.adjust是NA的,其实并不重要。
回复
使用道具 举报
zwg1 | 来自河南
几乎没什么配置要求
回复
使用道具 举报
sky小二 | 未知
讲的太好了,有自己的理解,感谢作者!
回复
使用道具 举报
12下一页
快速回复
您需要登录后才可以回帖 登录 | 立即注册

当贝投影