主成分分析-PCA图的优化(R语言)

R语言的主成分分析(PCA)详解和带聚类的PCA图绘制

最近有个老师在整理文章数据,由于分组较多,想展示PCA图,说明不同分组的差异,公司默认给出的PCA图比较朴素,想做的好看一些,怎么来做呢。自然难不倒小编,以下几种展示方法,让文章图表更炫酷(前提是样品多,分组多,如果2组3重复,是不够的)。
在RNA-seq中,主成分分析(PCA)是最常见的多元数据分析类型之一。基因表达定量后获得了各样本中所有基因的表达值信息,随后我们通常会期望比较样本之间在基因表达值的整体相似性或者差异程度。基因数量成千上万,肯定不能对每个基因的表达都作个比较,这时候就要用到“降维”算法,PCA分析因此派上用场。PCA设法将N维(N=基因数量)的表达矩阵降维成只有少数几个主成分的形式,这几个主成分就可以代表所有基因的整体表达格局,进而据此描述样本差异。

例如这是文献中的一些PCA分析图。

PCA图中,如果两个样本间整体基因表达值更为相似,那么它们的距离就接近;反之若整体基因表达值差异很大,则它们的距离就会更远。据此,我们就可以从中评估,不同组间样本的基因表达是否相差更为明显,组内样本的基因表达是否均匀或一致性较高,哪些处理组之间引起了相似的基因表达变化趋势,等等。

本篇教程就让我们来学习如何使用R语言进行PCA分析。示例数据和R代码等,可添加微信公众号”获取。

1 示例数据

“PCA.data.txt”为基因表达值矩阵。其中第一列“ensembl_id”为基因名称,这里以ensembl id作为指代;其余各列为各样本的名称,记录了RNA-seq获得的各基因在各样本中的表达值信息。

“group.txt”则为样本分组文件,记录了样本所属的不同分组。对于示例数据而言,共包含两组,即对照组(control)和处理组(treat),每组各5个样本。

接下来,就以基因表达值矩阵文件作为输入,展示如何进行PCA分析的一般过程。

2 R语言执行主成分分析(PCA)

首先,需要根据基因表达值进行样本间的PCA分析,确定样本在PCA图中的位置。

将上述基因表达值矩阵读入到R中进行计算。R语言中能够执行PCA分析的方法有很多,不过它们的算法都是统一的,随便使用任何一个R包就可以,例如这里选择使用FactoMineR包中的PCA方法。

#读取基因表达值矩阵
#推荐使用 log 转化后的基因表达值,降低不同基因表达水平数量级相差过大的问题
gene <- read.delim('PCA.data.txt', row.names = 1, sep = '\t')
​
#将基因表达值矩阵作个转置,使行为样本,列为基因
gene <- t(gene)
​
#我们使用 FactoMineR 包中的方法,实现 PCA 分析和聚类添加
library(FactoMineR)
​
#样本中基因表达值的 PCA 分析
gene.pca <- PCA(gene, ncp = 2, scale.unit = TRUE, graph = FALSE)
plot(gene.pca)  #PCA 简图

这样,PCA分析结果就初步得到了。从结果中我们可以看出,处理组和对照组的基因表达值整体差异还是非常明显的,因为两组的样本能够在PCA图中区分很开。

3 可视化PCA图

上一步获得了PCA分析结果,并观察到明显的组间差异。但如果想把结果往文章中摆放,上图肯定是不行的,起码要让它好看一些。因此接下来,继续展示如何绘制一个好看的PCA图。

例如这里选择使用ggplot2包美化PCA图,它是一款非常出名的R语言作图包。不过在使用ggplot2作图之前,需要事先在上述PCA分析结果中将关键信息提取出,例如样本点在PCA图中的位置信息,以及PCA轴的贡献度等。

#提取样本在 PCA 前两轴中的坐标
pca_sample <- data.frame(gene.pca$ind$coord[ ,1:2])
head(pca_sample)
​
#提取 PCA 前两轴的贡献度
pca_eig1 <- round(gene.pca$eig[1,2], 2)
pca_eig2 <- round(gene.pca$eig[2,2],2 )

随后,加载ggplot2作图包,根据提取出的样本位置坐标以及PCA轴的贡献度数值,绘制二维散点图表示PCA结果。在同时,我们也将样本分组文件读取到R中用于指定样本的分组信息,以在图中使用不同的颜色表示不同组的样本。

FactoMineR包也能用于绘制这类统计图,以上述添加层次聚类的PCA继续。

#读取并合并样本分组信息
group <- read.delim('group.txt', row.names = 1, sep = '\t', check.names = FALSE)
group <- group[rownames(pca_sample), ]
pca_sample <- cbind(pca_sample, group)
​
pca_sample$samples <- rownames(pca_sample)
head(pca_sample)  #作图数据中包含了样本坐标和分组信息
​
#ggplot2 绘制二维散点图
library(ggplot2)
​
p <- ggplot(data = pca_sample, aes(x = Dim.1, y = Dim.2)) +
geom_point(aes(color = group), size = 3) +  #根据样本坐标绘制二维散点图
scale_color_manual(values = c('orange', 'purple')) +  #自定义颜色
theme(panel.grid = element_blank(), panel.background = element_rect(color = 'black', fill = 'transparent'), 
    legend.key = element_rect(fill = 'transparent')) +  #去除背景和网格线
labs(x =  paste('PCA1:', pca_eig1, '%'), y = paste('PCA2:', pca_eig2, '%'), color = '')  #将 PCA 轴贡献度添加到坐标轴标题中
​
p
#标识样本名称,使用 ggplot2 的拓展包 ggrepel 来完成
library(ggrepel)
​
p <- p + 
geom_text_repel(aes(label = samples), size = 3, show.legend = FALSE, 
    box.padding = unit(0.5, 'lines'))

p

样式是不是比最初的好看很多?

再一次,能够很清晰地从图中观察到,处理组和对照组的基因表达值整体差异是非常明显的,因为两组的样本能够在PCA图中区分很开。

4 可选添加样本聚类

继续,可以选择在PCA图中展示“样本聚类”。方法大致分为两种,一种是通过样本点的坐标拟合置信椭圆,另一种是直接将各组的边界区样本点以多边形连接。不过需要注意的是,这种方法并不是真正的聚类,而是一种用于在作图时更好地区分不同组的方法。

#添加 95% 置信椭圆,可用于表示对象分类,但只能适用于各组样本数大于 5 个的情况
p + stat_ellipse(aes(color = group), level = 0.95, show.legend = FALSE)
​
p + stat_ellipse(aes(fill = group), geom = 'polygon', level = 0.95, alpha = 0.1, show.legend = FALSE) +
scale_fill_manual(values = c('orange', 'purple'))
​
#多边形连接同类别对象边界的样式,适用于各组样本数大于 3 个的情况
library(plyr)
cluster_border <- ddply(pca_sample, 'group', function(df) df[chull(df[[1]], df[[2]]), ])
​
p + geom_polygon(data = cluster_border, aes(color = group), fill = NA, show.legend = FALSE)
​
p + geom_polygon(data = cluster_border, aes(fill = group), alpha = 0.2, show.legend = FALSE) +
scale_fill_manual(values = c('orange', 'purple'))

这样,一个完整的PCA分析过程就完整地展示出来了,包括输入文件准备,如何计算PCA,以及PCA图的可视化等,还是非常简单的对吗?

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容