【问题标题】:Remove duplicate column pairs, sort rows based on 2 columns [duplicate]删除重复的列对,根据 2 列对行进行排序 [重复]
【发布时间】:2023-03-07 03:32:02
【问题描述】:

在以下数据框中,如果行具有重复的 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

感谢您的帮助!

【问题讨论】:

    标签: r


    【解决方案1】:

    如果人们有兴趣使用 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
    

    【讨论】:

    • 这是如何工作的?这真的很酷。我认为 paste 通过按顺序粘贴两列来工作,但我的列对的每个重复对都有一个相同的键。
    【解决方案2】:

    如果数据很大,如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]
    

    【讨论】:

      【解决方案3】:

      不是对整个数据集进行排序,而是对'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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-06-02
        • 2013-12-03
        • 2018-12-08
        • 2021-06-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多