【问题标题】:Avoid duplicates in numeric vector shifting numbers避免数字向量移位数字中的重复
【发布时间】:2021-08-03 08:37:48
【问题描述】:

我正在寻找从包含重复条目的数字向量出发的最佳方法,例如:

a=c(1,3,4,4,4,5,7,9,27,28,28,30,42,43)

到这个,如果合适的话,通过移动 +1 来避免重复:

b=c(1,3,4,5,6,7,8,9,27,28,29,30,42,43)

横向比较:

> data.frame(a=a, b=b)
    a  b
1   1  1
2   3  3
3   4  4
4   4  5
5   4  6
6   5  7
7   7  8
8   9  9
9  27 27
10 28 28
11 28 29
12 30 30
13 42 42
14 43 43

有什么简单快捷的方法吗?谢谢!

【问题讨论】:

  • 在条目 6 和 7 中,为什么这些值会发生变化?
  • 因为在之前的条目更改后它们会重复

标签: r duplicates numeric


【解决方案1】:

如果您希望它只执行一次(可能仍有重复):

a=c(1,3,4,4,4,5,7,9,27,28,28,30,42,43)
a <- ifelse(duplicated(a),a+1,a)

输出:

> a
 [1]  1  3  4  5  5  5  7  9 27 28 29 30 42 43

将导致没有任何重复的状态的循环:

a=c(1,3,4,4,4,5,7,9,27,28,28,30,42,43)
while(length(a[duplicated(a)])) {
  a <- ifelse(duplicated(a),a+1,a)
}

输出:

> a
 [1]  1  3  4  5  6  7  8  9 27 28 29 30 42 43

【讨论】:

    【解决方案2】:

    另一种方法是使用递归函数:

    no_dupes <- function(x) {
      if (anyDuplicated(x) == 0)
        x
      else
        no_dupes(x + duplicated(x))
    }
    
    no_dupes(a)
     [1]  1  3  4  5  6  7  8  9 27 28 29 30 42 43
    

    【讨论】:

      【解决方案3】:

      使用 purrr::accumulate 的 tidyverse 选项。

      library(dplyr)
      library(purrr)
      
      accumulate(a, ~ if_else(.y <= .x, .x+1, .y))
      
      # [1]  1  3  4  5  6  7  8  9 27 28 29 30 42 43
      

      【讨论】:

        猜你喜欢
        • 2020-10-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-10
        • 2020-07-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多