Loading...
墨滴

fafu生信小蘑菇

2021/05/11  阅读:43  主题:自定义主题1

聚类分析5—物种集合-数量生态学:R语言的应用

数量生态学:R语言的应用 第四章 聚类分析5—物种集合

在这之前我们学习了聚类分析的基本概念、几种计算层次聚类的方法、进一步解读和比较层次聚类结果以及非层次聚类,也学习了基于环境数据来进行聚类分析。本次呢,我们主要学习如何识别数据集内物种关联的方法。

本次的内容,主要分为四个部分:

  1. 组内数据简单统计
  2. Kendall共性系数(W)
  3. 基于有-无数据的物种集合
  4. 物种共生网络

1. 加载所需的数据和包以及数据预处理

1.1 加载所需的包和数据

setwd("E:/Rstudio_working/lai jian shan/DATA/Data")
#加载包和数据
library(ade4)
library(adespatial)
library(vegan)
library(gclus)
library(cluster)
library(pvclust)
library(RColorBrewer)
library(labdsv)
library(rioja)
library(indicspecies)
library(mvpart)
library(MVPARTwrap)
library(dendextend)
library(vegclust)
library(colorspace)
library(agricolae)
library(picante)

#加载函数
source("drawmap.R")
source("drawmap3.R")
source("hcoplot.R")
source("test.a.R")
source("coldiss.R")
source("bartlett.perm.R")
source("boxplerk.R")
source("boxplert.R")

#从聚类结果获得二元差异矩阵的函数
grpdist <- function(X)
{
  require(cluster)
  gr <- as.data.frame(as.factor(X))
  distgr <- daisy(gr,"gower")
  distgr
}

#导入Doubs数据
load("Doubs.RData")
#剔除无物种数据的样方8
spe <- spe[-8,]
env <- env[-8,]
spa <- spa[-8,]
latlong <- latlong[-8,] #经纬度

1.2数据预处理

#先计算样方之间的弦距离矩阵
spe.norm <- decostand(spe,"normalize")
spe.ch <- vegdist(spe.norm,"euc")

# 计算Ward最小方差聚类
spe.ch.ward <- hclust(spe.ch, method="ward.D2")

#Ward聚类同表型相关
spe.ch.ward.coph <- cophenetic(spe.ch.ward)
cor(spe.ch, spe.ch.ward.coph)

# 设定聚类组的数量
k <- 4  
# 根据上面4个融合水平值图,可以观察到分4组水平在所有图里有小的跳跃
# 裁剪聚类树

spech.ward.g <- cutree(spe.ch.ward, k=k)
# 计算Ward聚类获得4组中各个物种的平均多度矩阵
groups <- as.factor(spech.ward.g)
spe.means <- matrix(0, ncol(spe), length(levels(groups)))
row.names(spe.means) <- colnames(spe)
for (i in 1:ncol(spe)) {
  spe.means[i, ] <- tapply(spe.norm[, i], spech.ward.g, mean)
}
# 平均物种多度矩阵作为初始点
startpoints <- t(spe.means)
# 基于初始点的k-均值划分
spe.kmeans2 <- kmeans(spe.norm, centers = startpoints)

# 最终分组的轮廓宽度值图
spech.ward.gk <- spe.kmeans2$cluster
dev.new(
  title = "轮廓-优化分区",
  noRStudioGD = TRUE
)
par(mfrow = c(11))
k <- 4
sil <- silhouette(spech.ward.gk, spe.ch)
rownames(sil) <- row.names(spe)
plot(sil,
     main = "轮廓宽度值 - Ward & k均值",
     cex.names = 0.8,
     col = 2:(k + 1))


说明:这里数据处理方法,都是在聚类分析这一章学过的,不明白的同学,可以在回头去看看

这里用到的数据是非层次距离中得到的spech.ward.gk

2. 组内数据简单统计

之前我们也讲过某些定义广义的物种集合的方式:对聚类分析获得的样方组进行简单统计(比如平均多度),寻找每组样方内数量多、频度高或具有代表性的物种。比如下面:

#最优化Ward聚类分4组内每种物种平均多度
groups <- as.factor(spech.ward.gk)
spe.means <- matrix(0, ncol(spe), length(levels(groups)))
row.names(spe.means) <- colnames(spe)
for (i in 1:ncol(spe)) {
  spe.means[i, ] <- tapply(spe[, i], spech.ward.gk, mean)
}
# K-均值样方聚类簇平均多度
group1 <- round(sort(spe.means[, 1], decreasing = TRUE), 2)
group2 <- round(sort(spe.means[, 2], decreasing = TRUE), 2)
group3 <- round(sort(spe.means[, 3], decreasing = TRUE), 2)
group4 <- round(sort(spe.means[, 4], decreasing = TRUE), 2)
# 显示多度大于平均值的物种
group1.domin <- which(group1 > mean(group1))
group1
group1.domin
#... 对其他组进行相同分析
group2.domin <- which(group2 > mean(group2))
group2
group3.domin <- which(group3 > mean(group3))
group3
group4.domin <- which(group4 > mean(group4))
group4
group1.domin
group2.domin
group3.domin
group4.domin
显示多度大于平均值的物种
显示多度大于平均值的物种

