我们假设我在数据框中有一个字符列,其中包含a
,b
和c
的每个双重组合,就像这样
dat <- data.frame(V1 = c("a_a","a_b","a_c","b_a","b_b","b_c","c_a","c_b","c_c"))
但我不关心订单,因此我希望删除重复项b_a
,c_a
和c_b
,因为我已经a_b
,a_c
和b_c
。
dat <- data.frame(V1 = c("a_a","a_b","a_c","b_b","b_c","c_c"))
我通常使用dplyr进行数据争用,但我没有看到dplyr::distinct()
如何实现这一点。
我当然乐意考虑任何(非dplyr)解决方案。谢谢!
答案 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)
您可以使用dplyr
和stringr
执行以下操作:
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()