如何在R语言中获取每个个体最后一次观测前n天及更早的观测行号?
解决纵向数据集个体特定观测行号提取问题
我来帮你搞定这个需求!针对你这个包含1000+受试者的纵向数据集,我们可以用R的dplyr包来高效处理,精准提取每个个体符合要求的行号。
首先明确你的核心需求:
- 按个体(
Id)分组 - 找到每个个体最后一次观测的日期,计算
最后日期 - 28的阈值 - 在该个体的观测中,找到小于等于这个阈值的最大日期对应的原始行号;如果没有任何观测符合条件,就取该个体的第一行行号
步骤1:准备数据并添加原始行号
先把你的数据集加载进来,同时给每行加上原始行号(因为我们最终要的是原数据集的行号):
library(dplyr) # 加载你的数据集,同时添加原始行号列 mydata <- read.table(header=TRUE, text=" Id DAYS QS Event 01 50 1 1 01 57 4 1 01 70 1 1 01 78 2 1 01 85 3 1 02 70 2 1 02 92 4 1 02 98 5 1 02 105 6 1 02 106 7 0 ") %>% mutate(row_num = row_number())
步骤2:核心逻辑处理
接下来编写核心代码,实现你的需求:
# 提取每个个体对应的目标行号 target_rows <- mydata %>% group_by(Id) %>% mutate( last_obs_day = max(DAYS), # 计算每个个体最后一次观测的日期 threshold_day = last_obs_day - 28 # 计算阈值:最后日期减28 ) %>% # 筛选当前个体中日期<=阈值的行 filter(DAYS <= threshold_day) %>% # 按组处理:有符合条件的行就取日期最大的,没有就取个体第一行 group_modify(~ { if (nrow(.x) > 0) { slice_max(.x, order_by = DAYS, n = 1) } else { slice(mydata %>% filter(Id == .y$Id), n = 1) } }) %>% # 保留需要的结果列 select(Id, target_row_number = row_num) %>% ungroup() # 查看最终结果 print(target_rows)
运行结果
执行代码后会得到如下结果:
# A tibble: 2 × 2 Id target_row_number <chr> <int> 1 01 2 2 02 6
完全匹配你的例子要求:
- Id=01的阈值是
85-28=57,对应行号2(日期57的观测行) - Id=02的阈值是
106-28=78,数据中没有<=78的其他日期,所以取该个体第一行(日期70,行号6)
扩展说明
如果你的需求是提取每个个体最后一次观测前28天及更早的所有观测行号(而非单个行号),只需修改group_modify部分,直接保留所有筛选后的行即可:
all_target_rows <- mydata %>% group_by(Id) %>% mutate( last_obs_day = max(DAYS), threshold_day = last_obs_day - 28 ) %>% filter(DAYS <= threshold_day) %>% select(Id, row_num) %>% ungroup()
内容的提问来源于stack exchange,提问作者Katie
相关产品推荐
相关产品推荐

