为何specaccum与Rarefaction函数计算的物种丰富度低于实际值?
物种累积/稀疏曲线物种数不符问题排查与解决
问题原因
specaccum和specpool函数会自动过滤掉所有样地丰度均为0的物种,这类物种在实际调查中无有效记录,不属于当前数据集的统计范畴。- 你的数据有418列物种,但最终仅识别出181个,说明剩余237列为全0列(所有样地中该物种盖度均为0)。大概率是因为你使用
round(as.numeric(x))转换数据时,将原本低盖度的小数(如0.1、0.4)强制取整为0,导致这些物种在所有样地的丰度都变为0,被函数自动排除。
验证方法
运行以下代码确认全0物种列的数量:
# 统计每列(物种)的总丰度 species_total <- colSums(rare_data) # 统计全0物种的数量 zero_species_count <- sum(species_total == 0) zero_species_count # 查看全0物种的列名(可选) zero_species_names <- colnames(rare_data)[species_total == 0] zero_species_names
若zero_species_count结果为237(418-181),则验证了上述原因。
解决方案
方案1:修正数据转换逻辑(低盖度物种需保留)
如果原始数据中的小数盖度是有效记录(如0.1代表实际存在的低盖度),不要用取整操作破坏原始数据,仅转换为数值型即可:
# 仅转为数值型,保留原始盖度信息 rare_data[] <- lapply(rare_data, as.numeric)
这样低盖度物种会以非0值保留,不会被函数过滤。
方案2:手动过滤全0列(全0物种确实未出现)
如果这些全0物种是真实未被记录的,可提前手动移除全0列,让数据更简洁:
# 移除所有样地丰度均为0的物种列 rare_data_filtered <- rare_data[, colSums(rare_data) > 0] # 后续分析使用过滤后的数据 col <- specaccum(rare_data_filtered, method = "collector") # ... 其他代码保持不变
修改后的完整代码示例(方案1)
# 修正数据转换:仅转为数值型,保留原始盖度信息 rare_data[] <- lapply(rare_data, as.numeric) # 验证有效物种数量(此时应为418) length(colnames(rare_data)[colSums(rare_data) > 0]) # 物种累积曲线 col <- specaccum(rare_data, method = "collector") plot(col, xlab="样地数", ylab="物种数", col="blue") points(col$richness, pch=19, col="darkblue") # 稀疏曲线计算 N <- colSums(rare_data) sum(N) subs3 <- c(seq(500, 9000, by = 500), sum(N)) rar3 <- rarefy(N, sample = subs3, se = T, MARG = 2) print(rar3) # 物种丰富度估计 ace <- estimateR(N) chaoF <- specpool(rare_data) print(ace) print(chaoF) # 随机累积曲线 rand <- specaccum(rare_data, method = "random", permutations=1000) print(rand)
内容的提问来源于stack exchange,提问作者dainss delb
相关产品推荐
相关产品推荐

