[Rd] head.matrix can return 1000s of columns -- limit to n or add new argument?

Gabriel Becker g@bembecker @end|ng |rom gm@||@com
Sat Nov 2 20:37:08 CET 2019


Thanks Martin and Peter,

I agree that we can be careful and narrow and still see a nice improvement
in behavior. While Herve's point is valid and I understand his frustration,
I think staying within the matrix vs  c(matrix, array) space is the right
scope for this work in terms of fiddling with inheritance.

As another point,  I don't know off the top of my head of any other classes
which we would expect to have a dimensions attribute other than arrays
(including the "non-array" 2d matrices) and data.frames, but I imagine
there are some out there.

Do we want the default head and tail methods to be dimension aware as well,
via something along the lines of what I had in my previous message, or do
we want to retain the old behavior for things that aren't data.frames or
matrix/arrays? If the dim attribute can always be assumed to mean the same
thing I feel like it would be nice to give the dimensionality awareness
(and idempotence) to anything with dimensions, but again I don't know much
about the other classes taht have that attribute or how people want to use
them.

It would of course be written in a way that still worked identically to now
for any object that does not have a dimension attribute.

Thoughts?

~G

On Fri, Nov 1, 2019 at 1:52 AM Martin Maechler <maechler using stat.math.ethz.ch>
wrote:

