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

如何基于捕获日期计算并填充tibble中的动物年龄列

问题描述

我有一组动物活体捕获数据,释放前会提取一颗小臼齿用于年龄测定,但部分个体仅能在重捕时完成测龄。示例如下:

首次捕获时测龄

IDexitageindaysage
3673410.934
379NANA
386NANA
3101NANA
3119NANA

重捕时测龄

IDexitageindaysage
4428NANA
4435NANA
444111453.14
4462NANA
4470NANA
4471NANA

我希望基于个体测龄日期前后的天数,填充每个个体的age列(年龄,单位:年)。尝试了以下代码:

df <- df %>% group_by(ID) %>%
          mutate(ageindays=case_when(!is.na(ageindays) ~ ageindays, 
                                     is.na(ageindays) ~ first(ageindays) + exit)) %>%
          ungroup() %>%
          mutate(age=as.numeric(ageindays/365))

但first()的使用有误,计算似乎基于整个数据框的第一行,输出中前几行计算正确,但切换新ID后(如个体3)计算出错。

示例数据结构:

structure(list(ID = c("5", "5", "5", "6", 
"6", "6", "6", "6", "6", "6", "6"
), exit = c(408, 409, 437, 679, 682, 688, 694, 702, 716, 723, 
729), AgeDay = c(408, 
408, 408, 679, 679, 679, 679, 679, 679, 679, 679), ageindays = c(317, 
317, 317, 588, 588, 588, 588, 588, 588, 588, 588)), row.names = c(NA, 
-11L), class = c("tbl_df", "tbl", "data.frame"))
解决方案

你的核心问题有两个:一是误用了first(),二是年龄计算的逻辑错误——正确的公式应该是测龄当天的ageindays + (当前exit日期 - 测龄当天的exit日期),而非直接将first(ageindays)与exit相加。

以下是修正后的代码:

library(dplyr)

df <- df %>%
  group_by(ID) %>%
  # 提取每个个体的测龄日期(ageindays非NA对应的exit值)和基准年龄天数
  mutate(
    age_exit = exit[!is.na(ageindays)][1],
    base_ageindays = ageindays[!is.na(ageindays)][1]
  ) %>%
  # 填充缺失的ageindays
  mutate(
    ageindays = case_when(
      !is.na(ageindays) ~ ageindays,
      TRUE ~ base_ageindays + (exit - age_exit)
    )
  ) %>%
  # 转换为以年为单位的年龄
  mutate(age = ageindays / 365) %>%
  # 清理临时变量
  select(-age_exit, -base_ageindays) %>%
  ungroup()

关键逻辑说明

  1. 分组提取基准值:按ID分组后,exit[!is.na(ageindays)][1]会获取当前个体第一次测龄的日期;base_ageindays则是该个体在测龄当天的年龄天数。如果一个个体有多次测龄记录,若要取最近一次的测龄数据,将[1]替换为last()即可。
  2. 计算缺失值:对于ageindays为空的行,用基准年龄天数加上当前捕获日期与测龄日期的天数差,就能得到当前捕获时的准确年龄天数。
  3. 单位转换:最后将ageindays除以365,转换为以年为单位的年龄。

示例验证

以个体4为例:

  • 测龄日exit为441,对应的ageindays是1145
  • 当exit=428时,ageindays = 1145 + (428-441) = 1132,age≈3.10
  • 当exit=471时,ageindays=1145 + (471-441)=1175,age≈3.22,完全符合时间推移的逻辑

内容的提问来源于stack exchange,提问作者logical-curve7345

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 09:45:04