R 您是否重新分配==和!=是真的吗?

R 您是否重新分配==和!=是真的吗?,r,R,A提示我发布这个问题。将==重新分配给isTRUE(all.equal())(和!=给!isTRUE(all.equal())似乎是一种最佳做法。我想知道其他人在实践中是否会这样做?我刚刚意识到,我使用=和!=在整个代码库中实现数字相等。我的第一反应是,我需要做一次彻底的清理,然后转换为所有.equal。但事实上,每次我使用=和!=时,我都想测试相等性(不考虑数据类型).事实上,我不确定这些操作除了相等之外还能测试什么。我肯定我在这里遗漏了一些概念。有人能告诉我吗?我反对这种方法的唯一理由是,在

A提示我发布这个问题。将
==
重新分配给
isTRUE(all.equal())
(和
!=
!isTRUE(all.equal())似乎是一种最佳做法
。我想知道其他人在实践中是否会这样做?我刚刚意识到,我使用
=
!=
在整个代码库中实现数字相等。我的第一反应是,我需要做一次彻底的清理,然后转换为
所有.equal
。但事实上,每次我使用
=
!=
时,我都想测试相等性(不考虑数据类型).事实上,我不确定这些操作除了相等之外还能测试什么。我肯定我在这里遗漏了一些概念。有人能告诉我吗?我反对这种方法的唯一理由是,在某些情况下,两个不相同的数字似乎是相同的,因为
all.equal
的容差。但我们被告知two事实上相同的数字可能无法通过因为它们是如何存储在内存中的。那么,不默认为
所有.相等的
到底有什么意义呢?

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

最好定义一个新函数
almostEqual
fuzzyEqual
或类似函数。不幸的是,没有这样的基函数。
all.equal
不是很有效,因为它处理各种对象,并返回一个字符串来描述差异,而您通常只需要
TRUE
错误

下面是这样一个函数的示例。它像
==
一样进行矢量化

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

这似乎是一件很奇怪的事情,然后我阅读了比较帮助页面中的注释:“不要在测试中使用==和!=,例如在if表达式中,必须得到一个TRUE或FALSE。除非您绝对确定不会发生任何异常,否则应改为使用相同的函数。”所以,也许这不是一个荒谬的想法。我要说的是,你不应该这样做。相反,使用
相同的
,并在子集设置时保持
==
用于矢量化比较。如果你开始重载普通运算符,你的代码将严重不可移植。最好了解每个运算符或函数的作用,并使用正确的joran-但是相同并不总是有效的。从R常见问题解答:“因此,两个浮点数将不会可靠地相等,除非它们是用相同的算法计算的,而且不总是相等”。因此,基本上这是说,即使两个数字相同,相同也会失败!@SFun28是真的,但这只是一个浮点问题,你会在任何地方遇到。最好不要掩盖
==
。为什么要定义新的,
===
!=
而不是使用
isTRUE
all.equal
?Tommy-afterr一些测试我认为这个函数中有一个bug。考虑一下:matrixa=round(matrix(rnorm(9),nrow=3,ncol=3),6)matrixb=matrixa-.001 almostEqual(matrixa,matrixb,tolerance=.001),即使这样有时也会产生FALSE:almostEqual(matrixa,matrixb,tolerance=.01)@SFun28-我认为代码是正确的。尝试
all.equal
,您也会得到非真值。这是因为它是一个相对公差。
rnorm
可以给出大(3.5)或小(0.0003)数字,但您添加到matrixb的错误总是
0.001
。尝试
matrixb
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