如何高效去除无序重复二元组并保留右侧经度最小的记录?
问题描述
需要去除不考虑顺序的重复二元组,同时基于经度条件筛选——保留右侧元素始终具有最小经度的二元组。
示例数据
data <- data.frame( dyad.1 = c("A","B","A","C","B","C"), dyad.2 = c("B","A","C","A","C","B"), long_dyad.1 = c(1.3,2,1.3,0.3,2,1.3), long_dyad.2 = c(2,1.3,0.3,1.3,1.3,2) )
期望结果
data <- data.frame( dyad.1 = c("A","C","C"), dyad.2 = c("B","A","B"), long_dyad.1 = c(1.3,0.3,1.3), long_dyad.2 = c(2,1.3,2) )
现有可行代码
library(dplyr) library(tidyr) library(tidyverse) library(haven) data <- data %>% arrange(long_dyad.1) udata <- data[!duplicated(apply(data[,1:2], 1, function(row) paste(sort(row),collapse=""))),]
更高效的实现方案
方法1:dplyr向量化优化(tidyverse生态)
通过创建标准化二元组标识,结合分组筛选替代逐行循环,效率显著提升:
library(dplyr) data_cleaned <- data %>% # 生成不区分顺序的二元组唯一标识 mutate(dyad_pair = pmap_chr(list(dyad.1, dyad.2), ~paste(sort(c(..1, ..2)), collapse = "-"))) %>% # 按二元组分组,筛选右侧经度更小的行 group_by(dyad_pair) %>% filter(long_dyad.2 < long_dyad.1) %>% ungroup() %>% # 移除辅助列 select(-dyad_pair)
方法2:data.table实现(超大数据集首选)
data.table的分组操作在处理大规模数据时性能远超基础R循环:
library(data.table) setDT(data) # 生成标准化二元组键 data[, dyad_pair := sapply(.SD, function(x) paste(sort(x), collapse = "-")), .SDcols = c("dyad.1", "dyad.2")] # 按组筛选符合条件的唯一行 data_cleaned <- data[long_dyad.2 < long_dyad.1, .SD[1], by = dyad_pair][, dyad_pair := NULL]
核心优势说明
- 两种方法均避免了
apply逐行循环的低效操作,改用向量化或分组计算,数据量越大,效率提升越明显。 - 逻辑统一:先通过排序拼接生成不区分顺序的二元组标识,再按组筛选出
long_dyad.2更小的行,确保保留符合要求的唯一二元组。
内容的提问来源于stack exchange,提问作者Coralie
相关产品推荐
相关产品推荐

