按group_number分组后移除A、B列内容重复的分组
问题:按分组去重(组间A、B列完全重复则移除重复分组)
现有如下data.table示例数据:
example_data <- data.table( group_number = c(1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4), A = c(1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4), B = c(5, 6, 7, 8, 5, 6, 7, 8, 13, 14, 15, 16, 21, 22, 23, 24), other_columns = c(-0.03821019, -1.65126924, 0.26851449, -0.95818859, 0.51500988, 1.01449388, -0.65350743, -0.26931109, 1.04377564, 0.36648139, 2.47164652, -0.49508173, 0.53431890, -0.35798755, 0.38692761, 0.62482005) )
需求:按group_number分组后,若某分组的A、B列内容与另一分组完全一致,则移除重复分组,仅保留一组。比如示例中group_number=1和group_number=2的A、B列内容完全相同,需要移除group_number=2的所有行,最终输出如下:
example_data <- data.table( group_number = c(1, 1, 1, 1, 3, 3, 3, 3, 4, 4, 4, 4), A = c(1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4), B = c(5, 6, 7, 8, 13, 14, 15, 16, 21, 22, 23, 24), other_columns = c(-0.03821019, -1.65126924, 0.26851449, -0.95818859, 1.04377564, 0.36648139, 2.47164652, -0.49508173, 0.53431890, -0.35798755, 0.38692761, 0.62482005) )
注意:不能使用distinct(example_data,A,B,.keep_all = TRUE),该方法是按A、B的行组合去重,而非按分组整体判断重复。
解决方案
可以通过以下data.table的链式操作实现需求:
# 1. 为每个分组生成唯一标识(基于A、B列的组合) # 2. 保留每个标识对应的第一个分组 # 3. 筛选原数据中属于保留分组的行 result <- example_data[, .(group_id = paste(A, B, collapse = "|")), by = group_number ][, .SD[1], by = group_id ][example_data, on = "group_number"]
步骤解释:
- 生成分组标识:按
group_number分组后,将每个分组内的A、B值拼接成一个字符串(用|分隔避免歧义),作为该分组的唯一特征标识group_id。 - 去重分组:按
group_id分组,只保留每个标识对应的第一个group_number(即保留最早出现的分组)。 - 筛选原数据:通过连接操作,从原数据中筛选出保留的
group_number对应的所有行。
如果担心字符串拼接的性能或可能的冲突,也可以用哈希值替代字符串:
# 需要先安装digest包:install.packages("digest") result <- example_data[, .(group_hash = digest::digest(list(A, B))), by = group_number ][, .SD[1], by = group_hash ][example_data, on = "group_number"]
内容的提问来源于stack exchange,提问作者catin
相关产品推荐
相关产品推荐

