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

Tidyverse中时间-事件数据过滤:保留至首次事件或无事件全量数据

解决时间-事件数据过滤的报错问题

你的报错根源很明确:当某个受试者没有任何事件记录时,which(event == 1)会返回空向量,而between()函数要求right参数必须是单个有效值,空向量不符合这个要求,因此触发了Expecting a single value: [extent=0]的错误。

针对你的需求——有事件的受试者保留入组到首次事件的记录,无事件的保留全部数据,这里提供两种简洁的dplyr解决方案:

方法一:先计算首次事件ID,再过滤

library(tidyverse)

df %>%
  group_by(subject) %>%
  # 给每个受试者标记首次事件的ID,无事件则设为Inf(确保所有行都满足ID <= Inf)
  mutate(first_event_id = case_when(
    any(event == 1) ~ min(ID[event == 1]),
    TRUE ~ Inf
  )) %>%
  # 过滤到首次事件及之前的行(无事件则保留全部)
  filter(ID <= first_event_id) %>%
  # 可选:移除辅助计算列
  select(-first_event_id)

代码解释:

  • any(event == 1):判断当前受试者是否发生过事件
  • min(ID[event == 1]):如果有事件,取首次事件对应的最小ID(因为ID是按入组顺序生成的,最小ID就是首次事件的时间点)
  • 无事件时设为Inf,这样ID <= Inf会自动保留该受试者的所有行

方法二:直接在行号层面处理(更简洁)

df %>%
  group_by(subject) %>%
  filter(row_number() <= ifelse(any(event == 1), which(event == 1)[1], n()))

代码解释:

  • which(event == 1)[1]:取首次事件所在的行号(因为which()返回所有事件行的索引,[1]取第一个就是首次)
  • n():无事件时,用当前组的总行数作为边界,确保row_number() <= n()保留所有行
  • 这里row_number()和你生成的ID作用完全一致,所以也可以替换成ID <= ...

验证结果

运行上述代码后,你会得到符合需求的结果:

  • 受试者A:保留前3行(ID1-3,到首次事件为止)
  • 受试者E:保留前2行(首次事件在ID2)
  • 受试者B、D、F:保留全部行(无事件)
  • 受试者C:保留前3行(首次事件在ID3)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.06 09:57:31