Re: [R] Correct way to test for exact dimensions of matrix or array

From: Gregory Jefferis <gsxej2_at_cam.ac.uk>
Date: Wed 11 Jan 2006 - 05:58:49 EST


Thanks for suggestions. This is a simple question in principle, but there seem to be some wrinkles - I am always having to think quite carefully about how to test for equality in R. I should also have said that I would like the check to be efficient as well safe and succinct.

One suggestion was:     

    isTRUE(all.equal(dim(obj), c(3, 5)))

But that is not so efficient because all.equal does lots of work esp if it the objects are not equal.

Another suggestion was:

    all( dim( obj) == c(3,5) )     

But that is not safe eg because dim(vector(10)) is NULL and all(NULL==c(3,5)) is actually TRUE (to my initial surprise) so vectors would pass through the net.

So, so far the only way that is efficient, safe and succinct is:

    identical( dim( obj) , as.integer(c(3,5)))

Martin Maechler pointed out that at the beginning of a function you might want to break down the test into something less succinct, that printed more specific error messages - a good suggestion for a top level function that is supposed to be user friendly.

Any other suggestions? Many thanks,

Greg Jefferis.

On 10/1/06 15:13, "Martin Maechler" <maechler@stat.math.ethz.ch> wrote:

>>>>>> "Gregory" == Gregory Jefferis <gsxej2@cam.ac.uk>
>>>>>>     on Tue, 10 Jan 2006 14:47:43 +0000 writes:

>
> Gregory> Dear R Users,
>
> Gregory> I want to test the dimensions of an incoming
> Gregory> vector, matrix or array safely
>
>
> Gregory> and succinctly. Specifically I want to check if
> Gregory> the unknown object has exactly 2 dimensions with a
> Gregory> specified number of rows and columns.
>
> Gregory> I thought that the following would work:
>
>>> obj=matrix(1,nrow=3,ncol=5)
>>> identical( dim( obj) , c(3,5) )

> Gregory> [1] FALSE
>
> Gregory> But it doesn't because c(3,5) is numeric and the dims are
> integer. I
> Gregory> therefore ended up doing something like:
>
>>> identical( dim( obj) , as.integer(c(3,5)))

>
> Gregory> OR
>
>>> isTRUE(all( dim( obj) == c(3,5) ))

>
> the last one is almost perfect if you leave a way the superfluous
> isTRUE(..).
>
> But, you say that it's part of your function checking it's
> arguments.
> In that case, I'd recommend
>
> if(length(d <- dim(obj)) != 2)
> stop("'d' must be matrix-like")
> if(!all(d == c(3,5)))
> stop("the matrix must be 3 x 5")
>
> which also provides for nice error messages in case of error.
> A more concise form with less nice error messages is
>
> stopifnot(length(d <- dim(obj)) == 2,
> d == c(3,50))
>
> ## you can leave away all(.) for things in stopifnot(.)
>
>
>
>
> Gregory> Neither of which feel quite right. Is there a 'correct' way to
> do this?
>
> Gregory> Many thanks,
>
> You're welcome,
> Martin Maechler, ETH Zurich
>
> Gregory> Greg Jefferis.
>
> Gregory> PS Thinking about it, the second form is (doubly) wrong because:
>
>>> obj=array(1,dim=c(3,5,3,5))
>>> isTRUE(all( dim( obj) == c(3,5) ))

> Gregory> [1] TRUE
>
> Gregory> OR
>>> obj=numeric(10) >>> isTRUE(all( dim( obj) == c(3,5) ))
> Gregory> [1] TRUE
>
> Gregory> (neither of which are equalities that I am happy with!)
>
-- 
Gregory Jefferis, PhD                               and:
Research Fellow    
Department of Zoology                               St John's College
University of Cambridge                             Cambridge
Downing Street                                      CB2 1TP
Cambridge, CB2 3EJ 
United Kingdom

Tel: +44 (0)1223 336683                             +44 (0)1223 339899
Fax: +44 (0)1223 336676                             +44 (0)1223 337720

gsxej2@cam.ac.uk

______________________________________________
R-help@stat.math.ethz.ch mailing list
https://stat.ethz.ch/mailman/listinfo/r-help
PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
Received on Wed Jan 11 06:06:03 2006

This archive was generated by hypermail 2.1.8 : Fri 03 Mar 2006 - 03:41:59 EST