R语言FD包dbFD运行超时,求聚类提取medoid物种的方法
解决dbFD运行卡顿:基于聚类medoid简化物种集的实操步骤
针对你用dbFD处理大物种集时卡顿的问题,下面是从60%相似度聚类中提取medoid物种、再计算功能多样性的完整R代码步骤,每一步都附新手友好的注释:
1. 安装并加载所需包
# 首次运行先安装依赖包 install.packages(c("FD", "cluster", "dplyr", "tidyr")) # 加载包 library(FD) # 功能多样性计算、Gower距离 library(cluster) # 聚类、medoid提取 library(dplyr) # 数据分组处理 library(tidyr) # 数据格式转换
2. 读取数据(若已读可跳过)
# 读取性状表和群落表,假设第一列是物种/样地名 att <- read.csv("att.csv", row.names = 1) comm <- read.csv("comm.csv", row.names = 1)
3. 复用已计算的距离矩阵
你之前已经算出修正后的距离矩阵att.cal,直接用它就行:
注:
cailliez()修正后的矩阵符合欧氏距离要求,更适合后续聚类操作。
4. 层次聚类+按60%相似度切割分组
# 基于修正后的距离矩阵做层次聚类(ward法是功能性状聚类常用选择) hc <- hclust(att.cal, method = "ward.D2") # 60%相似度对应距离阈值:Gower相似度=1-距离 → 距离=1-0.6=0.4 cut_threshold <- 1 - 0.6 # 切割聚类树,得到每个物种的分组标签 species_clusters <- cutree(hc, h = cut_threshold) # 转成数据框方便后续处理 cluster_df <- data.frame(Species = names(species_clusters), Cluster = species_clusters)
5. 提取每个聚类组的medoid物种
medoid是组内与其他物种平均距离最小的物种,用距离矩阵计算筛选:
# 把距离矩阵转成矩阵格式,方便按组计算 dist_matrix <- as.matrix(att.cal) # 按聚类组计算每个物种的组内平均距离,筛选出最小的作为medoid medoid_list <- cluster_df %>% group_by(Cluster) %>% mutate(avg_group_dist = rowMeans(dist_matrix[Species, Species])) %>% filter(avg_group_dist == min(avg_group_dist)) %>% ungroup() # 提取最终的medoid物种名 medoid_species <- medoid_list$Species # 查看medoid数量(应该远小于546) cat("提取到的medoid物种数量:", length(medoid_species), "\n")
6. 生成medoid物种的距离矩阵
# 从原始修正矩阵中提取medoid物种的子矩阵 medoid_dist <- att.cal[medoid_species, medoid_species]
7. 调整群落表适配medoid物种
因为用medoid代表整个聚类组,需要把原群落中同组物种的存在情况合并(你的数据是有无分布,只要组内有物种存在,medoid就记为存在):
# 把宽格式群落表转成长格式,方便分组处理 comm_long <- comm %>% rownames_to_column("Site") %>% pivot_longer(-Site, names_to = "Species", values_to = "Present") # 合并聚类分组信息 comm_with_clusters <- comm_long %>% left_join(cluster_df, by = "Species") # 按样地+聚类组合并,判断该组是否有物种存在 comm_medoid <- comm_with_clusters %>% group_by(Site, Cluster) %>% summarise(Present = max(Present), .groups = "drop") %>% # 替换聚类组名为对应的medoid物种名 left_join(medoid_list %>% select(Cluster, Species = medoid_species), by = "Cluster") %>% select(Site, Species, Present) %>% pivot_wider(names_from = Species, values_from = Present) %>% column_to_rownames("Site") # 提取medoid物种的性状数据 att_medoid <- att[medoid_species, ]
8. 用medoid数据运行dbFD
# 运行功能多样性计算,现在数据量小,速度会快很多 fd_results <- dbFD( x = att_medoid, # medoid物种的性状表 a = comm_medoid, # 适配后的群落表 dist.family = "gower", # 对应之前用的Gower距离 stand.x = FALSE # 性状已经是分类变量,无需标准化 ) # 查看结果结构 str(fd_results) # 提取具体指标,比如功能丰富度 fd_results$FRic
可选调整建议
- 若medoid数量还是偏多,可降低相似度阈值(比如50%,对应距离0.5),减少聚类组数。
- 聚类方法可替换为
agnes(att.cal, method = "average"),适合不同的聚类需求。 - 若群落是多度数据,合并时把
max(Present)换成sum(Present)即可。
内容的提问来源于stack exchange,提问作者Julia Viotti Corrêa
相关产品推荐
相关产品推荐

