如何用data.table实现逐行排序分组,替代dplyr处理配对数据
用data.table实现配对观测数据的分组去重
先看原始数据:
library(data.table) library(dplyr) dt <- data.table( V1 = c("B", "A", "D", "A", "G", "B", "C", "C", "E", "C"), V2 = c("A", "B", "C", "B", "C", "E", "D", "B", "B", "G") )
需求是将A:B和B:A视为同一组,实现分组去重。以下是两种高效的data.table实现方式:
方法1:生成统一标识后去重
利用pmin()和pmax()直接得到每行配对的统一顺序(比sort()更高效,仅针对两个元素),生成widget列后按该列去重:
# 生成统一的widget标识 dt[, widget := paste(pmin(V1, V2), pmax(V1, V2), sep = ":")] # 按widget分组,保留每组第一行 orderedDT <- dt[, .SD[1], by = widget] # 如果仅需要去重后的widget标识,可简化为: orderedDT <- dt[, .(widget = paste(pmin(V1, V2), pmax(V1, V2), sep = ":"))][!duplicated(widget)]
方法2:直接按排序后的配对分组去重
无需额外生成widget列,直接以排序后的配对作为分组键,保留每组第一行:
orderedDT <- dt[, .SD[1], by = .(pmin(V1, V2), pmax(V1, V2))]
你之前写法的问题分析
你尝试的代码存在两个核心问题:
by = .(V1, V2)是按原始的(V1,V2)组合分组,而非排序后的配对,无法满足"AB和BA视为同一组"的需求;lapply(.SD, function(x){paste(sort(x), collapse = ":")})是对.SD中的每一列单独处理,而非将每行的V1和V2合并后排序,导致生成的widget列不符合预期。
内容的提问来源于stack exchange,提问作者mer_curius
相关产品推荐
相关产品推荐

