如何用R语言合并实现满足配对条件的分组样本筛选?
R语言DataFrame新增筛选列的优化方案
原始数据
raw.df <- data.frame(id = c("X01", "X02", "X03", "X04", "X05", "X06", "X07", "X08", "X09", "X10"), subject = c("S01", "S01", "S01", "S02", "S02", "S03", "S04", "S04", "S05", "S06"), time = c("D0", "D1", "D2", "D0", "D2", "D0", "D0", "D2", "D2", "D2"), response = c("Y", "Y", "Y", "N", "N", "Y", "Y", "Y", "Y", "N"))
需求说明
需要为上述数据新增selected列,规则如下:
- 若某个
subject的所有样本response均为"Y",且该subject同时拥有D0和D2时间点的样本,则该subject对应的这两个时间点的样本selected值为"Y" - 其余所有样本的
selected值为"N"
目标结果
final.df <- data.frame(id = c("X01", "X02", "X03", "X04", "X05", "X06", "X07", "X08", "X09", "X10"), subject = c("S01", "S01", "S01", "S02", "S02", "S03", "S04", "S04", "S05", "S06"), time = c("D0", "D1", "D2", "D0", "D2", "D0", "D0", "D2", "D2", "D2"), response = c("Y", "Y", "Y", "N", "N", "Y", "Y", "Y", "Y", "N"), selected = c("Y", "N", "Y", "N", "N", "N", "Y", "Y", "N", "N"))
原始分步实现
之前采用两步操作完成需求:
第一步:初步筛选候选样本
final.df <- raw.df %>% mutate(selected = case_when(time %in% c("D0", "D2") & response == "Y" ~ "Y", TRUE ~ "N"))
第二步:处理配对逻辑
final.df %>% filter(selected == "Y") %>% group_by(subject) %>% add_count() %>% ungroup() %>% mutate(n = if_else(n == 2, "Include", "Exclude")) %>% dplyr::rename(`paired` = n)
优化后的合并实现
通过分组计算核心条件,可一次性完成selected列的赋值,代码更简洁高效:
library(dplyr) final.df <- raw.df %>% group_by(subject) %>% mutate( # 计算当前subject是否满足核心条件:全Y且同时有D0、D2 meets_criteria = all(response == "Y") & all(c("D0", "D2") %in% time), # 根据条件和时间点赋值selected selected = case_when( meets_criteria & time %in% c("D0", "D2") ~ "Y", TRUE ~ "N" ) ) %>% ungroup() %>% select(-meets_criteria) # 可选:移除中间辅助列,按需保留
逻辑解释
- 按
subject分组后,先判断每组是否符合两个核心要求:该组所有样本response为"Y",且包含D0和D2两个时间点 - 基于组的判断结果,仅对符合条件的组中
time为D0或D2的样本标记selected为"Y",其余样本均为"N" - 最后可选择移除中间辅助列
meets_criteria,得到最终目标数据框
内容的提问来源于stack exchange,提问作者eraysahin
相关产品推荐
相关产品推荐

