You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.22 09:48:42