我会很惊讶如果这不是一个重复问题,但我没有找到解决方法。
我了解使用 ==
测试浮点数相等性的限制。应该使用 all.equal
。
0.1 + 0.2 == 0.3
# FALSE
all.equal(0.1 + 0.2, 0.3)
# TRUE
但是
==
具有矢量化的优势:set.seed(1)
Df <- data.frame(x = sample(seq(-1, 1, by = 0.1), size = 100, replace = TRUE),
y = 0.1)
Df[Df$x > 0 & Df$x < 0.2,]
## x y
## 44 0.1 0.1
## 45 0.1 0.1
# yet
sum(Df$x == Df$y)
# [1] 0
我可以自己编写一个(糟糕的)函数:
我可以自己编写一个(糟糕的)函数:
All.Equal <- function(x, y){
stopifnot(length(x) == length(y))
out <- logical(length(x))
for (i in seq_along(x)){
out[i] <- isTRUE(all.equal(x[i], y[i]))
}
out
}
sum(All.Equal(Df$x, Df$y))
虽然给出了正确答案,但仍有很长的路要走。
microbenchmark::microbenchmark(All.Equal(Df$x, Df$y), Df$x == Df$y)
Unit: microseconds
expr min lq mean median uq max neval cld
All.Equal(Df$x, Df$y) 9954.986 10298.127 20382.24436 10511.5360 10798.841 915182.911 100 b
Df$x == Df$y 16.857 19.265 29.06261 30.8535 38.529 45.151 100 a
另一个选择可能是:
All.equal.abs <- function(x,y){
tol <- .Machine$double.eps ^ 0.5
abs(x - y) < tol
}
有一个现有的函数可以执行与==
相似的操作。
这个任务需要使用什么函数?
with(Df, mapply(function(a, b) isTRUE(all.equal(a, b)), x, y))
,但这可能不比你已经做的更好。你可以尝试使用.mapply()
(裸骨的mapply()
) 以获得轻微的速度提升。 - Rich Scrivenabs(x-y)<tol
是非常标准的写法,绝对比使用==
或all.equal
更好。 - fishtank