如何用Base R筛选按id分组后type列无重复值的数据行?
用Base R筛选data.frame:保留按id分组后type列值不重复的组
问题场景
给定如下data.frame:
df = data.frame(id = c(1,1,2,2,3,3,4,4,5,5,6,6), group = c("A","B","A","B","A","B","A","B","A","B","A","B"), type = c("ABC","ABC","ABB","ABB","AAB","AAB","ABC","ABD","ABC","ABD","AAB","AAC"))
需要移除所有按id分组后type列值完全相同的行(即移除id为1、2、3的所有行),最终保留id为4、5、6的行。
Base R实现方案
方法1:使用ave()分组标记筛选
ave()可以轻松实现分组统计,这里我们为每行标记其所属id分组的type唯一值数量,再筛选出数量大于1的行:
# 为每行添加分组内type的唯一值计数 df$unique_type_count <- ave(df$type, df$id, FUN = function(x) length(unique(x))) # 筛选符合条件的行,并删除辅助列 final_df <- df[df$unique_type_count > 1, !names(df) %in% "unique_type_count"]
方法2:拆分-过滤-合并流程
先按id拆分数据框,过滤掉type唯一值数量为1的分组,最后合并剩余分组:
# 按id拆分数据框 split_groups <- split(df, df$id) # 过滤出type存在多个值的分组 valid_groups <- Filter(function(g) length(unique(g$type)) > 1, split_groups) # 合并分组并重置行名(可选) final_df <- do.call(rbind, valid_groups) rownames(final_df) <- NULL
方法3:基于频数表筛选id
先统计每个id对应的type种类数,再提取对应id的行:
# 计算每个id的type种类数 id_type_counts <- rowSums(table(df$id, df$type) > 0) # 获取符合条件的id列表 valid_ids <- names(id_type_counts[id_type_counts > 1]) # 筛选原数据 final_df <- df[df$id %in% valid_ids, ]
最终结果
执行任意上述方法后,final_df的输出为:
> final_df id group type 1 4 A ABC 2 4 B ABD 3 5 A ABC 4 5 B ABD 5 6 A AAB 6 6 B AAC
内容的提问来源于stack exchange,提问作者SchlaWiener
相关产品推荐
相关产品推荐

