R How to use which () with floating point values?

I ran into the same problem as in R, which () returns an integer (0)

price = seq(4,7, by=0.0025)
allPrices = as.data.frame(price)
lookupPrice = 5.0600
which(allPrices$price == lookupPrice)

The operator which()displays integer(0)that indicates a lack of compliance. It should print 425, the corresponding line number in this sequence.

I understand that this is a floating point problem. The link assumes use all.equal(x,y)in some way.

How to include a function all.equal()in a statement which()to get the line number in allPriceswhich matches lookupPrice(in this case, 5.06)?

Is there any other approach? I need a row number, because the values ​​in other columns at this price will be changed.

+4
source share
5 answers

A manual approach to this involves determining tolerance for comparison and implementation:

# tol = 1e-7: comparison will be TRUE if numbers are equal up to 
#   7 decimal places
tol = 1e-7
which(abs(allPrices$price - lookupPrice) < tol)
+2
source

You can sapplyat all prices and apply a function all.equalto each of them to find the one that isTRUE

which(sapply(price, all.equal, lookupPrice) == TRUE)
# [1] 425
+1
source

4 :

which(round(allPrices$price, digits=4) == lookupPrice)
[1] 425

4 lookupPrice .

+1

dplyr near:

near(x, y, tol = .Machine$double.eps^0.5)

:

which(near(allPrices$price, lookupPrice))
#[1] 425
+1

.

, as.character() , ().

However, I wanted to find out why it did not work with numeric data and made some additional problems.

It seems like the problem is how R generates decimal sequences with seq (). Using the round () function works as suggested by Tim Bigeleisen, but I think you only need to apply it to the numbers generated by seq (). You can check my work below - the error is very sporadic, I just tried the numbers until I found one of them: 19.2.

> data <- 19.2
> x.seq <- seq(5, 45, 0.2)
> x.seq[72]
[1] 19.2
> 
> data == 19.2
[1] TRUE
> x.seq[72] == 19.2
[1] FALSE
> data == x.seq[72]
[1] FALSE
> data == round(x.seq[72], digits = 1)
[1] TRUE
> round(data, digits = 1) == x.seq[72]
[1] FALSE
0
source

Source: https://habr.com/ru/post/1681844/


All Articles