如何用R计算鱼类饮食数据中每种猎物的肠道优势度?
问题描述
我正在处理鱼类饮食数据,想要找出每种猎物i在多少条鱼的肠道中占主导(即数量最多),并为每种猎物(完整数据集约有25种)计算其优势度:Di = (Ndi / N) * 100,其中:
Di为猎物i的优势度Ndi是猎物i在肠道中数量最多的鱼的数量N为被检测的鱼的总数
示例数据:
df1 <- data.frame(preyName = c("a", "b", "c", "d", "e", "e", "b", "a", "e","c","d"), id_uniquefish = c("1", "6", "2", "3", "1","3","4","4","6","6","6"), numberPrey = c(14,20,3,19,234,24,4,13,45,4,6))
在该示例中,猎物e在5条被检测的鱼中有3条的肠道中占主导,因此猎物e的Ndi为3,Di=(3/5)*100=60。我需要为所有preyName(a、b、c、d、e等)完成此计算,完整数据集有280条观测值。请问如何在R中实现这一需求?
解决方案
以下提供两种R实现方案,可根据个人习惯选择:
方案一:Base R实现
通过基础R函数完成计算,无需额外安装包:
# 1. 按鱼的唯一ID分组,找出每条鱼中数量最多的猎物 dominant_prey <- aggregate(numberPrey ~ id_uniquefish, data = df1, function(x) df1$preyName[which.max(x)]) colnames(dominant_prey)[2] <- "dominantPrey" # 2. 统计每种猎物作为主导的次数(Ndi) ndi_table <- table(dominant_prey$dominantPrey) # 3. 获取总检测鱼数N total_fish <- length(unique(df1$id_uniquefish)) # 4. 计算优势度Di并整理结果 dominance_result <- data.frame( preyName = names(ndi_table), Ndi = as.numeric(ndi_table), Di = round((as.numeric(ndi_table)/total_fish)*100, 2) # 保留两位小数 ) # 输出结果 print(dominance_result)
方案二:tidyverse(dplyr)实现
语法更简洁直观,适合熟悉tidyverse生态的用户:
首先安装并加载依赖包:
install.packages("tidyverse") library(tidyverse)
执行计算代码:
dominance_result <- df1 %>% # 按鱼ID分组,筛选出每组中猎物数量最多的记录 group_by(id_uniquefish) %>% filter(numberPrey == max(numberPrey)) %>% # 若一条鱼存在多个数量相同的最大猎物,可添加slice(1)只保留一个(比如按猎物名称排序取第一个) # slice_min(preyName) ungroup() %>% # 统计每种猎物的主导次数 count(preyName, name = "Ndi") %>% # 计算总鱼数并计算优势度Di mutate( total_fish = length(unique(df1$id_uniquefish)), Di = round((Ndi / total_fish)*100, 2) ) %>% # 保留需要的列 select(preyName, Ndi, Di) # 输出结果 print(dominance_result)
注意事项
- 若存在单条鱼肠道内多种猎物数量相同且均为最大值的情况,tidyverse方案默认会将这些猎物都计入主导统计;若需只保留一个,可在
filter后添加slice(1)或slice_min(preyName)等语句指定筛选规则。 - 示例数据运行后,猎物e的
Di结果为60,与题目示例一致。
内容的提问来源于stack exchange,提问作者FishyFishies
相关产品推荐
相关产品推荐

