文章目录

  • 学习来源
  • 1. 数据准备
    • 学习目标
    • 1.1 安装RNAseq123包和所需的包,并下载样本数据
    • 1.2 读入文件
    • 1.3 构建样本的分组信息
    • 1.4 基因注释
  • 2. 数据预处理
    • 2.1 转换count数据为CPM值
    • 2.2 过滤表达量太低的基因
    • 2.3 基因表达标准化
    • 2.4 样本非监督聚类
  • 3. 差异表达分析
    • 3.1 差异表达分析
    • 3.2 绘制Venn图
    • 3.3 导出差异表达基因的数据
    • 3.4 Examining individual DE genes from top to bottom
  • 4. 差异基因结果可视化
    • 4.1 log-CPM ~ logFC图
    • 4.2 绘制热图

使用limma,edgeR,Glimma 进行完整的数据分析流程指南 可参见:
http://master.bioconductor.org/packages/release/workflows/html/RNAseq123.html


学习来源

  • https://bioconductor.github.io/BiocWorkshops/rna-seq-analysis-is-easy-as-1-2-3-with-limma-glimma-and-edger.html

1. 数据准备

学习目标

  • read in count data and format as a DGEList-object 读取count格式的数据,并格式化为DGE对象
  • annotate Entrez gene identifiers with gene information 注释基因
  • filter out lowly expressed genes 过滤低表达的基因
  • normalise gene expression values 标准化基因表达数据
  • unsupervised clustering of samples (standard and interactive plots) 对样本进行无监督聚类
  • linear modelling for comparisons of interest 对感兴趣的分组用线性模型进行比较
  • remove heteroscedascity
  • examine the number of differentially expressed genes 检查差异表达基因的数目
  • mean-difference plots (standard and interactive plots) 画图
  • heatmaps 绘制热图

1.1 安装RNAseq123包和所需的包,并下载样本数据

suppressPackageStartupMessages({library(limma)library(Glimma)library(edgeR)library(Mus.musculus)
})
BiocManager::install("RNAseq123")
## download sample data
url <- "https://www.ncbi.nlm.nih.gov/geo/download/?acc=GSE63310&format=file"
utils::download.file(url, destfile="GSE63310_RAW.tar", mode="wb")
utils::untar("GSE63310_RAW.tar", exdir = ".")
files <- c("GSM1545535_10_6_5_11.txt", "GSM1545536_9_6_5_11.txt", "GSM1545538_purep53.txt","GSM1545539_JMS8-2.txt", "GSM1545540_JMS8-3.txt", "GSM1545541_JMS8-4.txt","GSM1545542_JMS8-5.txt", "GSM1545544_JMS9-P7c.txt", "GSM1545545_JMS9-P8c.txt")
for(i in paste(files, ".gz", sep=""))  R.utils::gunzip(i, overwrite=TRUE)

1.2 读入文件

每份文件,都包含给定样本的count数;我们本次练习只包含 basal, LP 和 ML这三类样本

## read data
read.delim(file.path(".", files[1]), nrow=5)## Use readDEG read counts
x <- readDGE(file.path(".", files), columns=c(1,3))
class(x)
dim(x)

如果count的数据是存储在单个文件中,那么可以使用 DEGList 函数,将数据读入函数后转为 DGEList 对象

1.3 构建样本的分组信息

对于下游分析而言,每个样本的分组实验信息需要添加上去。
包括: 细胞类型(本次练习中是 basal,LP,ML),基因型(wild-type野生型,knock-out 敲除型),表型(disease,status,sex,age),样本处理情况(drug,control),实验的批次信息等等
我们的DGEList对象包括:一个存储了所有细胞类型(group)和批次(lane)的 samples 的数据框。 注意,通过使用 x$sanples 提取数据时,每个样本的文库的大小会自动计算,并且 标准化因子会设置为1 。

  • 为了简化后续的运算,我们首先将GEO 样本ID中的 GSM前缀 去除
## Organising sample information 设定sample的名字
# 提取sample的名字
samplenames <- substring(colnames(x), 12, nchar(colnames(x)))
samplenames## 设置样本信息
colnames(x) <- samplenames
# 分组
group <- as.factor(c("LP", "ML", "Basal", "Basal", "ML", "LP", "Basal", "ML", "LP"))
x$samples$group <- group # 为每个样本添加细胞类型信息
lane <- as.factor(rep(c("L004","L006","L008"), c(3,4,2)))
x$samples$lane <- lane # 添加lane的信息
x$samples  # 此时sample信息中就会多出分组和细胞类型两列

