为什么as.numeric(1) == (3 | 4)的结果为TRUE?

3
我想用h == 1 | 2进行简单的比较,其中h是介于1和4之间的整数。令人惊讶的是,它没有起作用。
我有点理解为什么会这样:

1 == 2 | 4

TRUE

甚至可以理解为什么会这样:

1 == (2 | 4)

TRUE

但是,为什么会出现以下情况:

as.numeric(1) == (2 | 4)

或者

1L == (2 | 4)

或者

3 == 2 | 4

的结果都是

TRUE

???
我该如何让R告诉我是否1等于2或4,而答案将是FALSE

6
你应该使用1 %in% c(2,4) - dww
2
你期望 2|4 会计算成什么结果? - Hong Ooi
@HongOoi 我会期望像Julia或JavaScript一样的行为,而不是从数字到逻辑的强制转换... - Harold Cavendish
请回答问题。2|4的结果为TRUE,尽管它有点毫无意义。@dww可能更符合您想要的。在命令行中测试2|4可能会帮助您理解这个符号。 - Elin
2
顺便提一下,在Julia和Python中,1 == 2|4false,但不是你想的那个原因:|是按位或运算符,所以2|4的值为6...这并不值得单独回答,但也许值得有人在现有答案中包含这个信息... - Ben Bolker
3个回答

7
1 == 2 | 4

运算符优先级告诉我们它等同于(1 == 2) | 4

1 == 2FALSE,4被强制转换为逻辑值(因为|是一个逻辑运算符),as.logical(4)TRUE,所以你有FALSE | TRUE,这是TRUE

确实,逻辑运算符的强制转换规则?Logic)告诉我们:

数值和复杂向量将被强制转换为逻辑值,其中零为false,所有非零值为true。


3 == 2 | 4

同样的事情


1 == (2 | 4)

2 | 4 将被强制转换为 TRUE | TRUE,即 TRUE。然后 1 == TRUE 被强制转换为 1 == 1,即 TRUE

事实上,比较运算符的强制转换规则?Comparison)告诉我们:

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


as.numeric(1) == (2 | 4)

同样的事情


1L == (2 | 4)

同样的事情再来一次


1等于2或4

实际上是(1等于2)或(1等于4),即:

(1==2)|(1==4)

这是

FALSE | FALSE

这是FALSE


啊,强制类型转换...谢谢,我没有意识到像 as.logical(4) 这样的东西会变成 TRUE。我认为这根本不合理。 - Harold Cavendish
2
在大多数编程语言中,0 表示无,而 1、4 或 100 等数字则表示有意义的内容,因此它是“真”的,可以在许多情况下发挥作用。 - moodymudskipper
1
JavaScript、Julia 和 Python 都不会表现出这种方式,我也不太清楚其他的语言。无论如何,感谢您提供详细的解释。 - Harold Cavendish
2
但是 bool(4) 是真的,所以 Python 的行为是相同的。bool(0) 是假的,而 bool(-1) 也是真的。 - rawr
是的,不是'?comparison'而是'?Comparison',已经纠正了,谢谢。 - moodymudskipper
显示剩余5条评论

4

运行 2|4 将计算为 TRUE。这就是为什么当比较 1 == TRUE 时会得到 TRUE 的原因。你想要评估的是 (1 == 2) | (1 == 4),这将得到所需的 FALSE


你的运算符优先级有误,请参考其他答案。 - MichaelChirico
1
谢谢,我会接受更详细的答案,但我也很感激你的回答! - Harold Cavendish

3
您的第一个句子中所隐含问题的预期答案代码为:
1 %in% 2:4
[1] FALSE

h=1
h %in% 1:2
[1] TRUE

“==”运算符不会从逻辑连接中隐式生成范围(或备选项向量)。它被视为“比较”运算符,并且是“通用”的,这意味着不同数据类型的方法可能不同。它们也是向量化的(使用隐式循环规则),因此可能返回多个值:

(1:2) == (1:4)
[1]  TRUE  TRUE FALSE FALSE

as.numeric()函数应用于值1将返回完全相同的输入。

进一步评论:由于您尝试使用"=="实际上是一个隐式的集合操作,您可能需要查看?intersect帮助页面。还有一些处理更复杂集合函数的包。

R的强制转换可以在逻辑和数字之间来回转换,这取决于如何定义函数:

sum( letters[1:10] %in% letters)
[1] 10

sum( letters[1:10] == letters)
[1] 10
Warning message:
In letters[1:10] == letters :
  longer object length is not a multiple of shorter object length

我本来是在寻找c(2, 4)而不是2:4,但还是谢谢,这也很有用。 - Harold Cavendish
其实差别不大。1 %in% c(2,)同样是FALSE。Python的or函数以按位二进制方式处理数字值,因此2 or 3返回2。我会对任何声称这比R返回的更“直观”的说法提出异议。两者在完全相同的设置中都很有用...只有那些花时间阅读运算符和数据类型定义的人才能使用它们。 - IRTFM

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