3. Kendall共性系数(W)

Kendall共性系数与置换检验结合可以确认多度数据表格内物种集合(此方法不适用于物种有-无的数据):“首先进行所有物种独立性的总体检验,如果零假设被拒绝,则需要对物种进行分组,在每组内使用置换检验去分析每个物种对总体统计量贡献的显著性”。在这个过程中,物种之间关联的计算无需预先参考任何已知或从其他数据(例如环境因子)获得的分组情况,这个方法的目标是找到最全面的物种集合,即利用最少组数并尽可能让显著正相关物种分在同一个组

Kendall.W程序包可以做上面的计算,当判断的数量[=物种数]很少时,Kendall共性检验最合适,因为此时用传统的卡方检验过于保守,此外置换检验有准确的Ⅰ类错误值;因此置换检验的效果可能更好。**Kendall.global( )**函数也包含参数的F-检验,F-检验也可以避免卡方检验过于保守的问题,而并具有准确的Ⅰ类错误值。

使用K-均值法将这些物种分成几组,然后运行全局检验(Kendall.global( ))识别是否所有物种组显著关联。如果显著关联,将对每个物种进行后验概率检验(Kendall.post( )),验证同一组的物种是否具有共性?

# Kendall共性系数(W)
#物种数据转化和矩阵转置
spe.hel <- decostand(spe, "hellinger")
spe.std <- decostand(spe.hel, "standardize")
spe.t <- t(spe.std)

# 运行包含所有物种的Kendall共性分析首次检验
(spe.kendall.global1 <- kendall.global(spe.hel))
包含所有物种的Kendall共性分析首次检验
包含所有物种的Kendall共性分析首次检验

共性不一致的零假设被拒绝。所以我们需要先进性分组,再进行组内Kendall分析

# 物质K-均值划分
spe.t.kmeans.casc <- cascadeKM(
  spe.t,
  inf.gr = 2,
  sup.gr = 8,
  iter = 100,
  criterion = "calinski"
)
dev.new(
  title = "Kmeans on species",
  width = 10,
  height = 6,
  noRStudioGD = TRUE
)
plot(spe.t.kmeans.casc, sortg = TRUE)

鱼类数据在2组到8组条件下每种鱼归属的K-均值划分图
鱼类数据在2组到8组条件下每种鱼归属的K-均值划分图

Calinski-Harabasz 准则指出分2组是最佳方案,如果分更多的组,可能有些组只有一个物种,分两组的时候,第1个组有6个物种,第2个组有21个物种,在这里分3组或者4组也是合适的,因为至少每组有不少于三个物种。

# 分两组的情况刚好是在object$partition里面的第一列
(clusters2 <- spe.t.kmeans.casc$partition[, 1])

# 分成3组或4组
(clusters3 <- spe.t.kmeans.casc$partition[, 2]) 
(clusters4 <- spe.t.kmeans.casc$partition[, 3])
image-20210510220719968
image-20210510220719968

我们现在将分两组来研究物种的划分。让我们执行每组全局Kendall W检验,通过调用Kendall.global函数来完成。

# 全局Kendall W检验
(spe.kendall.global2 <- kendall.global(spe.hel, clusters2))
image-20210510220824532
image-20210510220824532

我们可以看到到已经矫正的置换检验P值。如果所有的P值等于或者小于0.05,可以认为所有组全局显著,即总体上说,每一组内所包含的物种具有共性;但是这不意味着所有的物种都具有共性,但至少是一部分物种具有共性。如果某些组矫正的P值不显著,意味着这些组包括非一致的种,必须再分为更小的组,换句话说,这里应该划分为比两组更多的组。

现在运行后验检验,以确定每组内共性显著的物种:

# 后验检验
(spe.kendall.post2 <- 
    kendall.post(spe.hel, 
                 clusters2, 
                 nperm = 9999))
后验检验
后验检验

查看各个物种的平均Spearman相关系数。如果组内每个物种与本组内其他物种之间有正平均相关系数值则该组包含一致物种如果一个物种与其所有其他成员的相关性的平均值为负这表明该物种应该被排除在本组外。尝试对组进行更精细的划分,看看该物种是否找到了与本组其他物种间具有正平均相关性的组。这个物种也可能形成单体,即具有单一物种的群体。

