【问题标题】:removing duplicates, dplyr removes non-duplicated rows.删除重复项, dplyr 删除非重复行。
【发布时间】:2018-04-07 06:25:12
【问题描述】:

我正在尝试向数据框中添加行,然后检查/删除在数据框的单个列中具有重复值的行。最终目标是如果提供了新值,则本质上是覆盖数据框中的一行。我无法弄清楚如何使用 dplyr (或实际上使用 R)动态指定行名,所以我正在这样做。

我从一个测试数据框开始,并使用 dplyr 删除列位置重复的第一组行,如下所示:

    testData.df<-data_frame(Position=c("B1","B2","B3","B1","B2","B3"), rep=c("B1","B2","B3","B4","B5","B6"),name=c(rep("wibble",each=6)),status=c(rep("unknown", each=6)))
    testData.df <- testData.df %>%
      filter(duplicated(Position))
    testData.df
# A tibble: 3 x 4
  Position   rep   name  status
     <chr> <chr>  <chr>   <chr>
1       B1    B4 wibble unknown
2       B2    B5 wibble unknown
3       B3    B6 wibble unknown

正如我所期望的那样。当我再次运行相同的过滤器时,我得到了这个:

testData.df <- testData.df %>%
  filter(duplicated(Position))
testData.df
# A tibble: 0 x 4
# ... with 4 variables: Position <chr>, rep <chr>, name <chr>, status <chr>

到底为什么要删除不重复的行?第一次运行它意味着它正在按预期工作,即它删除了实际的重复项。我无法解释第二轮的行为差异。

【问题讨论】:

    标签: r dplyr


    【解决方案1】:

    您期望filter(duplicated(...)) 保留非重复行,但实际上却相反。如果我们将row_numbers 添加到每一行,您可以看到这一点

    testData.df<-data_frame(Position=c("B1","B2","B3","B1","B2","B3"), rep=c("B1","B2","B3","B4","B5","B6"),name=c(rep("wibble",each=6)),status=c(rep("unknown", each=6))) %>%
                   mutate(rn = row_number())
    testData.df <- testData.df %>%
                      filter(duplicated(Position))
    

    输出

    # A tibble: 3 x 5
      Position   rep   name  status    rn
         <chr> <chr>  <chr>   <chr> <int>
    1       B1    B4 wibble unknown     4
    2       B2    B5 wibble unknown     5
    3       B3    B6 wibble unknown     6
    

    你应该改用filter(!duplicated(...))


    已编辑

    第一次尝试保留重复的行,但第二次不会丢失它

    testData.df<-data_frame(Position=c("B1","B2","B3","B1","B2","B3"), rep=c("B1","B2","B3","B4","B5","B6"),name=c(rep("wibble",each=6)),status=c(rep("unknown", each=6))) %>%
                    mutate(rn = row_number())
    
    run1 <- testData.df %>%
            group_by(Position) %>%
            slice(n()) %>%
                ungroup()
    
    run2 <- run1 %>%
            group_by(Position) %>%
            slice(n()) %>%
                ungroup()
    
    # A tibble: 3 x 5
    # Groups:   Position [3]
      Position   rep   name  status    rn
         <chr> <chr>  <chr>   <chr> <int>
    1       B1    B4 wibble unknown     4
    2       B2    B5 wibble unknown     5
    3       B3    B6 wibble unknown     6
    

    【讨论】:

    • 这有点扭曲了大脑。这行得通,谢谢。你知道如何让它保留后面的行,而不是重复的第一个实例吗?即让它 filter(!duplicated(Position)) 保留第 4,5,6 行而不是 1,2,3
    • @Ben 如果你想保留重复的行,你可以使用你的原始代码,但是你会遇到第二次执行相同代码时丢失这些行的问题。我有点困惑为什么你要运行 filter(duplicated(...)) 两次,为什么你想第一次而不是第二次保留重复的行。
    • 每次有人点击按钮时,代码都会在闪亮的应用程序中执行,因此会多次运行。它正在构建要输入机器人的地图,以便我们可以跟踪每个样本所在的位置。如果他们重新输入特定行的数据,我想覆盖已经存在的数据。可能有一种更简单/更好的方法来做到这一点,但通过闪亮是我获得界面的最简单/最快的方法。
    • 猜一下你在找什么,看看我编辑的答案
    • 非常多。这确实有效。虽然我刚刚发现 duplicated 有一个 fromLast 参数,但将其设置为 true,它也可以满足我的要求。
    猜你喜欢
    • 1970-01-01
    • 2014-05-22
    • 2020-02-04
    • 1970-01-01
    • 2021-09-24
    • 2023-03-09
    • 2019-08-08
    • 2011-03-24
    相关资源
    最近更新 更多