Попытка использовать unique
или table
для числа с плавающей запятой концептуально проблематична с точки зрения компьютера.Эта тема тесно связана с R FAQ 7.31 с выдержкой:
Единственными числами, которые могут быть точно представлены в числовом типе R, являются целые числа и дроби, знаменателем которых являетсястепень 2. Все остальные числа внутренне округлены с точностью (как правило) до 53 двоичных цифр.В результате два числа с плавающей запятой не будут надежно равны, если только они не были вычислены одним и тем же алгоритмом, и не всегда даже тогда.Например,
R> a <- sqrt(2)
R> a * a == 2
[1] FALSE
R> a * a - 2
[1] 4.440892e-16
R> print(a * a, digits = 18)
[1] 2.00000000000000044
(Существуют и другие примеры, если вам интересно, я советую вам прочитать больше в этой теме часто задаваемых вопросов.)
В связи с этим я предлагаю вам принять решение отребуемой точности, а затем используйте именно эти цифры при поиске уникальности.Используя ваши номера, вы можете вызвать проблему с помощью format
(и sprintf
):
a <- c(3.099331946117620972814,
3.099331946117621860992)
table(format(a, digits = 15))
# 3.09933194611762
# 2
table(format(a, digits = 16))
# 3.099331946117621 3.099331946117622
# 1 1
unique(format(a, digits = 15))
# [1] "3.09933194611762"
unique(format(a, digits = 16))
# [1] "3.099331946117621" "3.099331946117622"
Для любопытных причина того, что unique
и table
различны, коренится где-тоtable
использует factor
, что, в свою очередь, использует as.character(y)
.Если вы сделаете as.character(a)
, то произойдет произвольное снижение точности до 14 цифр:
as.character(a)
# [1] "3.09933194611762" "3.09933194611762"
Таким образом, чтобы ответить на вопрос, который вы задали : unique
и table
отличаются, потому чтоtable
в конечном итоге использует as.character
, который по умолчанию усекается до 14 цифр.(Поскольку это примитив, вам понадобится перейти к низкоуровневому источнику, чтобы выяснить это.)
Вопрос, на который я ответил выше, заключается в базовом предположении, что использование unique
для плавающей запятойэто хорошая вещь (я утверждаю, что это не так).