From gavin.simpson at ucl.ac.uk  Fri Jul  7 13:15:09 2006
From: gavin.simpson at ucl.ac.uk (Gavin Simpson)
Date: Fri, 07 Jul 2006 12:15:09 +0100
Subject: [Rd] BUG in " == " ? (PR#9065)
In-Reply-To: <20060707095044.80D4C549AE@slim.kubism.ku.dk>
References: <20060707095044.80D4C549AE@slim.kubism.ku.dk>
Message-ID: <1152270910.18259.21.camel@gsimpson.geog.ucl.ac.uk>

On Fri, 2006-07-07 at 11:50 +0200, eric.durand at imag.fr wrote:
> Hello,
> here is the version of R that I use :
> 
> > version
>                _
> platform       i486-pc-linux-gnu
> arch           i486
> os             linux-gnu
> system         i486, linux-gnu
> status
> major          2
> minor          3.1
> year           2006
> month          06
> day            01
> svn rev        38247
> language       R
> version.string Version 2.3.1 (2006-06-01)
> 
> And here is one of the sequences of isntruction that returns an abberation : 
> 
> > x<-seq(0,1,by=0.01)
> > x[71]
> [1] 0.7
> > which(x == 0.7)
> numeric(0)
> > x[71] == 0.7
> [1] FALSE
> 
> Or another version of (maybe) the same bug : 
> 
> > x <- 70
> > x == 70
> [1] TRUE
> > x <- x*0
> > x <- 70
> > x == 70
> [1] TRUE
> > x<-x*0.01
> > x
> [1] 0.7
> > x == 0.7
> [1] FALSE
> 
> It seems completely strange ... any help would be greatly appreciated :)
> 
> Regards,
> Eric Durand

Not a bug. Floating point precision - see
http://cran.r-project.org/doc/FAQ/R-FAQ.html#Why-doesn_0027t-R-think-these-numbers-are-equal_003f

E.g.:

x <- seq(0,1,by=0.01)
x[71]
which(x == 0.7) # FALSE
all.equal(0.7, x[71]) # TRUE

all.equal() should be used for this type of comparison. See ?all.equal

You could achieve what you wanted by something like this [ if you have a
real need to use which() ]:

x <- c(0.7, x, 0.7) # more 0.7's
lims <- range(0.7 + .Machine$double.eps^0.5, 0.7 - .Machine$double.eps^0.5)
which(x >= lims[1] & x <= lims[2])

Not sure if this is a good way to do it or not?

If you need to do this kind of comparison with which(), having a
v.all.equal() do a vectorised version of all.equal() would be useful,
returning a vector of TRUE/FALSE for each comparison. Maybe this already
exists somewhere?

E.g.:

v.all.equal <- function(x, y) {
  apply(as.matrix(x), 1, function(x, y) {
    retval <- as.logical(all.equal(x, y))
    retval[is.na(retval)] <- FALSE
    retval
  }, y)
}

which(v.all.equal(x, 0.7)) # 1  72 103

Again, maybe this is a bad thing...? In which case, I guess I'm about to
get told so... ;-)

G
-- 
%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%
 Gavin Simpson                 [t] +44 (0)20 7679 0522
 ECRC & ENSIS, UCL Geography,  [f] +44 (0)20 7679 0565
 Pearson Building,             [e] gavin.simpsonATNOSPAMucl.ac.uk
 Gower Street, London          [w] http://www.ucl.ac.uk/~ucfagls/cv/
 London, UK. WC1E 6BT.         [w] http://www.ucl.ac.uk/~ucfagls/
%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%~%



[Rd] BUG in " == " ? (PR#9065)
Gavin Simpson