求和2个距离矩阵得到第三个“整体”距离矩阵(生态背景)

时间:2014-01-24 12:39:16

标签: r matrix distance centroid vegan

我是生态学家,主要使用纯素R包。

我有2个矩阵(样本x丰度)(见下面的数据):

  
    

矩阵1 / nrow = 6replicates * 24sites,ncol = 15种丰度(鱼)     矩阵2 / nrow = 3replicates * 24sites,ncol = 10种丰度(无脊椎动物)

  

两个矩阵中的站点相同。我想在两对网站之间得到整体的bray-curtis不同(考虑两个矩阵)。我看到两个选项:

选项1,平均重复(在场地规模)鱼类和大型无脊椎动物丰度,cbind两个平均丰度矩阵(nrow = 24sites,ncol = 15 + 10平均丰度)和计算bray-curtis。

选项2,对于每个组合,计算站点对之间的bray-curtis不相似性,计算站点质心之间的距离。然后总结2个距离矩阵。

如果我不清楚,我在下面的R代码中完成了这两项操作。

请您告诉我选项2是否正确且比选项1更合适。

提前谢谢。

皮尔

这里是R代码示例

生成数据

library(plyr);library(vegan)

#assemblage 1: 15 fish species, 6 replicates per site
a1.env=data.frame(
  Habitat=paste("H",gl(2,12*6),sep=""),
  Site=paste("S",gl(24,6),sep=""),
  Replicate=rep(paste("R",1:6,sep=""),24))

summary(a1.env)

a1.bio=as.data.frame(replicate(15,rpois(144,sample(1:10,1))))

names(a1.bio)=paste("F",1:15,sep="")

a1.bio[1:72,]=2*a1.bio[1:72,]

#assemblage 2: 10 taxa of macro-invertebrates, 3 replicates per site

a2.env=a1.env[a1.env$Replicate%in%c("R1","R2","R3"),]

summary(a2.env)

a2.bio=as.data.frame(replicate(10,rpois(72,sample(10:100,1))))

names(a2.bio)=paste("I",1:10,sep="")

a2.bio[1:36,]=0.5*a2.bio[1:36,]


#environmental data at the sit scale

env=unique(a1.env[,c("Habitat","Site")])

env=env[order(env$Site),]

选项1,平均丰度和cbind

a1.bio.mean=ddply(cbind(a1.bio,a1.env),.(Habitat,Site),numcolwise(mean))

a1.bio.mean=a1.bio.mean[order(a1.bio.mean$Site),]

a2.bio.mean=ddply(cbind(a2.bio,a2.env),.(Habitat,Site),numcolwise(mean))

a2.bio.mean=a2.bio.mean[order(a2.bio.mean$Site),]

bio.mean=cbind(a1.bio.mean[,-c(1:2)],a2.bio.mean[,-c(1:2)])

dist.mean=vegdist(sqrt(bio.mean),"bray")

选项2,计算质心之间的每个组合距离并总结2个距离矩阵

a1.dist=vegdist(sqrt(a1.bio),"bray")

a1.coord.centroid=betadisper(a1.dist,a1.env$Site)$centroids

a1.dist.centroid=vegdist(a1.coord.centroid,"eucl")

a2.dist=vegdist(sqrt(a2.bio),"bray")

a2.coord.centroid=betadisper(a2.dist,a2.env$Site)$centroids

a2.dist.centroid=vegdist(a2.coord.centroid,"eucl")
  
    
      

使用Gavin Simpson的保险丝()

总结两个距离矩阵     
  
dist.centroid=fuse(a1.dist.centroid,a2.dist.centroid,weights=c(15/25,10/25))
  
    
      

总结两个欧氏距离矩阵(感谢Jari Oksanen校正)

    
  
dist.centroid=sqrt(a1.dist.centroid^2 + a2.dist.centroid^2)

和下面的'coord.centroid'用于进一步的基于距离的分析(它是否正确?)

coord.centroid=cmdscale(dist.centroid,k=23,add=TRUE)

比较选项1和2

pco.mean=cmdscale(vegdist(sqrt(bio.mean),"bray"))

pco.centroid=cmdscale(dist.centroid)

comparison=procrustes(pco.centroid,pco.mean)

protest(pco.centroid,pco.mean)

3 个答案:

答案 0 :(得分:4)

更简单的解决方案是通过对每个矩阵进行加权,灵活地组合两个相异矩阵。权重需要总和为1.对于两个相异矩阵,融合相异矩阵是

d.fused = (w * d.x) + ((1 - w) * d.y)

其中w是数字标量(长度为1的向量)权重。如果您没有理由对其中一个不同点进行加权,请使用w = 0.5

我的功能是在我的模拟包中为您执行此操作; fuse()。来自?fuse的示例是

 train1 <- data.frame(matrix(abs(runif(100)), ncol = 10))
 train2 <- data.frame(matrix(sample(c(0,1), 100, replace = TRUE),
                      ncol = 10))
 rownames(train1) <- rownames(train2) <- LETTERS[1:10]
 colnames(train1) <- colnames(train2) <- as.character(1:10)

 d1 <- vegdist(train1, method = "bray")
 d2 <- vegdist(train2, method = "jaccard")

 dd <- fuse(d1, d2, weights = c(0.6, 0.4))
 dd
 str(dd)