1.4 基因注释

DGEList 对象中包含名为 genes 的二级数据框,它主要用来存储和count矩阵相对应的行的基因相关信息。基因的信息可以使用物种包(例如小鼠的 Mus.musculus 包,人类的 Homo.sapiens 包) ,或者 biomaRt 包 来完成填充注释。

  • 本例中,我们使用提取物种包 Mus.musculus 中的注释基因 gene symbols 和染色体信息 来为count矩阵做注释(我们count矩阵原来是按照entrez id 来对基因进行表示的,这次我们通过与entrez id 对应的 gene symbol和染色体信息,来完善矩阵的基因注释)
## using the Mus.musculus package
## to retrieve associated gene symbols and chromosome information
geneid <- rownames(x)
genes <- select(Mus.musculus, keys=geneid, columns=c("SYMBOL", "TXCHROM"), keytype="ENTREZID")   # 提取symbol和chr, 以entrezid作为map id的源头
head(genes)
## !duplicated replicate genes
genes <- genes[!duplicated(genes$ENTREZID),]
## add genes 将提取好的基因信息添加入我们的DGEList中genes这个二级数据框
x$genes <- genes
x

需要注意的是
在本例中,注释和数据对象中的基因顺序是相同的。如果由于缺失和/或重新排列的基因id而不是这种情况,则可以使用 match 函数对基因进行正确排序。然后,将基因注释的数据框架添加到数据对象中,并整齐地打包在DGEList对象中,DGEList对象包含原始计数数据以及相关的样本信息基因注释

  • 这个时候就可以看到我们的DGEList对象x中有 个二级数据框了:samplescountsgenes
> x
An object of class "DGEList"
$samplesfiles group lib.size norm.factors lane
5_10_6_5_11 ./GSM1545535_10_6_5_11.txt    LP 32863052            1 L004
6_9_6_5_11   ./GSM1545536_9_6_5_11.txt    ML 35335491            1 L004
8_purep53     ./GSM1545538_purep53.txt Basal 57160817            1 L004
9_JMS8-2       ./GSM1545539_JMS8-2.txt Basal 51368625            1 L006
0_JMS8-3       ./GSM1545540_JMS8-3.txt    ML 75795034            1 L006
1_JMS8-4       ./GSM1545541_JMS8-4.txt    LP 60517657            1 L006
2_JMS8-5       ./GSM1545542_JMS8-5.txt Basal 55086324            1 L006
4_JMS9-P7c   ./GSM1545544_JMS9-P7c.txt    ML 21311068            1 L008
5_JMS9-P8c   ./GSM1545545_JMS9-P8c.txt    LP 19958838            1 L008$countsSamples
Tags        5_10_6_5_11 6_9_6_5_11 8_purep53 9_JMS8-2 0_JMS8-3 1_JMS8-4 2_JMS8-5 4_JMS9-P7c497097              1          2       342      526        3        3      535          2100503874           0          0         5        6        0        0        5          0100038431           0          0         0        0        0        0        1          019888               0          1         0        0       17        2        0          120671               1          1        76       40       33       14       98         18Samples
Tags        5_JMS9-P8c497097             0100503874          0100038431          019888              020671              8
27174 more rows ...$genesENTREZID  SYMBOL TXCHROM
1    497097    Xkr4    chr1
2 100503874 Gm19938    <NA>
3 100038431 Gm10568    <NA>
4     19888     Rp1    chr1
5     20671   Sox17    chr1
27174 more rows ...

2. 数据预处理

2.1 转换count数据为CPM值

差异表达分析之前,由于不同的测序深度会导致counts数目不同,所以为了消除这种由建库引起的基因之间的差异,我们需要将数据归一化。归一化常见的方法有: CPM, log-CPM, RPKMFPKM 。本例中使用CPM值(这已足够)。

  • 本例中使用 edgeR 包中的 cpm 函数来完成数据的归一化,log转换的时候取0.25作为先验来避免取到0 . (edgeR 包也提供了 rpkm 函数 来计算 RPKM值)
