R唯一命令和表命令不一致

时间:2019-06-15 10:01:13

标签: r floating-point unique

我有一个奇怪的问题。为了说明:

a <- c(3.099331946117620972814,
       3.099331946117621860992)

> unique(a)
[1] 3.099331946117620972814 3.099331946117621860992
> table(a)
a
3.09933194611762 
               2

因此unique()正确地识别出第15位数字之后的数字是不同的。 table()认为它们没有什么不同。

这可能是预期的行为,但是由于我需要他们两个都同意,所以这在我的某些代码中引起了错误:

times <- sort(unique(times))
k <- as.numeric(table(times))

times正确地提取了唯一时间。 k应该是每次发生的次数计数,但是由于上述问题,它无法正确执行此操作。

有人建议获得独特性并同意餐桌吗? (或其他解决方法?)

1 个答案:

答案 0 :(得分:3)

从计算机的角度来看,在浮点数上尝试使用uniquetable在概念上是有问题的。该主题与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

(还有其他示例,如果好奇的话,我鼓励您阅读该FAQ主题中的更多内容。)

因此,我建议您确定所需的精度,然后在寻找唯一性时准确使用这些数字。使用您的数字,您可以使用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"

出于好奇,uniquetable不同的原因是table使用factor的某个地方,而as.character(y)则使用as.character(a) 。如果您执行as.character(a) # [1] "3.09933194611762" "3.09933194611762" ,则会将精度任意降低到14位:

unique

因此,要回答您提出的问题:tabletable不同,因为as.character最终使用unique,默认情况下会截断为这里是14位数字。 (由于它是原始的,因此您必须进入低级源才能找出其中的一个。)

我在上面回答的问题是一个基本假设,即在浮点上使用 let form = document.forms['cal-form']; form.addEventListener('submit', calculate); function calculate(e) { //prevent default form submission e.preventDefault(); //get form values let num1 = parseInt(document.getElementsByTagName('input')[0].value); let num2 = parseInt(document.getElementsByTagName('input')[1].value); let op = document.getElementsByTagName('select')[0].value; //create object constructor function function Calculate(num1, num2, op){ this.num1 = num1; this.num2 = num2; this.op = op; } Calculate.prototype.result = function() { let res; switch (op) { case 'add': res = this.num1 + this.num2; break; case 'sub': res = this.num1 - this.num2; break; case 'mul': res = this.num1 * this.num2; break; case 'div': res = this.num1 / this.num2; break; default: res= 'Error! No operation selected.'; } return res; }; //create an object let cal = new Calculate(num1, num2, op); //display result document.getElementById('result').innerHTML = cal.result(); } }; 是一件好事(我认为这不是)。

相关问题