Byłbym zaskoczony, gdyby to nie dup, ale nie mogłem znaleźć rozwiązania.Wektoryzowane testy równości
Rozumiem ograniczenia ==
dla testowania równości liczb zmiennoprzecinkowych. Należy używać all.equal
0.1 + 0.2 == 0.3
# FALSE
all.equal(0.1 + 0.2, 0.3)
# TRUE
Ale ==
ma tę zaletę, że wektorowy:
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
można napisać (zły) Funkcja sobie:
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))
co daje poprawną odpowiedź, ale wciąż ma przed sobą długą drogę.
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
Inną opcją może być:
All.equal.abs <- function(x,y){
tol <- .Machine$double.eps^0.5
abs(x - y) < tol
}
który wykonuje porównywalnie do ==
.
Co to jest istniejąca funkcja, która wykonuje to zadanie?
Najbliższy mogę myśleć jest 'z (DF, mapply (function (a, b) isTRUE (all.equal (a, b)), x, y))', ale to będzie prawdopodobnie lepszy niż to, co już zrobiłeś. Możesz uzyskać niewielki wzrost prędkości używając '.mapply()' (bare bones 'mapply()'). –
'abs (x-y)
fishtank