Sarei sorpreso se questo non fosse un dup, ma non sono riuscito a trovare una soluzione.Test di uguaglianza vettorizzati
Capisco i limiti di ==
per verificare l'uguaglianza dei numeri in virgola mobile. Si dovrebbe usare all.equal
0.1 + 0.2 == 0.3
# FALSE
all.equal(0.1 + 0.2, 0.3)
# TRUE
Ma ==
ha il vantaggio di essere vettorializzare:
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
posso scrivere una (cattiva) funzione me stesso:
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))
che dà la risposta corretta, ma ha ancora una lunga strada da percorrere.
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
Un'altra opzione potrebbe essere:
All.equal.abs <- function(x,y){
tol <- .Machine$double.eps^0.5
abs(x - y) < tol
}
che svolge in modo paragonabile a ==
.
Che cos'è una funzione esistente che esegue questa attività?
più vicino mi viene in mente è 'con (Df, mapply (function (a, b) IsTrue (all.equal (a, b)), x, y))', ma che probabilmente sarebbe meglio di quello che hai già fatto. Potresti ottenere un leggero aumento della velocità usando '.mapply()' (bare bone 'mapply()'). –
'abs (x-y)
fishtank