2013-12-14 47 views
1

我試圖用ade4包的s.class函數來構建一個pca圖。 我有一個數據集,其中包含不同樣本(列)中細菌種類(行)的丰度。我需要執行一些統計測試,並獲得我的樣本的一些集羣,以在PCA中表示它們。 我跑了這一點,下面就一紙公佈的腳本:添加樣品名到PCA繪製s.class

>data=read.table("L4.txt",header=T,row.names=1,dec=".",sep="\t") 

>data=data[-1,] 

>library(cluster) 

> JSD <- function(x,y) sqrt(0.5 * KLD(x, (x+y)/2) + 0.5 * KLD(y, (x+y)/2)) 

> KLD <- function(x,y) sum(x * log(x/y)) 

> dist.JSD <- function(inMatrix, pseudocount=0.000001, ...) { 
    KLD <- function(x,y) sum(x *log(x/y)) 
    JSD<- function(x,y) sqrt(0.5 * KLD(x, (x+y)/2) + 0.5 * KLD(y, (x+y)/2)) 
    matrixColSize <- length(colnames(inMatrix)) 
    matrixRowSize <- length(rownames(inMatrix)) 
    colnames <- colnames(inMatrix) 
    resultsMatrix <- matrix(0, matrixColSize, matrixColSize) 

    inMatrix = apply(inMatrix,1:2,function(x) ifelse (x==0,pseudocount,x)) 

    for(i in 1:matrixColSize) { 
    for(j in 1:matrixColSize) { 
    resultsMatrix[i,j]=JSD(as.vector(inMatrix[,i]), 
    as.vector(inMatrix[,j])) 
    } 
    } 
colnames -> colnames(resultsMatrix) -> rownames(resultsMatrix) 
as.dist(resultsMatrix)->resultsMatrix 
attr(resultsMatrix, "method") <- "dist" 
return(resultsMatrix) 
} 

>data.dist=dist.JSD(data) 

>pam.clustering=function(x,k) { # x is a distance matrix and k the number of clusters 
         require(cluster) 
         cluster = as.vector(pam(as.dist(x), k, diss=TRUE)$clustering) 
         return(cluster) 
        } 

>data.cluster=pam.clustering(data.dist,k=3) 

>library(ade4) 

>obs.pca=dudi.pca(data.frame(t(data)), scannf=F, nf=10) 

>obs.bet=bca(obs.pca, fac=as.factor(data.cluster), scannf=F, nf=k-1) 

>s.class(obs.bet$ls, fac=as.factor(data.cluster), grid=F) 

我的數據是這樣的:

     06.TO.VG 21.TO.V 02.TO.VG 41.TO.VG 30.TO.V 
Actinomycetaceae  0.000000000 0.00000000 0.000000000 0.000000000 0.000000000 
Bifidobacteriaceae 0.019108280 0.00000000 0.000000000 0.000787092 0.000000000 
Coriobacteriaceae 0.060006705 0.01490985 0.002632445 0.003148367 0.008313539 
Propionibacteriaceae 0.000000000 0.00000000 0.000000000 0.000000000 0.000000000 
Bacteroidetes  0.000000000 0.00000000 0.000000000 0.000000000 0.000000000 
Bacteroidia   0.157224271 0.02288488 0.010529780 0.002361276 0.005938242 
Bacteroidaceae  0.072745558 0.01178918 0.028956894 0.059031877 0.097387173 
Porphyromonadaceae 0.004022796 0.01005548 0.147745969 0.026367572 0.038004751 
Prevotellaceae  0.083808247 0.30374480 0.586048042 0.487603306 0.290973872 
Rikenellaceae  0.025477707 0.07836338 0.011187891 0.003935458 0.004750594 

我有我一直在尋找的情節,但目前還沒有樣本名,所以我不知道哪些樣本聚集在一起。 我還試圖建立一個矢量包含我的數據的列名(sampleID),然後把它傳遞給標籤選項s.class

> s.class(obs.bet$ls, fac=as.factor(data.cluster), grid=F, label=labs) 

,但我還沒有他們....

有沒有辦法讓s.class函數得到這個?

感謝 弗朗西斯

+1

請提供可再現的例子。 –

+0

在你的代碼的倒數第二行中,你有'nf = k-1',但你永遠不會定義'k',所以你的代碼不會運行。我假設'k = 3',但你應該編輯你的問題。 – jlhoward

回答

1

沒有辦法(直接)標籤中使用s.class(...)各個點。正如您所指出的那樣,label=參數標記了聚類(點類),而不是單個點。

然而,由於s.class(...)使用在基礎R圖示程序,你可以簡單地添加一個調用text(...)

labs <- rownames(obs.bet$ls) 
s.class(obs.bet$ls,fac=factor(data.cluster),grid=F, xlim=c(-4,4)) 
text(obs.bet$ls,labels=labs,adj=c(-.1,-.8),cex=0.8) 

還有的xlim=adj=的調整相當數量,並cex=使標籤可讀,但它確實有效。

這裏有兩個備選方案可能會有所幫助(希望)。

clusplot(obs.bet$ls,data.cluster,labels=2) 

產生這個,這是非常類似於你的情節,與點標記。

另一種替代方法使用ggplot

library(ggplot2) 
gg <- cbind(obs.bet$ls,cluster=data.cluster) 
gg <- cbind(sample=rownames(gg),gg) 
ggplot(gg, aes(x=CS1, y=CS2)) + 
    geom_point(aes(color=factor(cluster)),size=5) + 
    geom_text(aes(label=sample),hjust=-0.2) + 
    geom_hline(yintercept=0,linetype=2) + 
    geom_vline(xintercept=0,linetype=2) + 
    scale_color_discrete(name="Cluster") + 
    xlim(-4,4) 

+0

這真的接近我所需要的......只是一個問題:爲什麼形成的簇(在這兩種情況下)與通過s.class創建的簇不同?有沒有辦法添加行名稱(我的細菌物種)?至少最豐富的....所以我可以知道哪些物種的不同...... –

+1

實際上,我說得太快了:你*可以*用's.class(...)調用「文本(...)」。看到我上面的編輯。在替代方案中,兩者都與您的集羣相同。 'clusplot(...)'版本反轉PC1和PC2的符號;我不知道爲什麼。 'ggplot(...)'版本與您的相同。 – jlhoward

+0

嗨jihoward!它運作良好!謝謝!你知道我是否也可以繪製細菌物種名稱,也就是我的數據文件中的行嗎?所以我可以知道哪些物種驅動每個羣集...謝謝! –