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 overrideequals
so as not to "break the contract". As per the API, the result returned from thehashCode()
method for two objects must be the same if theirequals
methods show that they are equivalent. The converse is not necessarily true.
Related Topics
Get a List of the Data Sets in a Particular Package
Issue with Ggplot2, Geom_Bar, and Position="Dodge": Stacked Has Correct Y Values, Dodged Does Not
How to Conditionally Highlight Points in Ggplot2 Facet Plots - Mapping Color to Column
R: Extracting "Clean" Utf-8 Text from a Web Page Scraped with Rcurl
Combining New Lines and Italics in Facet Labels with Ggplot2
(Igraph) Grouped Layout Based on Attribute
Datalabels in R Highcharter Cannot Be Seen After Print as Png or Jpg
Create a Ranking Variable with Dplyr
Horizontal Dendrogram in R with Labels
Add Image in Title Page of Rmarkdown PDF
Ggplot: Boxplot of Multiple Column Values
In Ggplot2, Coord_Flip and Free Scales Don't Work Together
How to Find the Indices of the Top 10,000 Elements in a Symmetric Matrix(12K X 12K) in R