> >>>>> peter dalgaard
> >>>>>     on Thu, 31 Oct 2019 23:04:29 +0100 writes:
>
>     > Hmm, the problem I see here is that these implied classes are all
> inherently one-off. We also have
>     >> inherits(matrix(1,1,1),"numeric")
>     > [1] FALSE
>     >> is.numeric(matrix(1,1,1))
>     > [1] TRUE
>     >> inherits(1L,"numeric")
>     > [1] FALSE
>     >> is.numeric(1L)
>     > [1] TRUE
>
>     > and if we start fixing one, we might need to fix all.
>
> I disagree about "fixing all" (see also my reply to Hervé), and
> the {"numeric","double","integer"} case is particularly messy,
> and I don't want to open that can now.
>
>     > For method dispatch, we do have inheritance, e.g.
>
>     >> foo.numeric <- function(x) x + 1
>     >> foo <- function(x) UseMethod("foo")
>     >> foo(1)
>     > [1] 2
>     >> foo(1L)
>     > [1] 2
>     >> foo(matrix(1,1,1))
>     > [,1]
>     > [1,]    2
>     >> foo.integer <- function(x) x + 2
>     >> foo(1)
>     > [1] 2
>     >> foo(1L)
>     > [1] 3
>     >> foo(matrix(1,1,1))
>     > [,1]
>     > [1,]    2
>     >> foo(matrix(1L,1,1))
>     > [,1]
>     > [1,]    3
>
>     > but these are not all automatic: "integer" implies "numeric", but
> "matrix" does not imply "numeric", much less "integer".
>
> well it should not imply in general:
> Contrary to Math,  we also have 'raw' or 'character' or 'logical' matrices.
>
>
>     > Also, we seem to have a rule that inherits(x, c)  iff  c %in%
> class(x),
>
> good point, and that's why my usage of  inherits(.,.) was not
> quite to the point.  [OTOH, it was to the point, as indeed from
>       the ?class / ?inherits docu, S3 method dispatch and inherits
>       must be consistent ]
>
>     > which would break -- unless we change class(x) to return the whole
> set of inherited classes, which I sense that we'd rather not do....
>
> and we have something like that already with  is(.)
>
> Thank you for these important points raised!
>
> Note again that both "matrix" and "array" are special [see ?class] as
> being of  __implicit class__  and I am considering that this
> implicit class behavior for these two should be slightly changed
> such that
>
>   foo <- function(x,...) UseMethod("foo")
>   foo.array <- function(x, ...)
>            sprintf("array of dim. %s", paste(dim(x), collapse = " x "))
>
> should work for all arrays and not be an exception for 2D arrays :
>
> > foo(array(pi, 1:3))
> [1] "array of dim. 1 x 2 x 3"
> > foo(array(pi, 1))
> [1] "array of dim. 1"
> > foo(array(pi, 2:7))
> [1] "array of dim. 2 x 3 x 4 x 5 x 6 x 7"
> > foo(array(pi, 1:2))
> Error in UseMethod("foo") :
>   no applicable method for 'foo' applied to an object of class
> "c('matrix', 'double', 'numeric')"
> >
>
> And indeed I think you are right on spot and this would mean
> that indeed the implicit class
> "matrix" should rather become c("matrix", "array").
>
> BTW: The 'Details' section of   ?class   nicely defines things,
>      notably the __implicit class__ situation
>      (but I think should be improved)  :
>
>      {numbering the paragraphs for reference}
>
> > Details:
> >
> > 1.   Here, we describe the so called “S3” classes (and methods). For
> >      “S4” classes (and methods), see ‘Formal classes’ below.
> >
> > 2.   Many R objects have a class attribute, a character vector giving
> >      the names of the classes from which the object _inherits_.
> >      (Functions oldClass and oldClass<- get and set the attribute,
> >      which can also be done directly.)
> >
> > 3.   If the object does not have a class attribute, it has an implicit
> >      class, notably ‘"matrix"’, ‘"array"’, ‘"function"’ or ‘"numeric"’
> >      or the result of ‘typeof(x)’ (which is similar to ‘mode(x)’), but
> >      for type ‘"language"’ and mode ‘"call"’, where the following
> >      extra classes exist for the corresponding function calls: if,
> >      while, for, =, <-, (, {, call.
>
> So, I think clearly  { for S3, not S4 ! }
>
>   "class attribute" :=  attr(x, "class")
>
>   "implicit class" := the class(x) of R objects that do *not*
>                       have a class attribute
>
>
> > 4.   Note that NULL objects cannot have attributes (hence not
> >      classes) and attempting to assign a class is an error.
>
> the above has one small flaw : "(hence not classes)" is not correct.
> Of course   class(NULL) is "NULL" by par. 3's  typeof(x) "rule".
>
> > 5a.  When a generic function ‘fun’ is applied to an object with class
> >      attribute ‘c("first", "second")’, the system searches for a
> >      function called ‘fun.first’ and, if it finds it, applies it to the
> >      object.  If no such function is found, a function called
> >      ‘fun.second’ is tried.  If no class name produces a suitable
> >      function, the function ‘fun.default’ is used (if it exists).
> > 5b.  If there is no class attribute, the implicit class is tried, then
> the
> >      default method.
>
> > 6.   The function 'class' prints the vector of names of classes an
> >      object inherits from.  Correspondingly, class<- sets the classes
> >      an object inherits from.  Assigning NULL removes the class
> >      attribute.
>
> ["of course", the word  "prints" above should be replaced by "returns" ! ]
>
> > 7.   'unclass' returns (a copy of) its argument with its class
> >      attribute removed.  (It is not allowed for objects which cannot be
> >      copied, namely environments and external pointers.)
>
> > 8.   'inherits' indicates whether its first argument inherits from any
> >      of the classes specified in the ‘what’ argument.  If which is
> >      TRUE then an integer vector of the same length as ‘what’ is
> >      returned.  Each element indicates the position in the ‘class(x)’
> >      matched by the element of ‘what’; zero indicates no match. If
> >      which is FALSE then TRUE is returned by inherits if any of
> >      the names in ‘what’ match with any class.
>
> {I had forgotten that the 2nd argument of inherits, 'what', can
>  be a vector and about the 'which' argument}
>
>
>     >> On 30 Oct 2019, at 12:29 , Martin Maechler <
> maechler using stat.math.ethz.ch> wrote:
>     >>
>     >> Note however the following  historical quirk :
>     >>
>     >>> sapply(setNames(,1:5), function(K) inherits(array(pi, dim=1:K),
> "array"))
>     >> 1     2     3     4     5
>     >> TRUE FALSE  TRUE  TRUE  TRUE
>     >>
>     >> (Is this something we should consider changing for R 4.0.0 -- to
>     >> have it TRUE also for 2d-arrays aka matrix objects ??)
>
>     > --
>     > Peter Dalgaard, Professor,
>     > Center for Statistics, Copenhagen Business School
>     > Solbjerg Plads 3, 2000 Frederiksberg, Denmark
>     > Phone: (+45)38153501
>     > Office: A 4.23
>     > Email: pd.mes using cbs.dk  Priv: PDalgd using gmail.com
>
>
>
>
>
>
>
>
>

	[[alternative HTML version deleted]]



More information about the R-devel mailing list