vegan包specnumber函数物种丰富度计算结果错位问题排查
问题:specnumber()计算物种丰富度时位点匹配错误
问题背景
拥有两个数据框:
obs_sp:记录不同位点的物种丰度(每行对应一个位点的一个物种)caract_sites:记录位点的生境特征
已通过dcast()将obs_sp转换为每行对应一个位点、每列对应一个物种的群落矩阵site_sp_ok(行名为位点名称)。
尝试用vegan包的specnumber()计算每位点的物种丰富度,并添加到caract_sites中,使用代码:
caract_sites <- caract_sites %>% add_column(specnumber(site_sp_ok))
但出现位点匹配错误:
- 错误结果:
Site Habitat sp_richness Site_1 C1 3 Site_2 E3 1 Site_3 C2 2 - 正确结果应为:
Site Habitat sp_richness Site_1 C1 1 Site_2 E3 2 Site_3 C2 3
问题原因
- 计算维度错误:
specnumber()默认参数MAR=2,表示按列计算丰富度。你的site_sp_ok是行代表位点、列代表物种的矩阵,直接调用会计算每个物种在多少个位点出现,而非每个位点有多少个物种,导致结果完全颠倒。 - 无匹配关联:
add_column()只是将计算结果按顺序追加到caract_sites,没有根据Site列做匹配,即使计算维度正确,若两个数据框的位点顺序不一致,仍会出现匹配错误。
解决方法
1. 按行计算物种丰富度
通过specnumber()的MAR=1参数指定按行(位点)计算:
# 计算每位点的物种丰富度 sp_richness <- specnumber(site_sp_ok, MAR = 1)
2. 基于Site列匹配合并
将计算结果转换为带Site列的数据框,再用left_join()与caract_sites按Site列合并,确保位点完全匹配:
library(dplyr) library(vegan) # 转换为带Site列的数据框 sp_rich_df <- data.frame( Site = names(sp_richness), sp_richness = sp_richness ) # 合并到caract_sites caract_sites <- caract_sites %>% left_join(sp_rich_df, by = "Site")
3. 简洁写法
可以在管道中直接完成计算与合并:
caract_sites <- caract_sites %>% left_join( data.frame( Site = rownames(site_sp_ok), sp_richness = specnumber(site_sp_ok, MAR = 1) ), by = "Site" )
验证结果
运行后得到正确的输出:
Site Habitat sp_richness 1 Site_1 C1 1 2 Site_2 E3 2 3 Site_3 C2 3
内容的提问来源于stack exchange,提问作者Chiara Mulloni
相关产品推荐
相关产品推荐

