在R中移除无序拼接值的重复项——dplyr实现疑问
嘿,这个场景我太熟悉了!dplyr::distinct()本身没法直接识别这种不考虑顺序的重复组合,不过我们可以先给每个组合生成一个"标准化"的键,让a_b和b_a变成同一个标识,之后再用distinct()就轻松解决啦。
用tidyverse工具链的话,最直观的方案是这样的:
library(dplyr) library(tidyr) # 你的原始数据框 dat <- data.frame(V1 = c("a_a","a_b","a_c","b_a","b_b","b_c","c_a","c_b","c_c")) # 处理流程 dat_cleaned <- dat %>% # 把V1按下划线拆成两列,同时保留原列 separate(V1, into = c("elem1", "elem2"), sep = "_", remove = FALSE) %>% # 生成标准化的组合键:把两个元素按字母排序后合并 mutate(standardized_key = paste(pmin(elem1, elem2), pmax(elem1, elem2), sep = "_")) %>% # 按标准化键去重,保留所有列 distinct(standardized_key, .keep_all = TRUE) %>% # 只保留原V1列,得到目标结果 select(V1) # 查看结果 dat_cleaned
我来拆解下每一步的作用:
separate():把每个组合拆成单独的元素列,方便后续排序操作,remove=FALSE确保我们不会丢失原始的V1值。pmin()和pmax():这两个函数会逐行取两个元素的最小值和最大值,不管原来的顺序是a_b还是b_a,都会变成a和b,合并后得到统一的a_b作为去重的标识。distinct(standardized_key, .keep_all = TRUE):基于标准化键去重,.keep_all=TRUE保证我们保留所有列(包括原始V1),而不是只留下键列。- 最后
select(V1)就得到了你想要的去重后的数据框。
如果你不想加载tidyr,也可以用stringr来完成拆分和排序,代码稍微长一点但原理一样:
library(dplyr) library(stringr) dat_cleaned <- dat %>% mutate( standardized_key = map_chr(V1, ~ str_split(.x, "_")[[1]] %>% sort() %>% paste(collapse = "_")) ) %>% distinct(standardized_key, .keep_all = TRUE) %>% select(V1)
两种方法都能得到你要的结果,选你顺手的就行~
内容的提问来源于stack exchange,提问作者Simon
相关产品推荐
相关产品推荐

