You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

R语言如何按年去重统计唯一鸟类ID及face.data为yes的数量

R语言按年去重统计鸟类观测指标方案

问题核心

统计年度鸟类观测数据时,同一只鸟同一年可能存在多条重复观测记录,直接逐行聚合会重复计数,需要先按「年份+鸟ID」维度去重后,再统计两个指标:

  • 当年所有唯一观测鸟ID总数
  • 当年存在face.data = "yes"记录的唯一鸟ID数量

前置修正:示例数据集格式问题

提供的原始示例代码中,日期值未加引号、数值型鸟ID会丢失前导0,先修正为R可正确识别的格式:

df <- data.frame(
  bird.ID = c("001", "001", "001", "002", "002", "002", "006" ,"006", "007", "007", "007", "007"), 
  date = as.Date(c("2010-04-09", "2013-04-14", "2013-09-14", "2013-05-08", "2013-06-08", "2013-08-08", "2013-04-08", "2013-06-08", "2014-06-08", "2016-06-08", "2017-06-08", "2017-08-08")), 
  face.data = c("yes", "yes", "no","yes", "yes", "no","yes", "yes", "no","yes", "yes", "no")
)

实现代码

方法1:dplyr 实现(逻辑清晰易维护)

library(dplyr)

stat_result <- df %>%
  # 从日期列提取年份
  mutate(year = format(date, "%Y")) %>%
  # 按 年份+鸟ID 分组,标记该鸟当年是否存在face.data为yes的记录
  group_by(year, bird.ID) %>%
  summarise(has_face_record = any(face.data == "yes"), .groups = "drop") %>%
  # 按年份分组聚合最终指标
  group_by(year) %>%
  summarise(
    `number of bird.ID` = n_distinct(bird.ID),
    `number of face.data` = sum(has_face_record),
    # 可选:直接计算yes记录的鸟占比
    yes_ratio = sum(has_face_record)/n_distinct(bird.ID)
  )

运行上述代码对示例数据统计得到的结果:

yearnumber of bird.IDnumber of face.datayes_ratio
2010111.0
2013331.0
2014100.0
2016111.0
2017111.0

方法2:基础R实现(无需安装第三方包)

# 提取年份列
df$year <- format(df$date, "%Y")

# 第一步:按年+鸟ID去重,判断每只鸟当年是否有face.data为yes的记录
bird_year_dedup <- aggregate(
  face.data ~ year + bird.ID,
  data = df,
  FUN = function(x) any(x == "yes")
)

# 第二步:按年聚合得到最终统计结果
stat_result <- aggregate(
  cbind(total_bird = bird.ID, face_bird = face.data) ~ year,
  data = bird_year_dedup,
  FUN = function(col) {
    if(is.logical(col)) sum(col) else length(unique(col))
  }
)

# 重命名列匹配要求格式
names(stat_result)[2:3] <- c("number of bird.ID", "number of face.data")

原代码问题说明

之前使用的aggregate(face.data=="yes" ~ cut(date, "1 year"), data = df, sum)逻辑是逐行判断后求和,同一只鸟当年有多条face.data="yes"的记录时会被重复计数,没有先按鸟ID做去重处理,因此结果偏大。

提示:如果你的日期列不是标准Date类型,一定要先用as.Date()转换后再提取年份,避免年份识别错误。

内容的提问来源于stack exchange,提问作者YBM

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 04:36:55