对向量进行舍入,以使所有结果元素都不同

标签 r vector rounding

我正在寻找一个例程,可以按“必要”的位数对向量进行舍入,以便所有元素仍然可以区分。我的第一次尝试如下所示:

discr.round <- function(x) {
  digits <- ceiling(-min(log10(diff(sort(x)))))
  round(x, digits)
}

discr.round(c(12.336, 12.344))
# [1] 12.336 12.344
discr.round(c(12.336, 12.347))
# [1] 12.34 12.35
discr.round(c(10, 25, 39))
# [1] 10 20 40
discr.round(c(1.2345679, 1.2345681))
# [1] 1.234568 1.234568
discr.round(c(1.23456789, 1.23456791))
# [1] 1.234568 1.234568

我需要它来格式化使用“几个”小数位的 float 向量。

如何调用这种舍入?在基础 R 或包中是否有此逻辑或类似逻辑的“标准”实现?

编辑:我需要这个成对,但代码应该推广到任意长度的向量。如果数字完全相等,则不需要区分。

最佳答案

options(digits=12) # Part of the problem is that your default digits = 7,
                   #   so you won't see any digits beyond that.
                   #  If you put too many (e.g, 22), you'll get floating point imprecision

#  Note the behavior for rounding off a 5 under ?round:
#  "IEC 60559 standard is expected to be used, ‘go to the even digit’."

# digits needed to distinguish between two nonequal elements
diff.dec.places <- function(x, y){
  delta <- abs(x - y)
  dec.place <- -ceiling(log10(abs(delta))) # your idea here was correct
  print(paste0("The elements (",x," & ",y,") differ in the ",
               10^-dec.place,"'s place."))
  if(round(x, dec.place)==round(y, dec.place)){
    print("But we add another sig. figure so they do not round to the same number.")
    dec.place <- dec.place + 1
  } 
  print(paste("The elements will round to",round(x, dec.place),'&',round(y, dec.place)))
  dec.place
}


# formula for arbitrary number of elements:
discr.round <- function(x){

  #- Find minimum-magnitude difference and which elements possess it: 
  #-   Create upper triangle of difference matrix of elements of vector with itself
  d <- abs(outer(x,x,"-"))
  d[lower.tri(d, diag=T)] <- NA
  #-   Return the smallest-magnitude difference and indices of elements forming it
  m <- min(d, na.rm=T)     
  if(m != 0){
    #- Round to number of dec places required to distinguish the closest elements
    e <- x[which(d==m, arr.ind=T)]
    round(x, diff.dec.places(e[1],e[2]))
  }
  else{
    print("Closest elements are equal.") 
    x
  }
}


discr.round(c(12.336, 12.344))
# [1] 12.336 12.344
discr.round(c(12.336, 12.347))
# [1] 12.34 12.35
discr.round(c(10, 25, 39))
# [1] 10 20 40
discr.round(c(1.2345679, 1.2345681))
# [1] 1.2345679 1.2345681
discr.round(c(1.23456789, 1.23456791))
# [1] 1.23456789 1.23456791

关于对向量进行舍入,以使所有结果元素都不同,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22094444/

相关文章:

r - 如何在 R 中读入整个二进制 blob?

r - 向绘图添加连续的颜色渐变图例条

c++ - 散列 std::vector 独立于项目顺序

algorithm - 消除矩阵的舍入误差

r - 如何 "round"ggplot中的范围线

r - 填充共现矩阵

c++ - 如何在 C++ 中存储和添加指向引用 vector 的链接?

c++ - 迭代器返回垃圾

lua - 如何四舍五入到最近的十分之一?

assembly - 如何将浮点舍入到最接近的偶数汇编