这种想法用于受监督的Kohonen网络(监督的SOM),将多层数据整合到一个分析中。

analogue 素食主义紧密合作,因此并排运行这两个软件包不会有任何问题。

答案 1 :(得分:3)

平均距离的正确性取决于你对这些距离做了什么。在某些应用程序中,您可能会认为它们确实 距离。也就是说,它们满足某些度量属性并且与原始数据具有已定义的关系。组合的差异可能无法满足这些要求。

这个问题与部分Mantel型差异性分析与矩形数据分析的争议有关,这种分析在β多样性研究中真的很热(我的意思是红热)。我们素食主义者为两者提供工具,但我认为在大多数情况下,矩形数据的分析更强大,更强大。对于矩形数据,我指的是正常采样单位乘以物种矩阵。在素食主义者中优选的基于相异性的方法将不相似性映射到矩形形式上。素食主义者的这些方法包括db-RDA(capscale),置换MANOVA(adonis)和组内分散(betadisper)分析。处理不明智问题的方法包括mantelanosimmrppmeandis

相异或距离的平均值通常与原始矩形数据没有明确的对应关系。即:不相似的平均值与数据的平均值不对应。我认为通常情况下,最好是平均或处理数据,然后从转换后的数据中获得不同之处。

如果您想要结合不同点,analogue::fuse()样式方法是最实用的。但是,您应该了解fuse()还将相异矩阵缩放为相等的最大值。如果您在比例0..1中有不相似性度量,这通常是次要问题,除非其中一个数据集更均匀并且与其他数据集的最大差异度更低。在fuse()中,它们都被均衡,因此它不是简单的平均值,而是在量程均衡后进行平均。此外,您必须记住,平均差异通常会破坏几何体,如果您对矩形化数据使用分析方法(素食主义者中为adonisbetadispercapscale),这将非常重要。

最后关于组合不相似性的几何。标度0..1中的不相似指数是A / B类型的分数。只有当分母相等时,才能直接添加两个分数(然后除以得到平均值)。如果忽略这一点并直接平均分数,那么结果将不等于平均数据的相同分数。这就是我破坏几何的意思。一些开放式指数不是分数,可能是累加的。曼哈顿距离是附加的。欧几里德距离是平方差的平方根,它们的正方形是加性的,但不是直接的距离。

我通过展示将两个不相似性加在一起的效果证明了这些事情(平均意味着将结果除以2,或者通过合适的权重)。我把Barro Colorado Island的素食主义者数据分成两个略微不相等的子集。保留数据子集距离的几何图形将得到与完整数据分析相同的结果:

library(vegan) ## data and vegdist
library(analogue) ## fuse
data(BCI)
dim(BCI) ## [1]  50 225
x1 <- BCI[, 1:100]
x2 <- BCI[, 101:225]
## Bray-Curtis and fuse: not additive
plot(vegdist(BCI), fuse(vegdist(x1), vegdist(x2), weights = c(100/225, 125/225)))
## summing distances is straigthforward (they are vectors), but preserving
## their attributes and keeping the dissimilarities needs fuse or some trick
## like below where we make dist structure dtmp to be replaced with the result
dtmp <- dist(BCI) ## dist skeleton with attributes
dtmp[] <- dist(x1, "manhattan") + dist(x2, "manhattan")
## manhattans are additive and can be averaged
plot(dist(BCI, "manhattan"), dtmp)
## Fuse rescales dissimilarities and they are no more additive
dfuse <- fuse(dist(x1, "man"), dist(x2, "man"), weights=c(100/225, 125/225))
plot(dist(BCI, "manhattan"), dfuse)
## Euclidean distances are not additive
dtmp[] <- dist(x1) + dist(x2)
plot(dist(BCI), dtmp)
## ... but squared Euclidean distances are additive
dtmp[] <- sqrt(dist(x1)^2 + dist(x2)^2)
plot(dist(BCI), dtmp)
## dfuse would rescale squared Euclidean distances like Manhattan (not shown)

我上面只考虑过添加,但如果你不能添加,你就无法平均。如果这很重要,那就是品味问题。勇敢的人会平均无法平均的事情,但有些人更胆小,想遵守规则。我宁愿去第二组。

答案 2 :(得分:0)

我喜欢this answer的简单性,但它仅适用于添加2个距离矩阵:

<div class="container">
    <div class="row">
        <div class="col-md-4">
            <div class="well">
                <p>Write Something Here</p>
            </div>
        </div>

        <div class="col-md-4">
            <div class="well">
                <p>Write Something Here</p>
            </div>
        </div>

        <div class="col-md-4">
            <div class="well">
                <p>Write Something Here</p>
            </div>
        </div>
    </div>
</div>

所以我编写了自己的代码片段来组合多个距离矩阵(不仅仅是2个)的数组,并使用标准的R包:

d.fused = (w * d.x) + ((1 - w) * d.y)

您还可以使用与# generate array of distance matrices x <- matrix(rnorm(100), nrow = 5) y <- matrix(rnorm(100), nrow = 5) z <- matrix(rnorm(100), nrow = 5) dst_array <- list(dist(x),dist(y),dist(z)) # create new distance matrix with first element of array dst <- dst_array[[1]] # loop over remaining array elements, add them to distance matrix for (jj in 2:length(dst_array)){ dst <- dst + dst_array[[jj]] } 大小相似的矢量来定义缩放因子

dst_array