## convert counts to CPM and log-CPM
cpm <- cpm(x)
lcpm <- cpm(x, log=TRUE) # 取log值

2.2 过滤表达量太低的基因

## Removing genes that are lowly expressed
# 首先查看那些在所有样本中均为0的基因数目
table(rowSums(x$counts==0)==9) # 可以发现有5153个基因在所有样本中表达量均为0
  • 在任何情况下,生物学水平上没有表达的基因都应该被丢弃,这样可以将基因的子集缩小到那些感兴趣的基因,并在做差异表达时减少下游分析所用于检验的基因数量。通过检验log-CPM值可以看出,每个样本中都有很大比例的基因未表达或低表达(如图a所示)。
  • 以CPM为1(相当于log-CPM值为0)作为分界线阈值来检查基因是低表达或者高表达,如果其表达高于此阈值,则视为表达,否则为低表达。基因必须在至少一组中表达(或在整个实验中至少三个样本中表达),以备后续分析。
  • 在这里,CPM值为1意味着如果一个基因在测序深度最低的样本中至少有20个计数(JMS9-P8c,文库大小约为2600万)。在测序深度最大的样本中至少有76个计数(JMS8-3,库大小约为。7600万)。如果测得的reads是外显子的而不是整个基因的,或实验的测序深度较低,则可以考虑较低的CPM阈值。
# 取出至少在三个样本中cpm值均大于1的基因
keep.exprs <- rowSums(cpm>1)>=3
x <- x[keep.exprs,, keep.lib.sizes=FALSE]
dim(x)

通过以上代码的过滤操作,我们就把基因的数量减少到最开始输入的一半了
接下来我们通过绘图,来可视化这个过程

## 绘图展示基因过滤前后log-cpm值的分布情况
library(RColorBrewer)
nsamples <- ncol(x)
col <- brewer.pal(nsamples, "Paired") ## 配置绘图调色盘的主题,paired 是 qualitative palettes 中的一个颜色配置
# col <- brewer.pal(nsamples, "Pastel1") # 尝试使用其它颜色
par(mfrow=c(1,2))
plot(density(lcpm[,1]), col=col[1], lwd=2, ylim=c(0,0.21), las=2, main="", xlab="") # 首先对第一列的第一个样本绘图
title(main="A. Raw data", xlab="Log-cpm") # 加入title
abline(v=0, lty=3) # 在0坐标处添加分隔虚线
for (i in 2:nsamples){ # 批量在同一画布上绘出其它样本的cpm分布情况den <- density(lcpm[,i])lines(den$x, den$y, col=col[i], lwd=2)
}
legend("topright", samplenames, text.col=col, bty="n") # 添加图例
## 开始对过滤后的lcpm绘图,函数功能注释基本同上
lcpm <- cpm(x, log=TRUE)
plot(density(lcpm[,1]), col=col[1], lwd=2, ylim=c(0,0.21), las=2, main="", xlab="")
title(main="B. Filtered data", xlab="Log-cpm")
abline(v=0, lty=3)
for (i in 2:nsamples){den <- density(lcpm[,i])lines(den$x, den$y, col=col[i], lwd=2)
}
legend("topright", samplenames, text.col=col, bty="n")

2.3 基因表达标准化

  • 使用 edgeR 包中的 calcNormFactors 函数来进行数据标准化 ,
    这里计算的标准化因子用作库大小的比例因子。
  • 当用此函数对 DGEList 对象做标准化时,标准化后的尺度因子会自动存储在 x$samples$norm.factors 中。
  • 对于本例数据集而言,TMM标准化的过程比较温和,可以发现标准化的尺度因子基本都接近于1
x <- calcNormFactors(x, method = "TMM")
x$samples$norm.factors
[1] 0.9053456 1.0211400 1.0406751 1.0414376 0.9933397 0.9145960 0.9962872
[8] 1.1050585 0.9978264
  • 接下来可视化展示数据标准化后的情况
    为了使可视化更加的直观,我们对数据进行略微的调整:使第一个样本的计数减少到原始值的5%,而在第二个样本中,它们被扩大到原来的5倍
x2 <- x # 制作一份copy x2
x2$samples$norm.factors <- 1
x2$counts[,1] <- ceiling(x2$counts[,1]*0.05)
x2$counts[,2] <- x2$counts[,2]*5
  • 绘制箱线图
