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

Martin Maechler maechler at stat.math.ethz.ch
Wed Jan 11 09:23:32 CET 2006


>>>>> "Gabor" == Gabor Grothendieck <ggrothendieck at gmail.com>
>>>>>     on Tue, 10 Jan 2006 14:47:57 -0500 writes:

    Gabor> If its just succint you are after then this is slightly
    Gabor> shorter:

    Gabor> identical(dim(x)+0, c(3,5))

indeed, or, less succinct, but maybe more readable (and along the
"top-level function checks" I had proposed yesterday):

     !is.null(d <- dim(x)) && all(d == c(3,5))



    Gabor> On 1/10/06, Gregory Jefferis <gsxej2 at cam.ac.uk> wrote:
    >> 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 at stat.math.ethz.ch> wrote:
    >> 
    >> >>>>>> "Gregory" == Gregory Jefferis <gsxej2 at 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 at cam.ac.uk
    >> 
    >> ______________________________________________
    >> R-help at 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
    >>




More information about the R-help mailing list