为什么在R语言中TRUE == "TRUE"是TRUE?

57
  1. R中为什么 TRUE == "TRUE" 的值是 TRUE
  2. R中是否存在与 === 相等的运算符?

更新:

以下所有语句的返回值均为 FALSE

TRUE == "True"
TRUE == "true"
TRUE == "T"

唯一的TRUE值是TRUE == "TRUE"

如果使用identical()进行检查,一切都正常。

第二次更新:

通过===运算符,我指的是检查变量数据类型的过程。在这种情况下,我假设==运算符只会比较变量的,而不是它们的数据类型


“===”是JavaScript运算符吗?[严格相等比较算法?] (http://ecma262-5.com/ELS5_HTML.htm#Section_11.9.6) - agstudy
@agstudy 我猜在许多以C语言为基础的语法的编程语言中,我们有这个运算符同时用于值和数据类型检查。我不确定其他编程语言是否也是如此... - Mahdi
1
TRUE==1和TRUE==1.0以及TRUE==1.0000000000000001(和0.99999999999999999)也是真的。通常,所有足够接近1.0以便被IEEE754舍入到它的东西都是真的。 - Bernd Elkemann
@Mahdi 大多数以 C 为基础的编程语言都具有静态类型,因此该运算符对它们来说没有意义。请注意,Ruby 具有此运算符。因此,它主要用于动态类型和默认类型强制转换进行值比较的语言中。 - Simon Bergot
可能是 https://dev59.com/K2025IYBdhLWcg3w_rFA 的重复问题。 - Arun
@Simon,Ruby是非常强类型的语言,根本没有默认的类型转换(是动态类型,但绝不是弱类型)。在Ruby中,“==”运算符就是精确相等运算符,如果你使用“===”进行相等比较,那么你就错了。而“===”运算符只是与“==”运算符有些微不足道的关系。在Ruby中,“===”是用于判断两个对象是否相等的运算符。它表示“右操作数是否可以‘适应’左操作数”。这有点难以解释,因此请参见https://dev59.com/GnA75IYBdhLWcg3wMmGo以获取详细信息。 - Ben Lee
3个回答

62
根据帮助文件中的说明 ?`==`

如果两个参数是不同类型的原子向量,则会将其中一个强制转换为另一个类型,优先顺序(按递减顺序)为字符型、复数型、数值型、整型、逻辑型和原始型。

因此,TRUE 被强制转换为 "TRUE" (即 as.character(TRUE)),因此相等。

在其他一些语言中,运算符 === 的等效操作(即两个对象是否相等且类型相同)将是函数 identical

identical(TRUE, "TRUE")
[1] FALSE

3
我需要修改我的答案,因为我想反过来了:实际上 == 会强制转换为一个公共类型,优先顺序为字符、复数、数字、整数、逻辑和原始数据。因此,实际上是将 TRUE 强制转换为 "TRUE",而不是相反,我犯了一个错误。请您谅解。 - plannapus
1
@plannapus 也许你应该处理 NaN 的情况。我认为 identical 不像 === 那样对待 NaN,例如:NaN===NaN 是 False,但是 identical(NaN,NaN) 是 TRUE。 - agstudy
2
在 R 中,没有任何东西与 NANaN 相等,甚至它们自己也不相等。 - IRTFM
1
@agstudy,你可以通过在identical中使用参数single.NA=FALSE来模拟NaN===NaN返回FALSE的情况:identical(log(-1), 0*Inf)返回TRUE,但是identical(log(-1), 0*Inf, single.NA=FALSE)返回FALSE(然而,仅测试identical(NaN, NaN, single.NA=FALSE)仍然返回TRUE)。 - plannapus
@agstudy 抱歉,我没明白你的意思。你能告诉我你希望我在原帖中添加什么吗? - Mahdi
显示剩余8条评论

12

TRUE和FALSE是R语言中的保留字。在eznme修改之前,他说任何非零值都是TRUE,我认为这是不正确的,因为TRUE == "A"的结果是FALSE。(这可以解释为什么TRUE == 1的结果是TRUE,但无法解释TRUE == 7的结果)。

plannapus所给出的解释是描述as.logical行为的上下文,更接近“真相”,因为是==运算符对TRUE进行隐式强制转换为字符类型导致了这个结果。虽然T和F最初被赋予TRUE和FALSE的值,但它们可以重新赋值为其他值或类型。

> TRUE == as.logical( c("TRUE", "T", "true", "True") )
[1] TRUE TRUE TRUE TRUE

>  TRUE == 7
[1] FALSE
> TRUE == as.logical(7)
[1] TRUE
>  TRUE == as.logical("A")
[1] NA

我之前错误地写道,TRUE == "TRUE" 引起的强制是逻辑上的;实际上是通过 as.character(TRUE) 返回 "TRUE" 实现的。


之前的引用确实是针对 as.logical 的,因为我假设 == 会强制转换为公共类型,但我对优先级的顺序做出了错误的假设。请参见我的编辑进行更正。 - plannapus
因为它们是不同的值,所以since TRUE == "A" evaluates to FALSE - Bernd Elkemann
但是TRUE和"TRUE"也是不同的值,实际上它们甚至是不同的模式。 - IRTFM

3

除了

TRUE == "TRUE"

这些也是正确的:

  • TRUE==1
  • TRUE==1.0
  • TRUE==1.0000000000000001
  • TRUE==0.99999999999999999 等等,通常也包括所有足够接近1.0以至于被IEEE754舍入到它的值。

但更有趣的是if()检查什么:它检查非false;实际上这个图表如下:

if(4.0) plot(1) 

我认为唯一不会触发if()的值是0、F、FALSE和"FALSE",它们被定义为确切的0。

2
"if" 明确声明它的参数被强制转换为逻辑值。 - IRTFM
所有非假值都将被强制转换为真值。数据类型宽度在这里并不重要,重要的是要注意哪些原始值被映射为真值,哪些被映射为假值。 - Bernd Elkemann
2
并不是所有非FALSE的值都会被强制转换为TRUE,NA值会抛出一个错误。 - IRTFM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接