如何结合str_starts与n_distinct()统计样本唯一物种数(排除重复未知种)
问题:统计样本唯一物种数(含未知物种条件判断)
需求
统计每个样本的唯一物种数量,但仅当未知物种确定不会与样本中已识别物种重复时,才将其计入总数。
示例数据集
test <- data.frame(sample = c(rep(1, 4), rep(2, 4), rep(3, 4), rep(4, 4), rep(5, 1)), species = c(c("Species_a", "Species_b", "Species_c", "Species_c"), c("Species_a", "Species_b", "Species_c", "Species_d"), c("Species_a", "Species_b", "Species_b", "Species_b"), c("Species_a", "Species_b", "Species_c", "Unknown_b_or_d"), c("Unknown_a_or_c")))
期望输出
sample nspp 1 1 3 2 2 4 3 3 2 4 4 3 5 5 1
疑问与尝试
我可以通过filter、summarize(n_distinct)和mutate的组合实现需求,但想通过str_starts简化步骤。尝试了以下语法有误的代码,想知道能否将str_starts与n_distinct()结合使用:
test %>% group_by(thing) %>% summarize(nspp_unknown = n_distinct(str_starts(common_name, pattern = "Unknown")))
补充规则
统计需避免重复计数:
- 若未知物种的候选包含样本中已识别的物种,则排除不计(如样本4的
Unknown_b_or_d,候选包含已存在的Species_b) - 若未知物种的候选均不在样本已识别物种中,则计入1个(如样本5的
Unknown_a_or_c,样本无已识别物种,候选均不存在)
解决方案
可以结合str_starts、n_distinct和字符串解析实现需求,以下是完整代码:
library(dplyr) library(stringr) test %>% group_by(sample) %>% summarize( # 计算已知物种的唯一数量 known_unique = n_distinct(species[!str_starts(species, "Unknown")]), # 提取当前样本中的未知物种 unknowns = species[str_starts(species, "Unknown")], # 判断是否需要计入未知物种 add_unknown = case_when( length(unknowns) == 0 ~ 0, TRUE ~ { # 解析未知物种中的候选物种(如从Unknown_a_or_c提取a、c) candidates = str_extract_all(unknowns, "(?<=Unknown_)[a-z]+(?=_or_|$)") %>% unlist() candidates_full = paste0("Species_", candidates) # 检查所有候选是否都不在已知物种中 if(all(!candidates_full %in% species[!str_starts(species, "Unknown")])) 1 else 0 } ), # 计算总物种数 nspp = known_unique + add_unknown ) %>% select(sample, nspp)
代码说明
- 按
sample分组后,先用str_starts筛选出已知物种,计算其唯一数量 - 提取未知物种,通过正则表达式解析出候选物种,转换为与已知物种一致的命名格式
- 判断候选物种是否均不在已知物种中,是则加1,否则不加
- 最后合并已知物种数和符合条件的未知物种数,得到最终结果
内容的提问来源于stack exchange,提问作者N.F.F.
相关产品推荐
相关产品推荐

