What's the Difference Between Identical(X, Y) and Istrue(All.Equal(X, Y))

What's the difference between identical(x, y) and isTRUE(all.equal(x, y))?

all.equal tests for near equality, while identical is more exact (e.g. it has no tolerance for differences, and it compares storage type). From ?identical:

The function ‘all.equal’ is also
sometimes used to test equality this
way, but was intended for something
different: it allows for small
differences in numeric results.

And one reason you would wrap all.equal in isTRUE is because all.equal will report differences rather than simply return FALSE.

What is the difference between identity and equality in OOP?

  • identity: a variable holds the
    same instance as another variable.

  • equality: two distinct objects can
    be used interchangeably. they often
    have the same id.

Identity

For example:

Integer a = new Integer(1);
Integer b = a;

a is identical to b.

In Java, identity is tested with ==. For example, if( a == b ).

Equality

Integer c =  new Integer(1);
Integer d = new Integer(1);

c is equal but not identical to d.

Of course, two identical variables are always equal.

In Java, equality is defined by the equals method. Keep in mind, if you implement equals you must also implement hashCode.

In Julia: Is there a way to test for equality like R's all.equal()?

isapprox(x,y) is what you are looking for.

use ?isapprox in the REPL for additional help. Specifically, 2 parameters which specify relative tolerance for error and absolute tolerance for error.

Happy 2016

Do you reassign == and != to isTRUE( all.equal() )?

As @joran alluded to, you'll run into floating point issues with == and != in pretty much any other language too. One important aspect of them in R is the vectorization part.

It would be much better to define a new function almostEqual, fuzzyEqual or similar. It is unfortunate that there is no such base function. all.equal isn't very efficient since it handles all kinds of objects and returns a string describing the difference when mostly you just want TRUE or FALSE.

Here's an example of such a function. It's vectorized like ==.

almostEqual <- function(x, y, tolerance=1e-8) {
diff <- abs(x - y)
mag <- pmax( abs(x), abs(y) )
ifelse( mag > tolerance, diff/mag <= tolerance, diff <= tolerance)
}

almostEqual(1, c(1+1e-8, 1+2e-8)) # [1] TRUE FALSE

...it is around 2x faster than all.equal for scalar values, and much faster with vectors.

x <- 1
y <- 1+1e-8
system.time(for(i in 1:1e4) almostEqual(x, y)) # 0.44 seconds
system.time(for(i in 1:1e4) all.equal(x, y)) # 0.93 seconds

A problem on identical() function in R? How does identical() work for different types of objects?

They are not identical precisely because they have different types. If you look at the documentation for identical you'll find the example identical(1, as.integer(1)) with the comment ## FALSE, stored as different types. That's one clue. The R language definition reminds us that:

Single numbers, such as 4.2, and strings, such as "four point two" are still vectors, of length 1; there are no more basic types (emphasis mine).

So, basically everything is a vector with a type (that's also why [1] shows up every time R returns something). You can check this by explicitly creating a vector with length 1 by using vector, and then comparing it to 0:

x <- vector("double", 1)
identical(x, 0)
# [1] TRUE

That is to say, both vector("double", 1) and 0 output vectors of type "double" and length == 1.

typeof and storage.mode point to the same thing, so you're kind of right when you say "this means identical() compares based on storage". I don't think this necessarily means that "bit patterns" are being compared, although I suppose it's possible. See what happens when you change the storage mode using storage.mode:

## Assign integer to x. This is really a vector length == 1.
x <- 1L

typeof(x)
# [1] "integer"

identical(x, 1L)
# [1] TRUE

## Now change the storage mode and compare again.
storage.mode(x) <- "double"

typeof(x)
# [1] "double"

identical(x, 1L) # This is no longer TRUE.
# [1] FALSE

identical(x, 1.0) # But this is.
# [1] TRUE

One last note: The documentation for identical states that num.eq is a…

logical indicating if (double and complex non-NA) numbers should be compared using == (‘equal’), or by bitwise comparison.

So, changing num.eq doesn't affect any comparison involving integers. Try the following:

# Comparing integers with integers.
identical(+0L, -0L, num.eq = T) # TRUE
identical(+0L, -0L, num.eq = F) # TRUE

# Comparing integers with doubles.
identical(+0, -0L, num.eq = T) # FALSE
identical(+0, -0L, num.eq = F) # FALSE

# Comparing doubles with doubles.
identical(+0.0, -0.0, num.eq = T) # TRUE
identical(+0.0, -0.0, num.eq = F) # FALSE

Test for equality among all elements of a single numeric vector

I use this method, which compares the min and the max, after dividing by the mean:

# Determine if range of vector is FP 0.
zero_range <- function(x, tol = .Machine$double.eps ^ 0.5) {
if (length(x) == 1) return(TRUE)
x <- range(x) / mean(x)
isTRUE(all.equal(x[1], x[2], tolerance = tol))
}

If you were using this more seriously, you'd probably want to remove missing values before computing the range and mean.

What is the difference between == and equals() in Java?

In general, the answer to your question is "yes", but...

  • .equals(...) will only compare what it is written to compare, no more, no less.
  • If a class does not override the equals method, then it defaults to the equals(Object o) method of the closest parent class that has overridden this method.
  • If no parent classes have provided an override, then it defaults to the method from the ultimate parent class, Object, and so you're left with the Object#equals(Object o) method. Per the Object API this is the same as ==; that is, it returns true if and only if both variables refer to the same object, if their references are one and the same. Thus you will be testing for object equality and not functional equality.
  • Always remember to override hashCode if you override equals so as not to "break the contract". As per the API, the result returned from the hashCode() method for two objects must be the same if their equals methods show that they are equivalent. The converse is not necessarily true.


Related Topics



Leave a reply



Submit