R中的“ identical()”函数有问题吗? “ identical()”如何用于不同类型的对象?

时间:2019-05-23 09:28:30

标签: r integer double storage notation

(添加了可复制的示例)

我无法充分理解为什么FALSE(我知道它们分别是doubleinteger):

identical(1, as.integer(1)) # FALSE

?identical显示:

num.eq: 逻辑指示是否应该使用==(“等于”)或按位比较来比较(双精度和复数非NA)数字。后者(非默认) 区分-0和+0。

sprintf("%.8190f", as.integer(1))sprintf("%.8190f", 1)返回完全相等的位模式。因此,我认为以下至少之一必须返回TRUE。但是,我在以下每个方面得到FALSE

identical(1, as.integer(1), num.eq=TRUE) # FALSE
identical(1, as.integer(1), num.eq=FALSE) # FALSE

我现在认为是这样的:如果sprintf是符号指示符,而不是存储指示符,那么这意味着identical()根据存储进行比较。即 identical(bitpattern1, bitpattern1bitpattern2)返回FALSE。对于以上FALSE / FALSE的情况,我找不到其他合乎逻辑的解释。

我确实知道在R的32位/ 64位架构中,整数都存储为32位。

1 个答案:

答案 0 :(得分:1)

由于它们具有不同的类型,因此它们并不完全相同。如果您查看identical的文档,则会发现示例identical(1, as.integer(1))及其注释## FALSE, stored as different types。那是一个线索。 R language definition提醒我们:

  

单个数字(例如4.2)和字符串(例如“四点二”)仍然是长度为1的向量; 没有其他基本类型(重点是我的)。

因此,基本上所有东西都是带有类型的向量(这也是[1]每次R返回值时都会显示的原因)。您可以通过使用vector显式创建一个长度为1的向量,然后将其与0进行比较来进行检查:

x <- vector("double", 1)
identical(x, 0)
# [1] TRUE

也就是说,vector("double", 1)0的输出向量均为“ double”类型,且长度== 1。

typeofstorage.mode指向同一件事,因此当您说“这意味着identical()根据存储进行比较”时,您是对的。我认为这不一定意味着要比较“位模式”,尽管我认为这是可能的。查看使用storage.mode更改存储模式时会发生什么:

## Assign integer to x. This is really a vector length == 1.
x <- 1L

typeof(x)
# [1] "integer"

identical(x, 1L)
# [1] TRUE

## Now change the storage mode and compare again. 
storage.mode(x) <- "double"

typeof(x)
# [1] "double"

identical(x, 1L) # This is no longer TRUE.
# [1] FALSE

identical(x, 1.0) # But this is.
# [1] TRUE

最后一点:identical的文档指出num.eq是…

  

逻辑指示是否应该使用==(“等于”)或按位比较来比较(双数和复数非NA)数字。

因此,更改num.eq不会影响任何涉及整数的比较。请尝试以下操作:

# Comparing integers with integers.
identical(+0L, -0L, num.eq = T) # TRUE
identical(+0L, -0L, num.eq = F) # TRUE

# Comparing integers with doubles.
identical(+0, -0L, num.eq = T) # FALSE
identical(+0, -0L, num.eq = F) # FALSE

# Comparing doubles with doubles.
identical(+0.0, -0.0, num.eq = T) # TRUE
identical(+0.0, -0.0, num.eq = F) # FALSE

相关问题