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

在R中压缩数据框并保留最值:野生动物遥测生存分析数据处理

问题:合并野生动物遥测生存分析的连续时间步数据

我正在处理野生动物遥测数据的比例风险生存分析,需要格式化带时间间隔步长的数据。需求是合并连续的时间步,仅当动物失联1个及以上时间步时,才新建一行记录。


当前数据

# Current data
   id    start end  fail cause   
 1 1       2     3     0 NA      
 2 1       3     4     0 NA      
 3 1       4     5     0 NA      
 4 1       5     6     0 NA      
 5 1       6     7     0 NA      
 6 1       7     8     0 NA      
 7 1       8     9     0 NA   
 8 1      12    13     0 NA      
 9 1      13    14     0 NA      
10 1      14    15     0 NA      
11 1      15    16     0 NA      
12 1      16    17     0 NA      
13 1      17    18     0 NA      
14 1      18    19     0 NA      
15 1      19    20     0 NA   
16 1      23    24     0 NA      
17 1      24    25     0 Censored
18 2       2     3     0 NA      
19 2       3     4     0 NA      
20 2       4     5     0 NA      
21 2       5     6     0 NA      
22 2       6     7     0 Censored
23 3       2     3     0 NA      
24 3       3     4     0 NA    
25 3       8     9     1 Dead

期望结果

# What I would like it to look like
   id    start end  fail cause   
 1 1       2     9     0 Censored            
 2 1      12    20     0 Censored         
 3 1      23    25     0 Censored      
 4 2       2     7     0 Censored      
 5 3       2     4     0 Censored      
 6 3       8     9     1 Dead

已有思路

我已经做过相关搜索,认为核心是给每个动物的连续监测期创建唯一分组标识,参考过类似如下的dplyr代码逻辑:

library(dplyr)    
dat %>%
   group_by(grp) %>%  
   mutate_at(vars(ends_with('high')), max) %>% 
   group_by_at(vars(ends_with('high')), .add = TRUE) %>% 
   summarise_at(vars(ends_with('low')), min)

恳请各位提供具体的实现建议!


解决方案

可以用dplyr直接实现连续时间步的分组与合并,核心是生成连续监测期的分组标识,再按分组聚合:

library(dplyr)

# 示例数据(替换为你的实际数据)
dat <- tibble::tribble(
  ~id, ~start, ~end, ~fail, ~cause,
  1, 2, 3, 0, NA,
  1, 3, 4, 0, NA,
  1, 4, 5, 0, NA,
  1, 5, 6, 0, NA,
  1, 6, 7, 0, NA,
  1, 7, 8, 0, NA,
  1, 8, 9, 0, NA,
  1, 12, 13, 0, NA,
  1, 13, 14, 0, NA,
  1, 14, 15, 0, NA,
  1, 15, 16, 0, NA,
  1, 16, 17, 0, NA,
  1, 17, 18, 0, NA,
  1, 18, 19, 0, NA,
  1, 19, 20, 0, NA,
  1, 23, 24, 0, NA,
  1, 24, 25, 0, "Censored",
  2, 2, 3, 0, NA,
  2, 3, 4, 0, NA,
  2, 4, 5, 0, NA,
  2, 5, 6, 0, NA,
  2, 6, 7, 0, "Censored",
  3, 2, 3, 0, NA,
  3, 3, 4, 0, NA,
  3, 8, 9, 1, "Dead"
)

# 核心处理逻辑
formatted_dat <- dat %>%
  arrange(id, start) %>% # 确保数据按个体和时间排序
  group_by(id) %>%
  # 生成连续监测期的分组标识:当当前start≠上一行end时,分组+1
  mutate(period_grp = cumsum(start != lag(end, default = first(start)))) %>%
  group_by(id, period_grp) %>%
  summarise(
    start = min(start), # 取该监测期的起始时间
    end = max(end),     # 取该监测期的结束时间
    fail = last(fail),  # 取该监测期最后一条记录的fail状态
    cause = last(cause),# 取该监测期最后一条记录的终止原因
    .groups = "drop"
  ) %>%
  # 把NA的终止原因替换为"Censored",匹配期望结果
  mutate(cause = ifelse(is.na(cause), "Censored", cause))

print(formatted_dat)

代码说明

  1. 排序:先按id和start排序,保证时间顺序正确,避免分组错误
  2. 生成分组标识:通过cumsum(start != lag(end))判断是否出现失联间隔,生成连续监测期的唯一分组号period_grp
  3. 聚合数据:按id和period_grp分组,提取每个监测期的起始/结束时间,以及最后一条记录的fail和cause(对应监测期的最终状态)
  4. 补全缺失值:将cause列的NA替换为"Censored",与你的期望结果一致

运行后输出的结果完全匹配你想要的格式。


内容的提问来源于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 19:42:46