Проблема с функцией "равенства ()" в R? Как работает «равенства ()» для разных типов объектов? - PullRequest
1 голос
/ 23 мая 2019

(добавлен воспроизводимый пример)

Я не могу достаточно понять, почему следующее FALSE (я знаю, что они double и integer соответственно):

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.

Я знаю, что в 32-битной / 64-битной архитектуре R целые числа хранятся как 32-битные.

1 Ответ

1 голос
/ 24 мая 2019

Они не идентичны именно потому, что они имеют разные типы.Если вы посмотрите документацию для identical, вы найдете пример identical(1, as.integer(1)) с комментарием ## FALSE, stored as different types.Это одна подсказка.Определение языка R напоминает нам о том, что:

Одиночные числа, такие как 4.2, и строки, такие как "четыре целых два", являются по-прежнему векторами длины 1; больше нет базовых типов (выделено мной).

Итак, в основном все - это вектор с типом (поэтому также [1] появляется каждый раз, когда R возвращает что-то).Вы можете проверить это, явно создав вектор с длиной 1, используя vector, а затем сравнив его с 0:

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

Другими словами, vector("double", 1) и 0 outputвекторы типа "double" и длины == 1.

typeof и storage.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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...