对于分两组的情况,我们在较大的一组中有一个物种(Spce)与本组内其他成员的平均相关性为负,这表明我们应该寻找一个更精细的物种分组。让我们进行分三组后检验。

(spe.kendall.post3 <- 
    kendall.post(spe.hel, 
                 clusters3, 
                 nperm = 9999))
后验检验
后验检验

现在我们可以看到,三组中的所有物种与同小组的其他成员都是正的Spearman相关。Sqce发现自己处于一个由9个物种组成的,具有平均正相关的新群体中,尽管它对该组的一致性贡献并不显著。三组中的其他物种都对他们组一致性具有显著的贡献,所以我们可以停止继续分组,现在分为物种数为12 、9和6种的分组足以充分描述Doubs河流的物种关联。

生态理论通常预测生态关系中具有嵌套结构。在每个群落内,物种亚组或多或少或松散或紧密地关联在一起。可以通过考察Kendall W检验获得的物种关联大组中更小物种亚组情况探索这种嵌套现象。

这里定义的物种组,可以用不同的方式解读其生态意义,例如绘制河流的多度分布并计算每个样方的基本统计信息,也可帮助评估这些物种组的生态作用。另一种途径是对显著观念的物种进行RDA分析(以环境因子为解释变量,以后会学习

4. 基于有-无数据的物种集合

有一种方法专门针对物种有-无数据的聚类分析,它包括了计算R-模式的Jaccard系数S(作为物种间共发生的测度)的α组分,并通过Raup和Crick系数置换检验评估阿尔法的概率。此时P值可以当做距离:共发生度越高的两个物种,其P值越小。可是使用作者编写的test.a( )函数计算这个系数。

可以利用test.a( )函数分析转化有-无数据的的鱼类数据。

利用之后(第7章的内容)矫正方法可以设定置换检验中足够的置换次数,以获得多重检验的显著水平。Doubs1数据共有27个物种,因此需要运行,27×26÷2=351次检验,为了保持0.05水平的显著性,Bonferroni矫正需要P值达到0.05÷351=0.0001425。只有当置换次数达到9999次,最小的P值才能达到1÷(9999+1)=0.0001。置换次数达到99999可以达到更精细的P值,但是请注意这么大的置换次数,可能会让电脑多运行几分钟。

# 将物种转化为有-无数据
spe.pa <- decostand(spe, "pa")
# 共发生的物种检验
#设置较多的置换次数,有足够小的P值满足Holm矫正的要求
res <- test.a(spe.pa, nperm = 99999)
summary(res)

输出的结果res$p.a.dsit包含一个p值的矩阵。下一步计算向量化的p值矩阵的Holm矫正数(在之后第7章学习)

# 计算Holm矫正的p值矩阵
(res.p.vec <- as.vector(res$p.a.dist))
(adjust.res <- p.adjust(res.p.vec, method = "holm"))
# 检查一下置换的次数是否满足在Holm矫正之后还能允许显著性的p值
# 寻找 <=0.05值:
range(adjust.res)
计算Holm矫正的p值矩阵
计算Holm矫正的p值矩阵
image-20210511104211391
image-20210511104211391

在矫正后的p值中,可以发现0.05或比0.05小但很接近的值

#在矫正后的p值中,可以发现0.05或比0.05小但很接近的值
(adj.sigth <- max(adjust.res[adjust.res <= 0.05]))
# 现在寻找与adj.sigth对应的非矫正的p值
(sigth <- max(res.p.vec[adjust.res <= 0.05]))

P值0.04878的未矫正P值应该是0.00017。Holm矫正后的P值矩阵内大约有83个值小于0.05(可能每次运行这个数值有轻微的变化)。因此0.00017或更小的概率才能成为显著。接下来将相异矩阵内的所有大于0.00017的值都用1替换。

res.pa.dist <- res$p.a.dist
res.pa.dist[res.pa.dist > sigth] <- 1

那么有多少为矫正的p值小于或等于0.00017(sigth)

# 显著p值热图
dev.new(
  title = "0-1 species associations, heat map",
  width = 12,
  height = 6,
  noRStudioGD = TRUE
)
coldiss(res.pa.dist,
        nc = 16,
        byrank = TRUE,
        diag = TRUE)

显著p值热图
显著p值热图

5. 物种共生网络

共生网络分析在群落生态学研究中比较流行,特别是研究物种之间或群落之间生态相互作用等方面。原理就是分析生态群落内或多营养级的物种组合内物种之间的关联程度。

基于共生网络的拓扑图,我们可以定义物种的群组称为模块,网络结构有两个重要属性,即**“模块化”(共生物种被组织成模块的程度,即密集连接、不重叠的物种子集)“嵌套性”(网络嵌套程度,即小组合的物种组成是较大组合的嵌套子集)。一个物种角色被定位为与自身模块中其他物种相比较(“标准化的模块内程度”**,即与同一模块中的其他节点的连接数,然后被由连接数的均值和标准差标准化)以及与它与其他模块中的物种连接的程度(模块间“连通性”)。

基本上,网络是由邻接矩阵构成,该矩阵可以是二进制的(物种显著共生或不共生)或数字(物种之间的加权连接)。物种间各种正、中性或负的关联测度的均可以用来计算邻接矩阵,包括Spearman相关、Jaccard相似系数或前一节获得的P值。这些指标可以根据物种有-无数据或者多度数据来计算。通常应用阀值来限制一些数值比较小但非零点连接,以减少连接的规模。网络图以这样的模式绘制,即通过网各种算法将共生频次比较高的物种聚集在一起。

我们可以使用igraph包进行网络处理和picante包计算共生距离

让我们从计算鱼类属数据几个邻接矩阵开始,你可以选择其中一个对称矩阵来构建无向共生网络,这里基于Jaccard相似性进行计算。

# 加载包
library(igraph)
library(rgexf)

# 从上一节获得的显著的共生二元矩阵计算邻接矩阵
adjm1 <- 1 - as.matrix(res.pa.dist)
diag(adjm1) <- 0

# 从“a”距离矩阵计算邻接矩阵
adjm2 <- 1 - as.matrix(res$p.a.dist)
adjm2[adjm2 < 0.5] <- 0
diag(adjm2) <- 0

# 从 Spearman 秩相关矩阵计算邻接矩阵
adjm3 <- cor(spe, method = "spearman")

# 仅保存正相关(rho>=0.25)
adjm2[adjm3 < 0.25] <- 0
adjm2[adjm3 >= 0.25] <- 1  # 二元共生
diag(adjm3) <- 0

# 物种共生相异性(picante包)
?species.dist
adjm4 <- species.dist(spe.pa, metric = "jaccard"# Jaccard!!
adjm4 <- as.matrix(adjm4)
adjm4[adjm4 < 0.4] <- 0

# 选择邻接矩阵
adjm <- adjm4
summary(as.vector(adjm))

dev.new(
  title = "Species co-occurrences",
  noRStudioGD = TRUE
)
# 绘制邻接值柱状图
hist(adjm)
绘制邻接值柱状图
绘制邻接值柱状图
# 构建图像元
go <- graph_from_adjacency_matrix(adjm, 
                                  weighted = TRUE
                                  mode = "undirected")
plot(go)
image-20210511141837793
image-20210511141837793
# 网络结构检测:发现连接图中的密集连接子集(模块或群落)
wc <- cluster_optimal(go)
modularity(wc)
membership(wc)
plot(wc, go)
基于Jaccard相似性的鱼类共生网络图
基于Jaccard相似性的鱼类共生网络图

图中显示三个模块(以物种气泡颜色来区别)。黑线指示正的模块内关联,红线指示正的模块间关联

# 输出 gephi 图
gexfo <- igraph.to.gexf(go)
print(gexfo, file = "gexfo.gexf", replace = TRUE)

# 卸载 rgexf 程序包
detach("package:rgexf", unload = TRUE)
# 如果无效请执行以下命令
unloadNamespace("rgexf")

本次物种集合就是这四个部分的内容:

  1. 组内数据简单统计
  2. Kendall共性系数(W)
  3. 基于有-无数据的物种集合
  4. 物种共生网络

今天的内容就到这里结束了,下一次将继续第四章聚类分析中指示物种的内容,请期待。

这些案例的源代码我都已经上传到getee,可以在我的公众号回复:数量生态学获得仓库链接

如有不足或错误之处,请批评指正。 有什么不明白的也欢迎留言讨论。

欢迎关注同名wx公众号

往期内容:

《数量生态学:R语言的应用》第三章-R模式

《数量生态学:R语言的应用》第二版第三章-关联测度与矩阵------Q模式

《数量生态学:R语言的应用》第二版笔记2

《数量生态学——R语言的应用》第二版阅读笔记--绪论和第二章(一部分)

R语言 pheatmap 包绘制热图(基础部分)

R语言pheatmap包绘制热图进阶教程

使用PicGo和gitee搭建图床

组间分析—T检验、R语言绘图

Rmarkdown的xaringan包来制作PPT

htlm文件部署到个人网站

感谢你的阅读!!!你的点赞关注转发是对我最大的鼓励。

fafu生信小蘑菇

2021/05/11  阅读:43  主题:自定义主题1

作者介绍

fafu生信小蘑菇