[Rd] Format printing inside a matrix
Martin Maechler
m@ech|er @end|ng |rom @t@t@m@th@ethz@ch
Mon Jul 15 11:30:08 CEST 2019
>>>>> Pages, Herve
>>>>> on Mon, 8 Jul 2019 04:32:29 +0000 writes:
> On 7/7/19 17:41, Jialin Ma wrote:
>> Hi Abby,
>>
>> Thanks a lot for your paraphrasing and your suggestion!
>>
>> The problem of wrapping the list into a S3/S4 object, i.e. subclassing array
>> or matrix, is that one also has to define a bunch of methods for subsetting,
>> joining, etc, in order to make it behave like a list array. The reason is that
>> most R functions for subsetting, joining, etc. do not preserve class
>> attributes of the input, which is possibly by design.
> Is it? One could argue that a more sensible behavior would be that
> things like `[`(..., drop=FALSE), rbind(), cbind(), etc... preserve
> the class attribute.
> Interestingly t() does that:
> m <- matrix(1:6, nrow=2)
> class(m) <- "foo"
> m
> # [,1] [,2] [,3]
> # [1,] 1 3 5
> # [2,] 2 4 6
> # attr(,"class")
> # [1] "foo"
> t(m)
> # [,1] [,2]
> # [1,] 1 2
> # [2,] 3 4
> # [3,] 5 6
> # attr(,"class")
> # [1] "foo"
> but not aperm() (which in this case would be expected to be
> equivalent to t()):
> aperm(m, 2:1)
> # [,1] [,2]
> # [1,] 1 2
> # [2,] 3 4
> # [3,] 5 6
> Reshaping also preserves the class:
> dim(m) <- c(6, 1)
> m
> # [,1]
> # [1,] 1
> # [2,] 2
> # [3,] 3
> # [4,] 4
> # [5,] 5
> # [6,] 6
> # attr(,"class")
> # [1] "foo"
> So if it makes sense for t() and reshaping, it's not clear why it
> wouldn't for [, aperm(), cbind(), etc...?
> H.
I think I definitely tend to agree for aperm(); all others are
(slightly or much) more dubious to me however :
- `[`: yes probably, but only if drop=FALSE is used, so,
e.g. dim & dimnames attributes will be kept {modified to the
new dimensions of course}
- cbind(), rbind():
Here we are talking about an arbitrary number of arguments,
each potentially with different and partly conflicting
attributes, notably 'class'.
Of course there are -- sometimes quite sophisticated -- S3
and S4 methods that may apply here typically ((notably for
specialized matrices, "my" Matrix and Rmpfr packages being
mentioned)).
For the (internal C code based) default method, a point could
be made for trying to keep some attributes of the first
argument; but I'm not convinced really yet that it would be
wise to change behavior of the (base internal) default method
for the cbind() / rbind() twin.
>> It is not desirable if a
>> simple matrix subsetting will remove the class attributes of the object.
The sentence above in its generality is wrong, sorry.
Think e.g. of the class "symmetricMatrix", or imagine "covarianceMatrix"
or similar: Almost all subsetting will change the most
important "property" of the class and keeping the class
attribute would be clearly internally inconsistent and wrong.
{and also consider that subsetting in R can be with repeated
indices, say m[c(1:10, 1:20, 20:1) , ] }
>> There are also many other common functions that are meant to drop the
>> attributes of the input, e.g. lapply, apply -- they are not generics and it is
>> not wise to override them.
>>
>> Overall, introducing a new S3/S4 class often brings some extra price in order
>> to maintain the correct behavior,
that is correct
>> which is why I tend to avoid them unless it is necessary.
well, it is never absolutely necessary, I'd say.
{ you could tell your users that your objects must only be
accessed in one of a few possible ways and all other "access", i.e.,
function calls with them as arguments is "forbidden" / "undefined" ...
.. but your users will not follow what you told them, e.g., if
your objects look closely like other R objects they already
know very well ...
}
So, I'm convinced good programmers should
pay the extra price _once_
for the benefit of their package useRs and often themselves _forever_
(after that initial price has been paid).
Martin
>> Best regards,
>> Jialin
>>
>> On Sunday, July 7, 2019 4:43:59 PM PDT Abby Spurdle wrote:
>>> contains an array of question marks, which
>>> isn't helpful.
>>>
>>> Would it be possible for the print method for both matrices and arrays
>>> (conditional on having a list type), call the format method for each
>>> object, possibly creating a character matrix?
>>> Presumably there are other approaches, but the main thing is that the
>>> output is useful and it's easy for R users to control the way objects (in
>>> matrices and arrays) are printed.
>>>
>>>> Or is there any other place that I can override without introducing a new
>>>
>>> S3 class?
>>>
>>> In theory, the simplest approach is to redefine the print method for
>>> matrices.
>>> However, that would be unacceptable in a CRAN package, probably...
>>>
>>> So, unless R Core change the print method, you may have to create a matrix
>>> subclass.
>>
>> ______________________________________________
>> R-devel using r-project.org mailing list
>> https://urldefense.proofpoint.com/v2/url?u=https-3A__stat.ethz.ch_mailman_listinfo_r-2Ddevel&d=DwIFAg&c=eRAMFD45gAfqt84VtBcfhQ&r=BK7q3XeAvimeWdGbWY_wJYbW0WYiZvSXAJJKaaPhzWA&m=CFwIFXl8lv7HqmAdD6GKNJ6jlR0VRL1Ek1iGNO_suAk&s=Mhiq-DX7GTrcmqUFXKjuATvQy8Zs6op359DAMvOrois&e=
>>
> --
> Hervé Pagès
> Program in Computational Biology
> Division of Public Health Sciences
> Fred Hutchinson Cancer Research Center
> 1100 Fairview Ave. N, M1-B514
> P.O. Box 19024
> Seattle, WA 98109-1024
> E-mail: hpages using fredhutch.org
> Phone: (206) 667-5791
> Fax: (206) 667-1319
> ______________________________________________
> R-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
More information about the R-devel
mailing list