此功能有什么问题? -R

时间:2018-07-18 03:44:07

标签: r

函数如下:

qual <- function(x, y, z)
{if ((abs(x - y) <= .15)&(abs(x - z) <= .15)&(abs(y - z) <= .15)){print("grade A")} 
else if((abs(x - y) <= .15)|(abs(x - z) <= .15)){print("grade B")} 
else if((abs(x - y) <= .2)|(abs(x - z) <= .2)){print("grade C")} 
else if((abs(x - y) <= .25)|(abs(x - z) <= .25)){print("grade D")} 
else {print("check manually")}}

例如,qual(1.19, 1.04, 1.06)qual(1.10, .95, .97)的输出应该是“ A级”。但是,输出分别是“ A级”和“ B级”。

这是为什么?

1 个答案:

答案 0 :(得分:0)

我认为您遇到了一些浮点精度问题。有关完整说明,请参见Why are these numbers not equal

要解决此问题,您可以使用一个简短的函数,该函数在比较时会考虑到较小的精度错误:

less_equal_safe <- function(x, y) {
    (x < y) | dplyr::near(x, y)
}

qual <- function(x, y, z) {
    if (less_equal_safe(abs(x - y), .15) & (abs(x - z) <= .15) &(abs(y - z) <= .15)) {
        print("grade A")
    } else if ((abs(x - y) <= .15) | (abs(x - z) <= .15)) {
        print("grade B")
    } else if ((abs(x - y) <= .2) | (abs(x - z) <= .2)) {
        print("grade C")
    } 
    else if ((abs(x - y) <= .25) | (abs(x - z) <= .25)) {
        print("grade D")
    } else {
        print("check manually")
    }
}

(请注意,您需要安装dplyr软件包才能使用dplyr::near

我只替换了导致问题的第一个比较,但是理想情况下,您应该使用浮点安全函数替换函数中的 all 比较。