如何按USUBJID分组填充FLAG列,遇FLAG="Y"时停止LOCF向下填充?
问题需求
按患者ID(USUBJID)分组,用FLAG的有效值填充缺失值,直到FLAG变为非缺失值;当FLAG="Y"时,停止对FLAG列的填充。尝试过fill( ,.direction=down)函数,但该函数会将前值结转至所有观测行,无法满足需求。
示例数据
原始数据框 df_have
USUBJID <- c(1,1,1,1,1,1, 2,2,2,2,2,2 ,3,3,3,3,3,3) FLAG <- c("N", NA, NA, "Y", NA, NA, "N", NA, NA, "Y", NA, NA, "N", NA, "Y", NA, NA, NA) df_have <- data.frame(USUBJID, FLAG) df_have
目标数据框 df_want
USUBJID <- c(1,1,1,1,1,1, 2,2,2,2,2,2 ,3,3,3,3,3,3) FLAG <- c("N", "N", "N", "Y", NA, NA, "N", "N", "N", "Y", NA, NA, "N", "N", "Y", NA, NA, NA) df_want <- data.frame(USUBJID, FLAG) df_want
解决方案
可以用dplyr结合分组逻辑实现:先定位每个组中第一个FLAG="Y"的行号,然后只对该行之前的NA进行向下填充,之后的NA保留原样。
library(dplyr) library(tidyr) df_result <- df_have %>% group_by(USUBJID) %>% mutate( # 找到每个组中第一个"Y"的位置,无"Y"则设为组内行数+1 first_y = ifelse(any(FLAG == "Y"), min(which(FLAG == "Y")), n() + 1), # 仅对first_y之前的行填充NA FLAG = ifelse(row_number() < first_y, fill(FLAG, .direction = "down"), FLAG) ) %>% select(-first_y) %>% # 移除辅助计算列 ungroup() # 查看结果 df_result
逻辑说明
- 按
USUBJID分组后,计算每个组内第一个FLAG="Y"的行号first_y;若组内无"Y",则设为组内行数+1,确保所有行都能被填充。 - 行号小于
first_y的行,用fill()向下填充NA;行号大于等于first_y的行,保持原FLAG值(包括后续的NA)。 - 最后移除辅助列并取消分组,得到符合要求的结果。
内容的提问来源于stack exchange,提问作者MKro
相关产品推荐
相关产品推荐

