if (!requireNamespace("BiocManager", quietly = TRUE))
install.packages("BiocManager")
if (!require("airway", quietly = TRUE)) #使用数据集
BiocManager::install("airway")
if (!require("org.Hs.eg.db", quietly = TRUE))
BiocManager::install("org.Hs.eg.db")
if (!require("clusterProfiler", quietly = TRUE))
BiocManager::install("clusterProfiler")
if (!require("DESeq2", quietly = TRUE)) #差异分析
BiocManager::install("DESeq2")
library(airway)
data(airway)#数据
head(airway)
expr <- assay(airway)
expr[1:5,1:5]
dim(expr)
index1=c(rowSums(expr)>0)
class(index1)
exp2=expr[index1,]
dim(exp2)
#此处操作的目的在于将没有read比对上的基因行删去,简洁数据~
#获取分组信息
group_list <- colData(airway)$dex
group_list
library(DESeq2)
options(stringsAsFactors = F)
#构建dds对象,从表达矩阵countData和样品信息colData构建DESeqDataSet对象
colData <- data.frame(row.names=colnames(expr), group_list=group_list)
colData
dds <- DESeqDataSetFromMatrix(countData = round(exp2,0),colData = colData,design = ~ group_list)
dds
#数据过滤
dds <- dds[rowSums(counts(dds))>1,]#过滤低丰度数据
nrow(dds)
#用vst来标化数据
vsd <- vst(dds, blind = F)
#再用dist这个函数计算样本间的距离
sampleDists <- dist(t(assay(vsd)))
library(ggplot2)
library(factoextra)
res <- hcut(sampleDists, k = 2, stand = TRUE)
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)
dds <- estimateSizeFactors(dds)
normalized_counts <- counts(dds,normalized=T)
dds <- DESeq(dds)
#提取差异分析结果
res <- results(dds)
resultsNames(dds)
res=results(dds,contrast=c("group_list","trt","untrt"))
plotMA(res,ylim=c(-2,2))
names(res)
用summary这个函数,可以看到差异分析的结果,高表达和低表达的比例。低丰度基因所占的比例。
plotMA(res,ylim=c(-2,2))
DEG1=as.data.frame(res)
write.csv(x=DEG1,file="res.csv")
MA-plot上的点是每一个基因。横坐标是标准化后的counts平均值,纵坐标是log后的变化值。蓝色的点是p.adjust的值小于0.1的基因,由counts函数中的alpha 参数指定。 我们发现在左侧,有很多counts很小的基因,发生了很大的变化,但是没有明显意义。类似于从(1,3,9)变成了(20,12,3)他们的counts很小,波动性很大,对logFC产生了很大的影响。 GSEA分析中,排序就是按照logFC来进行的。按照这个结果往下做,GSEA那里,富集不到任何条目。
那就需要矫正。用的函数是lfcShrink
这一步,对于依赖logFC变化值的分析,很重要,比如GSEA分析。我们画一个MAplot图,
resultsNames(dds)
dd1 <- lfcShrink(dds, coef="group_list_untrt_vs_trt", type="apeglm")
plotMA(dd1,ylim=c(-2,2))
这样,原先那些波动很大的基因,就被矫正了。而此时有LogFC以蓝色的点为主。
names(dd1)
与res相比少了"stat"一列。这一步只会对LFC的值产生影响,p值是没有改变的,不会改变显著差异的基因总数。
res<-dd1
resOrdered=res[order(res$pvalue),] #order函数是给出从小到大排序后的位置(默认升序)
sum(res$padj<0.1, na.rm=TRUE) # na.rm 为remove na值,否则会影响统计量
sum(res$pvalue<0.05, na.rm=TRUE)
sum(!is.na(res$pvalue))
resSig=subset(resOrdered, padj < 0.1 & abs(log2FoldChange) > 1)
dim(resSig)
save(resSig,file="resSig.Rdata")
load(file="resSig.Rdata")
DEG2=as.data.frame(resSig)
write.csv(x=resSig, file = "results.csv")
library(pheatmap)
choose_gene=head(rownames(DEG2),50)
#根据DEG2结果,提取目标基因名
choose_matrix=exp2[choose_gene,]
choose_matrix=t(scale(t(choose_matrix)))
一般绘制热图,都需要对数据进行归一化处理。这里用到了t()转置函数的原因是因为基因表达矩阵表中观测为基因,变量为样本。而scale()归一化函数是针对每一列单独处理的。因为每一个基因的本身情况各不相同,而且我们的目的是基于实验组与对照组的比较来研究基因表达变化,所以需要转置下表达矩阵(观测为样本,变量为基因),然后再进行对每一列的归一化处理;最后再进行一次转置,即得到下图结果。
pheatmap(choose_matrix,filename = 'DEG_top50_heatmap.png')
DEG1=na.omit(DEG1)
logFC_cutoff=with(DEG1,mean(abs(log2FoldChange))+2*sd(abs(log2FoldChange)))
logFC_cutoff
2^logFC_cutoff
DEG1$change=as.factor(ifelse(DEG1$pvalue<0.05 & abs(DEG1$log2FoldChange)>logFC_cutoff,
ifelse(DEG1$log2FoldChange>logFC_cutoff,'UP','DOWN'),'NOT'))
this_tile=paste('Cutoff for logFC is ',round(logFC_cutoff,3),
'\nThe number of up gene is ',nrow(DEG1[DEG1$change=='UP',]),
'\nThe number of down gene is ',nrow(DEG1[DEG1$change=='DOWN',]))
#其中\n为换行符
library(ggplot2)
g=ggplot(data=DEG1,
aes(x=log2FoldChange,y=-log10(pvalue), #这里将pvalue取负对数
color=change)) +
geom_point(alpha=0.4,size=1.75) + #绘制点图
theme_set(theme_set(theme_bw(base_size=20))) +
xlab("log2 fold change")+ylab("-log10 pvalue") + #轴标签
ggtitle(this_tile)+theme(plot.title=element_text(size=15,hjust=0.5)) +
scale_color_manual(values=c('blue','black','red')) #设定颜色
ggsave(g,filename='volcanoo.png')
#再把差异分析的结果转化成data.frame的格式
library(dplyr)
library(tibble)
res <- DEG2 %>%
data.frame() %>%
rownames_to_column("gene_id")
res
#基因ID转换
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")
head(res)
这里GSEA分析是用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)
head(geneList)
#完成KEGG的GSEA分析
library(clusterProfiler)
gseaKEGG <- gseKEGG(geneList = geneList,
organism = 'hsa',
nPerm = 1000,
minGSSize = 10,
pvalueCutoff = 0.9,
verbose = FALSE)
head(gseaKEGG)[,1:6]
gseaKEGG$Description
library(ggplot2)
dotplot(gseaKEGG,showCategory=12,split=".sign")+facet_grid(~.sign)
gseaKEGG_results <- gseaKEGG@result
gseaKEGG_results
这时候,我们看到有一些通路是被激活的,有一些通路是被抑制的。比如Pathways in cancer是被抑制的,我们可以选取单个通路来作图。 把富集的结果转换成data.frame,找到Pathways in cancer的通路ID是hsa05200.
library(enrichplot)
pathway.id = "hsa05200"
gseaplot2(gseaKEGG,
color = "red",
geneSetID = pathway.id,
pvalue_table = T)
比如Calcium signaling pathway不是被抑制的,我们可以选取单个通路来作图。 把富集的结果转换成data.frame,找到Calcium signaling pathway的通路ID是hsa04020.
library(enrichplot)
pathway.id = "hsa04020"
gseaplot2(gseaKEGG,
color = "red",
geneSetID = pathway.id,
pvalue_table = T)