删除重复的列对,根据2列对行进行排序

时间:2015-03-20 15:24:20

标签: r

在以下数据框中,如果他们有Var1Var2的重复对(1 4和4 1被认为是同一对),我只想保留一次行。我想过对行中的Var1Var2进行排序,然后根据Var1Var2删除重复的行。但是,我没有得到我想要的结果。

这就是我的数据:

Var1 <- c(1,2,3,4,5,5)
Var2 <- c(4,3,2,1,5,5)
f <- c("blue","green","yellow","red","orange2","grey")
g <- c("blue","green","yellow","red","orange1","grey")
testdata <- data.frame(Var1,Var2,f,g)

我可以在行内排序,但是列f和g的值应保持不变,我该怎么做?

testdata <- t(apply(testdata, 1, function(x) x[order(x)]))
testdata <- as.data.table(testdata)

然后,我想根据Var1Var2

删除重复的行

我希望得到这个结果:

Var1 Var2 f       g
1    4    blue    blue
2    3    green   green
5    5    orange2 orange1

感谢您的帮助!

3 个答案:

答案 0 :(得分:6)

如果人们有兴趣使用dplyr解决这个问题:

library(dplyr)
testdata %>% 
   rowwise() %>%
   mutate(key = paste(sort(c(Var1, Var2)), collapse="")) %>%
   distinct(key, .keep_all=T) %>%
   select(-key)

# Source: local data frame [3 x 4]
# Groups: <by row>
# 
# # A tibble: 3 × 4
#    Var1  Var2       f       g
#   <dbl> <dbl>  <fctr>  <fctr>
# 1     1     4    blue    blue
# 2     2     3   green   green
# 3     5     5 orange2 orange1

答案 1 :(得分:5)

不是对整个数据集进行排序,而是对“Var1&#39;”&#39; Var2&#39;进行排序,然后使用duplicated删除重复的行

testdata[1:2] <- t( apply(testdata[1:2], 1, sort) )
testdata[!duplicated(testdata[1:2]),]
#   Var1 Var2       f       g
#1    1    4    blue    blue
#2    2    3   green   green
#5    5    5 orange2 orange1

答案 2 :(得分:3)

如果数据很大,如Sort large amout of data and save repeated pairs of values in R中所示,则每行使用apply()将会很昂贵。而是创建一组唯一值

uid = unique(unlist(testdata[c("Var1", "Var2")], use.names=FALSE))

确定是否需要交换

swap = match(testdata[["Var1"]], uid) > match(testdata[["Var2"]], uid)

并更新

tmp = testdata[swap, "Var1"]
testdata[swap, "Var1"] = testdata[swap, "Var2"]
testdata[swap, "Var2"] = tmp

像以前一样删除重复项

testdata[!duplicated(testdata[1:2]),]

如果有许多额外的列,并且复制这些列很昂贵,那么就会有一个更独立的解决方案

uid = unique(unlist(testdata[c("Var1", "Var2")], use.names=FALSE))
swap = match(testdata[["Var1"]], uid) > match(testdata[["Var2"]], uid)
idx = !duplicated(data.frame(
    V1 = ifelse(swap, testdata[["Var2"]], testdata[["Var1"]]),
    V2 = ifelse(swap, testdata[["Var1"]], testdata[["Var2"]])))
testdata[idx, , drop=FALSE]