如何将纵向数据中初始确定的分类变量沿个体重复填充?
按ID填充首次血红蛋白分类的解决方案
优化初始分类生成(替代多层ifelse)
首先可以用cut函数简化分类逻辑,比嵌套ifelse更易维护:
df <- data.frame(id=factor(c(1,1,1,2,2,2)), time=c(0,30,60,0,30,60), art_hb=c(5.8,6.1,5.9,6.7,6.9,NA)) # 仅对time=0的行生成分类,其余行先留空 df$art_hb_cat <- "" df[df$time == 0, "art_hb_cat"] <- cut( df[df$time == 0, "art_hb"], breaks = c(-Inf, 3, 6, 9, Inf), labels = c("0-3", "3-6", "6-9", ">9") )
方法1:使用dplyr(tidyverse生态)
按id分组后,提取每组非空的首个分类值并填充所有行:
library(dplyr) df_filled <- df %>% group_by(id) %>% mutate(art_hb_cat = first(art_hb_cat[art_hb_cat != ""])) %>% ungroup()
方法2:使用data.table(适合大数据集)
利用data.table的分组赋值语法,直接将time=0时的分类同步到同ID的所有行:
library(data.table) setDT(df) # 先生成初始分类(同cut方法) df[time == 0, art_hb_cat := cut(art_hb, breaks = c(-Inf,3,6,9,Inf), labels = c("0-3","3-6","6-9",">9"))] # 按ID填充分类 df[, art_hb_cat := art_hb_cat[time == 0], by = id]
方法3:基础R实现(无需额外包)
通过筛选+合并的方式完成填充:
# 先生成初始分类(同cut方法) df$art_hb_cat <- "" df[df$time == 0, "art_hb_cat"] <- cut(df[df$time == 0, "art_hb"], breaks = c(-Inf,3,6,9,Inf), labels = c("0-3","3-6","6-9",">9")) # 提取每个ID对应的分类 id_class_map <- df[df$time == 0, c("id", "art_hb_cat")] # 合并回原数据并替换分类列 df_filled <- merge(df, id_class_map, by = "id", suffixes = c("", "_fixed")) df_filled$art_hb_cat <- df_filled$art_hb_cat_fixed df_filled <- df_filled[, names(df)]
以上三种方法最终都能得到你需要的结果:每个ID的所有时间点都使用首次(time=0)的血红蛋白分类。
内容的提问来源于stack exchange,提问作者Tobias
相关产品推荐
相关产品推荐