par(mfrow=c(1,2))
lcpm <- cpm(x2, log=TRUE)
boxplot(lcpm, las=2, col=col, main="")
title(main="A. Example: Unnormalised data",ylab="Log-cpm")
x2 <- calcNormFactors(x2)
x2$samples$norm.factors
#> [1] 0.05472223 6.13059440 1.22927355 1.17051887 1.21487709 1.05622968
#> [7] 1.14587663 1.26129350 1.11702264
lcpm <- cpm(x2, log=TRUE)
boxplot(lcpm, las=2, col=col, main="")
title(main="B. Example: Normalised data",ylab="Log-cpm")

明显看到标准化后数据更加整齐了

2.4 样本非监督聚类

差异分析之前,一个重要的工作,就是对样本进行聚类画图分析。聚类可以揭示样本之间的相似性与差异性,这样也更好的帮助我们去判断哪些样本可以用来进行差异比较。如果是同一个处理中的多个重复样本,那么这些样本聚类的时候就会聚在一起,否则很可能是实验中数据有问题。

  • limma包中提供了 plotMDS 函数来实现多维标度图的绘制。
## 非监督聚类
# 展示样本之间的差异性与相似性
# 同一个处理的多个重复,没啥实验误差的话一般会聚在一起
lcpm <- cpm(x, log=TRUE)
par(mfrow=c(1,2)) # set huabu
col.group <- group
levels(col.group) <- brewer.pal(nlevels(col.group), "Set1")
col.group <- as.character(col.group)
col.lane <- lane
levels(col.lane) <- brewer.pal(nlevels(col.lane), "Set2")
col.lane <- as.character(col.lane)
plotMDS(lcpm, labels=group, col=col.group)
title(main="A. Sample groups")
plotMDS(lcpm, labels=lane, col=col.lane, dim=c(3,4))
title(main="B. Sequencing lanes")

可以看到,LP,ML,Basal 三种细胞类型的样本,重复处理之间都聚在了一起。也可以发现,如果对LP 和 ML 做比对的话,可能差异比较小

  • 也可以使用 Glimma 包中 glMDSPlot 绘制MDS(multi-dimensional scaling)图 (Glimma的图是有动态效果的,很炫酷)
# Glimma 提供的绘MDS图函数
glMDSPlot(lcpm, labels=paste(group, lane, sep="_"), groups=x$samples[,c(2,5)], launch=FALSE)


3. 差异表达分析

  • 首先设置好分组矩阵
# First,建立分组信息
design <- model.matrix(~0+group+lane) # 设置分组矩阵
colnames(design) <- gsub("group", "", colnames(design)) # 去掉列名中的group
design
  • 添加比对信息
