R 在%中使用%时出现浮点问题

R 在%中使用%时出现浮点问题,r,R,在处理浮点问题时,我在使用%时遇到困难,例如 > x = seq(0.05, 0.3, 0.01) > x %in% seq(0.15, 0.3, 0.01) [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE TRUE TRUE TRUE TRUE TRUE FALSE FALSE TRUE TRUE TRUE TRUE TRUE TRUE [25] FALSE TRU

在处理浮点问题时,我在使用%时遇到困难,例如

> x = seq(0.05, 0.3, 0.01)
> x %in% seq(0.15, 0.3, 0.01)
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE FALSE FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
[25] FALSE  TRUE
我知道这是因为计算机是如何存储浮点的,但是有没有像
dplyr::near
这样的函数可以用来替换%中的
%呢<如果
x
的长度与
y
不同,则near(x,y)
将不起作用


非常感谢

使用四舍五入到小数点后两位的浮点似乎有效:

x <- round(seq(0.05, 0.3, 0.01), 2)
x %in% round(seq(0.15, 0.3, 0.01), 2)

                                                                 ^^ 0.15
 [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE
[13]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
[25]  TRUE  TRUE   <-- 0.3

x您可以在此处使用
dplyr::near
,但由于
near
进行两两比较,您需要与向量使用中的任何值进行比较
sapply

check_values <- seq(0.15, 0.3, 0.01)
sapply(x, function(x) any(dplyr::near(x, check_values)))

#[1]  FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE  TRUE  TRUE
#[13]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
#[25]  TRUE  TRUE

检查\u值将
转换为.character

as.character(x) %in% as.character(seq(0.15, 0.3, 0.01))
# [1] FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE FALSE
# [10] FALSE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
# [19]  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE  TRUE
这似乎也适用于更复杂的情况。考虑:

x <- c(.2999, .3, .2499, .25)
y <- c(.299, .3, .249, .25)

as.character(x) %in% as.character(y)
# [1] FALSE  TRUE FALSE  TRUE
它可以自动执行:

d <- max(nchar(c(x, y))) - 2
round(x, d) %in% round(y, d)
# [1] FALSE  TRUE FALSE  TRUE

d这是否回答了您的问题?根据我发布的链接,尝试
sprintf(“%.20f”,x)
。在我的电脑上,我期望返回为真的值之一返回为假的值是0.29;看看所有这些小数位,它实际上被视为0。28999999999999998002@camilleOP似乎已经理解了为什么它的代码由于浮点不精确而无法工作。这里的问题是如何解决这个问题。@camille不幸的是没有。我知道这是因为机器以二进制格式存储小数,但在这个问题上,当比较向量x和y时,它们的长度被假定为相等。当长度不同时,我要求x%在%y中。这是一个绝妙的解决方案!我怎么会错过呢!非常感谢,这真是…太棒了!我希望我能接受两个答案-谢谢Jay!
d <- max(nchar(c(x, y))) - 2
round(x, d) %in% round(y, d)
# [1] FALSE  TRUE FALSE  TRUE
`%in2%` <- function(x, y) {
  d <- max(nchar(c(x, y))) - 2
  round(x, d) %in% round(y, d)
}
`%in3%` <- function(x, y) {
  as.character(x) %in% as.character(y)
}
x %in2% y
# [1] FALSE  TRUE FALSE  TRUE
x %in3% y
# [1] FALSE  TRUE FALSE  TRUE