2013-12-14 49 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!它运作良好!谢谢!你知道我是否也可以绘制细菌物种名称,也就是我的数据文件中的行吗?所以我可以知道哪些物种驱动每个群集...谢谢! –