【问题标题】:Do you reassign == and != to isTRUE( all.equal() )?您是否将 == 和 != 重新分配给 isTRUE(all.equal())?
【发布时间】:2011-12-01 14:48:15
【问题描述】:

previous post 提示我发布此问题。将==重新分配给isTRUE(all.equal())(和!=重新分配给!isTRUE(all.equal())似乎是一个最佳实践。我想知道其他人是否在实践中这样做?我刚刚意识到我使用==和@987654327 @ 在我的代码库中进行数字相等。我的第一反应是我需要做一个全面的擦洗并转换为all.equal。但实际上,每次我使用==!= 时我都想测试相等(不管的数据类型)。事实上,我不确定这些操作除了平等之外会测试什么。我确定我在这里遗漏了一些概念。有人可以启发我吗?我看到的唯一反对这种方法的论点是在某些情况下,由于all.equal 的容差,两个不同的数字看起来是相同的。但是我们被告知,实际上相同的两个数字可能不会通过identical(),因为它们是如何存储在内存中的. 那么,不默认all.equal到底有什么意义呢?

【问题讨论】:

  • 这似乎是一件很奇怪的事情,然后我阅读了比较帮助页面中的注释:“不要使用 == 和 != 进行测试,例如在 if 表达式中,你必须得到一个 TRUE 或 FALSE。除非你绝对确定不会发生任何异常情况,否则你应该使用相同的函数。所以也许这不是一个荒谬的想法。
  • 我要说不,你不应该。请改用identical,并在子集时保留== 以进行矢量化比较。
  • 如果您开始重载常用运算符,您的代码将严重不可移植。更好地了解每个运算符或函数的作用,并为正确的工作使用正确的工具。
  • joran - 但相同并不总是有效。来自 R 常见问题解答:“因此,两个浮点数不会可靠地相等,除非它们是由相同的算法计算的,而且即使那样也不总是”。所以基本上这就是说即使两个数字相同,相同也会失败!
  • @SFun28 没错,但这只是一个浮点问题,你会在任何地方遇到。最好不要掩盖==。为什么要定义新的 ===!== 而不是使用 isTRUEall.equal

标签: r


【解决方案1】:

正如@joran 所暗示的,在几乎任何其他语言中,您都会遇到==!= 的浮点问题。在 R 中它们的一个重要方面是矢量化部分。

最好定义一个新函数almostEqualfuzzyEqual 或类似函数。不幸的是,没有这样的基本功能。 all.equal 效率不高,因为它处理各种对象并返回一个描述差异的字符串,而大多数情况下您只需要TRUEFALSE

这是一个这样的函数的例子。它像== 一样被矢量化。

almostEqual <- function(x, y, tolerance=1e-8) {
  diff <- abs(x - y)
  mag <- pmax( abs(x), abs(y) )
  ifelse( mag > tolerance, diff/mag <= tolerance, diff <= tolerance)
}

almostEqual(1, c(1+1e-8, 1+2e-8)) # [1]  TRUE FALSE

...对于标量值,它比 all.equal 快大约 2 倍,而对于向量则要快得多。

x <- 1
y <- 1+1e-8
system.time(for(i in 1:1e4) almostEqual(x, y)) # 0.44 seconds
system.time(for(i in 1:1e4) all.equal(x, y))   # 0.93 seconds

【讨论】:

  • Tommy - 经过一些测试后,我认为此功能存在错误。考虑: matrixa = round( matrix( rnorm( 9 ) , nrow = 3 , ncol = 3 ) , 6 ) matrixb = matrixa - .001 mostEqual( matrixa , matrixb , tolerance = .001 )
  • 即使这样有时也会产生 FALSE:mostEqual( matrixa , matrixb , tolerance = .01 )
  • @SFun28 - 我认为代码是正确的。试试all.equal,你也会得到不正确的结果。这是因为它是一个相对的容忍度。 rnorm 可以给出大 (3.5) 或小 (0.0003) 数字,但您添加到 matrixb 的错误始终是 0.001。请改用matrixb &lt;- matrixa*1.001
猜你喜欢
  • 2023-04-05
  • 1970-01-01
  • 2021-12-30
  • 1970-01-01
  • 1970-01-01
  • 2013-05-08
  • 2020-02-12
相关资源
最近更新 更多