R使用tidyverse按ID分组取最小timepoint对应值生成非时变新变量
实现方法
你需要在mutate中定位到每个ID分组下timepoint最小值对应的行,再提取该行的目标变量值即可,核心逻辑是用which.min()定位最小时间点的行下标。如果同一ID存在多个相同的最小timepoint记录,which.min()会默认取第一条出现的记录的值,符合常规基线取值逻辑:
library(tidyverse) # 基于你的示例数据补充处理逻辑 df_result <- df %>% group_by(ID) %>% mutate( first_age = age[which.min(timepoint)], first_cell = cell_prop[which.min(timepoint)] ) %>% ungroup()
运行后得到的df_result就会包含你需要的first_age和first_cell变量,取值和你给出的预期结果完全一致。
之前方法错误原因
- 第一种方法
min(age)取的是每个ID下age变量本身的最小值,和时间点无关,刚好年龄随时间递增才得到了看似正确的结果,换其他变量就会出错 - 第二种方法
age==min(timepoint)是判断当前行的年龄值是否等于该ID的最小时间点值,两个字段含义完全不同,自然全为FALSE
批量生成多变量的优化方案
如果你需要处理大量要生成first_前缀的变量,不需要逐个写mutate逻辑,可以用across()批量处理:
df_result <- df %>% group_by(ID) %>% # c()里填写所有需要生成首测值的变量名即可 mutate(across(c(age, cell_prop), ~.x[which.min(timepoint)], .names = "first_{.col}")) %>% ungroup()
内容的提问来源于stack exchange,提问作者am1s
相关产品推荐
相关产品推荐

