在R中删除没有顺序的重复值的重复值

时间:2018-04-11 19:02:19

标签: r dplyr

我们假设我在数据框中有一个字符列,其中包含abc的每个双重组合,就像这样

dat <- data.frame(V1 = c("a_a","a_b","a_c","b_a","b_b","b_c","c_a","c_b","c_c"))

但我不关心订单,因此我希望删除重复项b_ac_ac_b,因为我已经a_ba_cb_c

dat <- data.frame(V1 = c("a_a","a_b","a_c","b_b","b_c","c_c"))

我通常使用dplyr进行数据争用,但我没有看到dplyr::distinct()如何实现这一点。

我当然乐意考虑任何(非dplyr)解决方案。谢谢!

3 个答案:

答案 0 :(得分:1)

如果所有组合都有重复项并且总是有一个已排序的组合,您可以这样做:

dat[sapply(strsplit(as.character(dat$V1),"_"),is.unsorted,s=T),,drop=F]
#    V1
# 1 a_a
# 4 b_a
# 5 b_b
# 7 c_a
# 8 c_b
# 9 c_c

更一般:

dat[!duplicated(sapply(strsplit(as.character(dat$V1),"_"),
                       function(x) paste(sort(x),collapse=''))),,drop=F]

答案 1 :(得分:0)

你需要两件事:一个对_进行内部排序的函数 - 分离的东西;以及删除重复项的能力。

首先:

internalsort <- function(x, split="_") {
  x <- as.character(x)
  sapply(lapply(strsplit(as.character(x), split=split), sort), paste, collapse=split)
}
rbind(as.character(dat$V1), internalsort(dat$V1))
#      [,1]  [,2]  [,3]  [,4]  [,5]  [,6]  [,7]  [,8]  [,9] 
# [1,] "a_a" "a_b" "a_c" "b_a" "b_b" "b_c" "c_a" "c_b" "c_c"
# [2,] "a_a" "a_b" "a_c" "a_b" "b_b" "b_c" "a_c" "b_c" "c_c"

其中第二行是第一行的内部排序。

其次,您需要使用duplicated查找重复项。显然,如果没有内部排序,它就不会发现欺骗行为:

duplicated(dat$V1)
# [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE

但现在......

duplicated(internalsort(dat$V1))
# [1] FALSE FALSE FALSE  TRUE FALSE FALSE  TRUE  TRUE FALSE

所以你的数据:

dat[! duplicated(internalsort(dat$V1)),,drop=FALSE]
#    V1
# 1 a_a
# 2 a_b
# 3 a_c
# 5 b_b
# 6 b_c
# 9 c_c

答案 2 :(得分:0)

您可以使用dplyrstringr执行以下操作:

dat %>%
  mutate(newval = unlist(
                    lapply(stringr::str_split(V1, "_"),
                           function(x) paste(sort(x), collapse = "_")))) %>%
  group_by(newval) %>%
  summarise()

## # A tibble: 6 x 1
##   newval
##   <chr> 
## 1 a_a   
## 2 a_b   
## 3 a_c   
## 4 b_b   
## 5 b_c   
## 6 c_c   

修改

以下是使用unlist(lapply...

替换sapply的更简化版本
dat %>%
  mutate(newval = sapply(str_split(V1, "_"),
                         function(x) paste(sort(x), collapse = "_"))) %>%
  group_by(newval) %>%
  summarise()