如何移除R数据框中Query与target列的双向重复行
如何移除R数据框中Query与target列的双向重复行
嘿,我来帮你搞定这个双向重复行的问题!你要的是不管Query和target的顺序如何,只要这对组合之前出现过,就删掉后面重复的那行,对吧?咱们先从你的示例数据入手,我加了个set.seed让结果可重复:
set.seed(123) tmp <- data.frame(Query=c("A", "B", "C", "D", "A"), target=c("D", "A", "A", "A", "B"), values=runif(5)) tmp
运行后得到的结果是:
Query target values 1 A D 0.2875775 2 B A 0.7883051 3 C A 0.4089769 4 D A 0.8830174 5 A B 0.9404673
接下来给你两种常用的解决思路,一种是base R的原生方法,一种是tidyverse风格的,你可以选自己顺手的来用~
方法一:Base R 原生实现
核心思路是给每一对Query-target生成一个统一的标识——不管顺序是A-D还是D-A,我们都把它们排序后拼成同一个字符串,这样就能把双向重复的行标记出来,再去重。
具体代码如下:
# 对每行的Query和target排序,拼接成唯一标识 tmp$pair <- apply(tmp[, c("Query", "target")], 1, function(x) paste(sort(x), collapse = "_")) # 筛选出第一次出现的非重复行 result <- tmp[!duplicated(tmp$pair), ] # 删掉临时的pair列(可选,如果你不需要的话) result <- result[, !names(result) %in% "pair"] # 看看结果 result
运行后就能得到你想要的输出:
Query target values 1 A D 0.2875775 2 B A 0.7883051 3 C A 0.4089769
方法二:用dplyr(tidyverse风格)
如果你平时习惯用tidyverse系列的包,这个方法会更符合你的编码习惯,代码是流水线式的,可读性很强:
library(dplyr) library(stringr) result <- tmp %>% # 按行处理每一组Query和target rowwise() %>% # 生成排序后的统一标识 mutate(pair = str_c(sort(c(Query, target)), collapse = "_")) %>% # 取消按行分组 ungroup() %>% # 根据pair去重,同时保留所有列 distinct(pair, .keep_all = TRUE) %>% # 移除临时的pair列 select(-pair) result
运行后同样能得到正确的结果。
本质上两种方法的核心逻辑是一样的:把双向的配对转换成同一个唯一标识,这样就能用常规的去重函数处理啦。
备注:内容来源于stack exchange,提问作者nouse
相关产品推荐
相关产品推荐

