R语言:按companyID分组筛选同时含status 0、1、2的观测子集
R语言分组筛选:保留组内同时包含多类status值的全部观测
核心需求:按companyID对观测分组,提取组内status同时包含0、1、2三类值的所有观测。示例中companyID=2的分组仅存在status=1的取值,会被完全排除,最终输出结果和给定的预期完全匹配。
常用实现方法
方法1:tidyverse/dplyr 实现(最通用的写法)
实现逻辑:先按companyID分组,对每个分组判断status值集合是否覆盖目标值,满足条件就保留整组所有行。
library(dplyr) # 构建示例数据集 df <- data.frame( companyID = c(1,1,1,1,2,2,2,3,3,3,3,3), status = c(1,1,0,2,1,1,1,1,0,2,2,2) ) # 分组筛选 df_filtered <- df %>% group_by(companyID) %>% # 判断当前分组是否同时存在0、1、2三类status值 filter(all(c(0, 1, 2) %in% status)) %>% ungroup()
判断逻辑说明:all(c(0,1,2) %in% status)会依次检查目标值集合里的每个值是否都在当前分组的status向量中,只要有任意一个目标值缺失就排除整个分组,不关心每个值在组内的出现次数。
方法2:base R 原生实现(无需安装额外包)
实现逻辑:用ave函数按分组生成布尔筛选标记,再基于标记对原数据集取子集。
# 为每个分组生成匹配标记 group_keep_flag <- with( df, ave(status, companyID, FUN = function(x) all(c(0,1,2) %in% x)) ) # 基于标记筛选符合条件的行 df_filtered_base <- df[as.logical(group_keep_flag), ]
方法3:data.table 实现(适合大规模数据集)
实现逻辑:将数据集转换为data.table格式,分组后直接对符合条件的分组提取全量行,运行效率远高于前两种方法。
library(data.table) # 将数据框转换为data.table格式 setDT(df) # 分组筛选 df_filtered_dt <- df[, .SD[all(c(0,1,2) %in% status)], by = companyID]
内容的提问来源于stack exchange,提问作者coding_sailor
相关产品推荐
相关产品推荐

