如何在R中对站点物种丰度数据执行无放回个体抽样
你之前的代码之所以无放回模式无法运行,是因为sample函数在replace=FALSE时的prob参数是对抽样对象(也就是物种ID)的抽取概率加权,要求抽样数量不超过抽样对象总数,而且本质是抽取不重复的物种ID,不是你需要的抽取不重复的个体。
单站点实现代码
核心逻辑是先把丰度向量转换为「每个物种ID重复对应丰度次数」的个体池,再对个体池做无放回抽样,最后统计各物种的抽中数量:
# 提取单个站点的丰度向量 site_abun <- abundances[1, ] # 生成个体池:每个物种ID重复的次数等于该物种的丰度 individual_pool <- rep(seq_along(site_abun), times = site_abun) # 无放回抽取50个个体 sampled_individuals <- sample(individual_pool, size = 50, replace = FALSE) # 统计抽样后各物种的丰度,固定levels保证和原数据列顺序完全对齐,无抽中个体的物种值为0 sampled_abun <- as.numeric(table(factor(sampled_individuals, levels = seq_along(site_abun))))
批量处理所有站点
无需手动写for循环,用apply即可直接对所有行(站点)批量处理,还可以提前判断站点总个体数是否满足抽样要求:
rarefied_abundances <- t(apply(abundances, 1, function(site_abun) { total_ind <- sum(site_abun) # 站点总个体数不足50的情况可自定义处理逻辑,这里示例返回全NA并抛出警告 if (total_ind < 50) { warning(paste("站点总个体数不足50,当前个体数:", total_ind)) return(rep(NA_real_, length(site_abun))) } individual_pool <- rep(seq_along(site_abun), times = site_abun) sampled_ind <- sample(individual_pool, size = 50, replace = FALSE) as.numeric(table(factor(sampled_ind, levels = seq_along(site_abun)))) }))
现成工具包方案(生态领域通用)
如果不需要自定义逻辑,可以直接使用生态分析常用的vegan包的rrarefy函数,专门用于丰度矩阵的无放回个体抽样,一行代码即可完成操作:
# 首次使用先安装包 # install.packages("vegan") library(vegan) # 直接对整个丰度矩阵做抽样,返回和原矩阵结构完全一致的结果 rarefied_abundances <- rrarefy(abundances, sample = 50)
内容的提问来源于stack exchange,提问作者ktg
相关产品推荐
相关产品推荐

