R語言實現PCOA分析
- 2019 年 12 月 19 日
- 筆記
大家對主成分分析(principal components analysis, PCA) 都很熟悉,但是今天我們來介紹下主坐標分析(principal coordinate analysis, PCoA)。那麼這兩個差了個o字母具體有什麼區別?首先PCA是常用的降維演算法;利用線性變換,將數據變換到一個新的坐標系統中;然後再利用降維的思想,使得任何數據投影的第一大方差在第一個坐標(稱為第一主成分)上,第二大方差在第二個坐標(第二主成分)上。這種降維的思想首先減少數據集的維數,同時還保持數據集的對方差貢獻最大的特徵,最終使數據直觀呈現在二維坐標系。PCoA主要是探索數據相似度或者相異度可視化方法。可呈現研究數據相似性或差異性的可視化坐標,是一種非約束性的數據降維分析方法,可用來研究樣本群落組成的相似性或相異性。其實通俗的講,PCA主要是基於原始數據矩陣的降維;PCoA主要是基於樣本的原始數據計算出來的距離矩陣的降維。如果樣本數目比較多,而物種數目比較少,那肯定首選PCA;如果樣本數目比較少,而物種數目比較多,那肯定首選PCoA。
接下來我們看下在R中如何去實現,首先安裝ape包和vegan包,聯合使用才能達到最終的目的。包的安裝我們就不贅述了,其在CRAN平台,直接install.packages()。
首先是數據的導入,我們利用vegan自帶的數據dune。具體的數據集的構成大家可以直接在包的資訊中去看。接下來我們首先基於dune數據構造距離矩陣,需要用到的函數vegdist。
vegdist(x, method="bray",binary=FALSE, diag=FALSE, upper=FALSE,
na.rm = FALSE, ...)
其中主要的參數:
Method 支援了目前大部分的距離計算函數。"manhattan", "euclidean", "canberra","clark", "bray", "kulczynski","jaccard", "gower", "altGower","morisita", "horn", "mountford", "raup","binomial", "chao", "cao" or"mahalanobis"。
Diag 是否顯示對角線的值。
Upper 是否顯示對角線以上的值
library(vegan) data(dune) data(dune.env) dune.dist <- vegdist(dune)#構造距離矩陣。

接下來就是利用ape中的pcoa函數獲取PCOA分析結果。當然也可以應用我們R自帶的函數cmdscale。
pcoa(D, correction="none",rn=NULL)
其中主要參數:
D 不用多說就是距離矩陣
Correction 主要指需不需進行校正。
Rn 主要是指的每個樣本的名稱標籤,可以進行自定義
接下來我們看下實例:
res=pcoa(dune.dist,correction="none") head(res$value)

其中主要的值是特徵值的一些相關的轉換的值。
head(res$vectors)

其中主要是和PCA中主成分類似的柱坐標的值,進行了排序展示,一般選擇前兩個繪製二維可視散點圖。
biplot(res)#可視化PCOA 的結果

為了進一步完善我們的可靠性,我們還可以利用vegan中的ANOSIM相似性分析是一種非參數檢驗,用來檢驗組間(兩組或多組)差異是否顯著大於組內差異,從而判斷分組是否有意義。
anosim(x, grouping, permutations = 999, distance = "bray", strata = NULL, parallel = getOption("mc.cores"))其中的參數我們不再贅述,直接看下實例:
dune.ano <- with(dune.env, anosim(dune.dist, Management)) summary(dune.ano)

plot(dune.ano)

至此,我們的PCOA的分析過程可以實現,那麼如何優化我們輸出的可視化影像,我們需要用到ggplot2這個包可以對我們的值進行更加友好的可視化。直接看實例:
library(ggplot2) P= dune.ano$signif R=round( dune.ano$statistic,3) data=res$vectors[,1:2] data=data.frame(data) colnames(data)=c('x','y') eig=as.numeric(res$value[,1]) type=dune.env$Management data=cbind(data,type) p =ggplot(data, aes(x=x, y=y, color=type))+ geom_point(alpha=.7, size=2) + labs(x=paste("PCoA 1 (",format(100* eig[1] / sum(eig), digits=4), "%)", sep=""), y=paste("PCoA 2 (", format(100*eig[2] / sum(eig), digits=4), "%)", sep=""), title="PCoA") p +theme_classic()+stat_ellipse(type ="t", linetype = 2)+ annotate("text",x=0.004,y=-0.15,parse=TRUE,size=4,label=paste('R:',R),family="serif",fontface="italic",colour="darkred")+ annotate("text",x=0,y=-0.17,parse=TRUE,size=4,label=paste('p:',P),family="serif",fontface="italic",colour="darkred")

