在R语言中筛选同时包含pre和post观测值的ID
筛选同时包含pre和post观测值的ID的方法
之前用merge(pre, post, by='ID', all=FALSE)出错,大概率是因为pre和post数据框有其他同名列,merge后生成了带.x/.y后缀的列,让你误以为结果不符合预期。下面给几种更直接的实现方式:
方法1:用dplyr(适合tidyverse用户)
如果你的所有数据在同一个数据框(比如叫df),其中period列是pre1、pre2、post1这类值:
library(dplyr) df_filtered <- df %>% group_by(ID) %>% # 标记每个ID是否有pre和post记录 mutate(has_pre = any(grepl("^pre", period)), has_post = any(grepl("^post", period))) %>% # 只保留同时满足两个条件的ID filter(has_pre & has_post) %>% ungroup() %>% select(-has_pre, -has_post) # 删掉临时标记列
如果pre和post是两个分开的数据框(pre_df、post_df):
# 先取两个数据框ID的交集 valid_ids <- intersect(pre_df$ID, post_df$ID) # 分别筛选后合并 filtered_pre <- pre_df %>% filter(ID %in% valid_ids) filtered_post <- post_df %>% filter(ID %in% valid_ids) combined_df <- bind_rows(filtered_pre, filtered_post)
方法2:Base R原生实现(不用第三方包)
如果数据在同一个数据框df:
# 提取有pre和post记录的ID集合 id_with_pre <- unique(df$ID[grepl("^pre", df$period)]) id_with_post <- unique(df$ID[grepl("^post", df$period)]) # 取交集得到有效ID valid_ids <- intersect(id_with_pre, id_with_post) # 过滤原数据 df_filtered <- df[df$ID %in% valid_ids, ]
如果是分开的pre和post数据框:
valid_ids <- intersect(unique(pre_df$ID), unique(post_df$ID)) filtered_pre <- pre_df[pre_df$ID %in% valid_ids, ] filtered_post <- post_df[post_df$ID %in% valid_ids, ] combined_df <- rbind(filtered_pre, filtered_post)
方法3:data.table(大数据量下更高效)
如果数据量很大,用data.table速度更快:
library(data.table) setDT(df) df_filtered <- df[, .(has_pre = any(grepl("^pre", period)), has_post = any(grepl("^post", period))), by = ID][has_pre & has_post, .(ID)][df, on = "ID"]
分开数据框的情况:
setDT(pre_df) setDT(post_df) valid_ids <- intersect(pre_df$ID, post_df$ID) filtered_pre <- pre_df[ID %in% valid_ids] filtered_post <- post_df[ID %in% valid_ids] combined_df <- rbindlist(list(filtered_pre, filtered_post))
内容的提问来源于stack exchange,提问作者J L
相关产品推荐
相关产品推荐

