all.equal - cut two, test.equal
Paul Gilbert
pgilbert@bank-banque-canada.ca
Thu, 14 May 1998 11:06:11 -0400
Below is a second cut at all.equal and also a generic function test.equal which
is intended to return a T/F value. The default method uses all.equal, which is
the reason I was looking for all.equal in the first place. Prompted by Thomas
Lumley's observation that a T/F result makes more sense I thought it would be
worthwhile to indicate what I'm really doing.
I have been using test.equal for a few years in a fairly extensive set of tests
for my time series library. My tests never get to the all.equal part of the
default method, so I have only just noticed the absence of this function. This
approach to testing equality works very well since it allows for a class
specific definition of when things are equal. It was originally suggested to me
by John Chambers, in the context of a question I had about error trapping which,
since I'm on the subject, I will describe shortly in a separate post.
One shortcoming of the following all.equal is that numeric elements of a list
are not compared using tolerance. If anyone has a simple suggestion for
extracting the numeric parts of a list I would like to incorporate it.
Paul Gilbert
_______
test.equal <-function (obj1, obj2, ...) UseMethod("test.equal")
test.equal.default <-function (obj1, obj2, ...)
{ if (is.array(obj1)) test.equal.array(obj1, obj2, ...)
else is.logical(all.equal(obj1, obj2, ...))
}
all.equal <- function(obj1, obj2, tolerance=100*Machine()$double.eps)
{if(mode(obj1) != mode(obj2) ) return("modes differ.")
if (length(obj1) != length(obj2) ) return("lengths differ")
if(is.null(class(obj1)) != is.null(class(obj2))) return("classes differ.")
else if(!is.null(class(obj1))
&& any(class(obj1) != class(obj2)) ) return("classes differ.")
if(is.null(attributes(obj1)) != is.null(attributes(obj2)))
return("attributes differ.")
else if(!is.null(attributes(obj1))
&& any(unlist(attributes(obj1)) != unlist(attributes(obj2))))
return("attributes differ.")
# The mode test above insures that both are numeric if one is. A shortcoming
# here is that for a list with some numeric components, the components are
# not compared using the tolerance test.
if(is.numeric(obj1))
{if (any(abs(obj1 -obj2) > tolerance))
return("value differences exceed tolerance.") }
else if (! all(unlist(obj1) == unlist(obj2))) return("values differ.")
T
}
-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-
r-devel mailing list -- Read http://www.ci.tuwien.ac.at/~hornik/R/R-FAQ.html
Send "info", "help", or "[un]subscribe"
(in the "body", not the subject !) To: r-devel-request@stat.math.ethz.ch
_._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._._