删除重复的列对,根据两个列排序行。

7
在下面的数据框中,如果它们具有重复的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个回答

10

如果有人想使用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

这是怎么工作的?这真的很酷。我以为粘贴是按照那个顺序粘贴两列,但我的列对有一个相同的键,每个重复对都是如此。 - Adam

5

不要对整个数据集进行排序,而是先按'Var1'、'Var2'排序,然后使用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

4
如果数据量很大,例如在 对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]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接