# Second,use makeContrasts function 建立比较信息
contr.matrix <- makeContrasts(BasalvsLP = Basal-LP, # Basal 和 LP 比较BasalvsML = Basal - ML, # Basal 和 ML 比较LPvsML = LP - ML, # LP 和 ML 比较levels = colnames(design))
contr.matrix

3.1 差异表达分析

绘制 log-CPM均值与方差关系的图像,具有高生物学变异的实验通常导致更平坦的趋势,其中方差值在高表达值处稳定。具有低生物变异的实验倾向于导致急剧下降的趋势

  • 使用voom函数 将count reads 转换为log-CPM值,并估计它的均值差异关系,从而为之后线性建模做准备

Transform count data to log2-counts per million (logCPM), estimate the mean-variance relationship and use this to compute appropriate observation-level weights. The data are then ready for linear modelling.

par(mfrow=c(1,2))
v <- voom(x, design, plot=TRUE) # Transform RNA-Seq Data Ready for Linear Modelling
v
  • 拟合线性模型&差异表达分析
vfit <- lmFit(v, design) # Fit linear model for each gene given a series of arrays
vfit <- contrasts.fit(vfit, contrasts=contr.matrix)
efit <- eBayes(vfit)
plotSA(efit, main="Final model: Mean-variance trend")
  • 查看基因分布结果
summary(decideTests(efit))
  • 使用 treat 从大量的差异基因中,选出更有意义的基因
# treat 类似于 ebayes
# When the number of DE genes is large,
# treat is often useful for giving preference to
# larger fold-changes and for prioritizing genes
# that are biologically important
tfit <- treat(vfit, lfc=1)
dt <- decideTests(tfit) # 使用decideTest 提取多重比较的差异基因结果
> head(dt)
#        Contrasts
#         BasalvsLP BasalvsML LPvsML
#  497097         1         1      0
#  27395          0         0      0
#  18777          0         0      0
#  21399          0         0      0
#  58175         -1        -1      0
#  108664         0         0      0
summary(dt)
#>        BasalvsLP BasalvsML LPvsML
#> Down        1417      1512    203
#> NotSig     11030     10895  13780
#> Up          1718      1758    182

dt 中的0代表非差异基因,1代表上调基因,-1代表下调基因

3.2 绘制Venn图

## Fourth, plot Venn
# 取出BasalvsLP和BasalvsML 这两组比较中的共同差异基因
de.common <- which(dt[,1]!=0 & dt[,2]!=0)
# 查看共同差异基因数目
length(de.common)
# 查看前20个基因symbol
head(tfit$genes$SYMBOL[de.common], n=20)
# 绘制Venn图
vennDiagram(dt[,1:2], circle.col=c("turquoise", "salmon"))

3.3 导出差异表达基因的数据

## Fifth , output result
write.fit(tfit, dt, file="results.txt")

3.4 Examining individual DE genes from top to bottom

# 使用 topTreat() 将差异基因按padj,logFC,log-CPM,t值 从小到大排序
# n=Inf 表示选取所有基因参与排序
basal.vs.lp <- topTreat(tfit, coef=1, n=Inf) # coef在此处代表选取的比对的组别
basal.vs.ml <- topTreat(tfit, coef=2, n=Inf)
head(basal.vs.lp)
head(basal.vs.ml)

4. 差异基因结果可视化

4.1 log-CPM ~ logFC图

## 差异基因结果可视化
# plot MD
plotMD(tfit, column=1, status=dt[,1], main=colnames(tfit)[1], xlim=c(-8,13))
# plot MD using GLimma 这个包绘制出来的是动态的MD图
glMDPlot(tfit, coef=1, status=dt, main=colnames(tfit)[1],side.main="ENTREZID", counts=x$counts, groups=group, launch=FALSE)

4.2 绘制热图

library(gplots)
basal.vs.lp.topgenes <- basal.vs.lp$ENTREZID[1:100]
i <- which(v$genes$ENTREZID %in% basal.vs.lp.topgenes)
mycol <- colorpanel(1000,"blue","white","red")
heatmap.2(v$E[i,], scale="row",labRow=v$genes$SYMBOL[i], labCol=group, col=mycol, trace="none", density.info="none", margin=c(8,6), lhei=c(2,10), dendrogram="column")

  • 热图:basal与LP两个分组中前100个基因DE的log-CPM值的热图。对每个基因(或行)的表达进行了缩放,使平均值为零,标准偏差为1。给定基因表达量较高的样本用红色标记,表达量较低的样本用蓝色标记。浅色和白色代表中等表达水平的基因。采用层次聚类的方法对样本和基因进行重新排序。给出了样本聚类的树状图。

【生信进阶练习1000days】day16~day22-RNA-seq data analysis with limma edgeR and Glimma相关推荐

  1. 生信识图之 点图进阶-3(MA)

    各位亲爱的土豪富婆,承蒙您慧眼识珠大驾光临大Y老师为您准备的小灶课堂. -----以下是日常碎碎念,日理万机的您,可以直接跳到图图图图分割线享用----- 对于"诈尸式"更新,大Y ...

  2. 生信识图之 点图进阶-6(UMAP)

    各位亲爱的土豪富婆,见字如面. -----以下是日常碎碎念,日理万机的您,可以直接跳到图图图图分割线享用----- 春天来啦,又到了--考研计划的时候.大Y老师不是会把咱们公众号的更新陆续同步到知乎上 ...

  3. 生信识图之 点图进阶-4 (PCA下篇)

    各位亲爱的土豪富婆,承蒙您慧眼识珠大驾光临大Y老师为您准备的小灶课堂. 近期有朋友说发现有人抄袭咱们的文章,自标为"原创".对此大Y老师有心理准备,咱们的每一篇文章都是大Y老师仔细 ...

  4. 生信识图 之 点图进阶-1

    各位亲爱的土豪富婆,承蒙您慧眼识珠大驾光临大Y老师为您准备的小灶课堂. -----以下是日常碎碎念,日理万机的您,可以直接跳到图图图图分割线享用----- 大Y老师做生信分析十多年了,在此期间结识很多 ...

  5. 送书《R语言数据分析和可视化》 | 这个为生信学习和生信作图打造的开源R教程真香!!!...

    生物信息学习的正确姿势 NGS系列文章包括NGS基础.在线绘图.转录组分析 (Nature重磅综述|关于RNA-seq你想知道的全在这).ChIP-seq分析 (ChIP-seq基本分析流程).单细胞 ...

  6. 当我们谈论生信的时候我们在谈什么

    生物信息学习的正确姿势 NGS系列文章包括NGS基础.高颜值在线绘图和分析.转录组分析 (Nature重磅综述|关于RNA-seq你想知道的全在这).ChIP-seq分析 (ChIP-seq基本分析流 ...

  7. 易生信极高性价比暑期黑马集训 -- 低至2500每人

    开课背景 生物信息学说起来很好理解,可是对大部分想学习生信的人来说,操作起来却是有些棘手,无有头绪.生信的研究内容主要包括两个方面:首先,需要生物研究者利用实验收集.整理.储存.获取生物学数据:另一方 ...

  8. 生信宝典教程大放送,一站式学习生信技术

    生物信息学包含生物数据分析.数据可视化.重复工作程序化,是生物.医学科研必备的技能之一.生信宝典精心组织生信学习系列教程.生信工具精品教程,通过大量的生信例子.关键的注释.浓缩的语句和录制的视频帮助快 ...

  9. 送书 | 知乎阅读300w+的生信学习指南(更新版)

    先送书 在上周的留言送书活动中,恭喜下面这位读者获得书籍"Oracle高性能系统架构实战大全",请及时与生信宝典编辑(shengxinbaodian)联系. 2020过去三分之一了 ...

  10. 生信数据库ID大总结-想踏入生信大门的你值得拥有

    花了差不多一周写了这个总结 希望对一些小伙伴有帮助 目录 各大生信资源的使用流行程度 生信数据库的霸主-NCBI以及Entrez检索系统 Gene查找好帮手-Entrez Gene数据库 人类基因命名 ...

最新文章

  1. Mysql错误1045解决方法
  2. 【ajax+php】动态展示4级单位(省、市、县、镇)
  3. [RHEL5企业级Linux服务攻略]--第6季 Vsftpd服务全攻略之常规配置
  4. c语言 串口中断服务函数,GCC-AVR 编写中断服务函数的注意事项
  5. 动静分离和前后端分离
  6. c语言上机注意事项,计算机三级(C语言)上机考试题型总结与注意事项(讲解详细)...
  7. python日志模块的封装
  8. 学习总结5 - bootstrap学习记录1__安装
  9. 等待事件之日志等待事件解决的方法
  10. Genaro Network厚积薄发,开创区块链3.0新时代
  11. 8年项目总结:4个G,项目经理必备模板全汇总
  12. PageBarHelper(数字页码条帮助类)
  13. 点餐APP 冲刺三总结
  14. Delphi编程中流的使用
  15. 陈潭:大数据战略实施的实践逻辑与行动框架
  16. softmax 和 log-likelihood(对数似然) 损失函数
  17. 3种解法 - 计算三维形体的表面积
  18. 硬件在环系统环境架构
  19. java 飞翔小鸟源码
  20. UIC564-2 附录4 –阻燃防火测试:火焰的扩散

热门文章

  1. emacs 安装指引
  2. Android API之android.view.View.MeasureSpec
  3. Java Collection Framework View
  4. flash物理引擎应用:FisixObject类(1)
  5. Linux中的Tomcat500异常,Linux处理Tomcat异常的方法
  6. 虚拟机命令里面的光标不动了怎么办_Linux Sever简单笔记(第四堂课)之Linux下的文本编辑器vim(vim中常用的操作方式命令) - 我杨晓东太难了...
  7. nyoj 买水果(组合数求法与分析)
  8. java类中静态变量自增_Java中静态变量(类变量)、实例变量、局部变量和成员变量...
  9. string 操作 java_Java中String类的一些常见问题
  10. 安装blocksci mac出错_你的Mac与Big Sur兼容吗?