[Rd] RFC: diag(x, n) not preserving integer and logical x

Martin Maechler maechler at stat.math.ethz.ch
Thu Aug 7 10:51:51 CEST 2014

This is not at all something new(*). As maintainer of the
Matrix  package, I don't like this inconsistency of base R's diag().
We have had the following -- forever, almost surely inherited
from S and S+  :

diag(x) preserves the storage mode of x  for  'complex' and
'double' precision,  but converts integer and logicals to double :

  > storage.mode(x <- 1i + 1:7); storage.mode(diag(x))
  [1] "complex"
  [1] "complex"
  > storage.mode(x <- 0 + 1:7);  storage.mode(diag(x))
  [1] "double"
  [1] "double"

  > storage.mode(x <- 1:7);      storage.mode(diag(x))
  [1] "integer"
  [1] "double"
  > storage.mode(x <- 1:7 > 3);  storage.mode(diag(x))
  [1] "logical"
  [1] "double"

and so it is actually a bit cumbersome (and a memory waste in
the case of large matrices) to create a diagonal integer or
logical matrix.

The help page does not mention the current behavior, though you
may say it alludes to the fact that logicals are treated as 0/1
implicitly (**)

If I change this behavior such that logical and integer x are

	make check-all

which includes all checks, including those of all recommended
packages (including Matrix!) successfully runs through; so at
least  base + Recommended R never relies on the current
behavior, nor should any "well programmed" R code ...

Hence my proposal, somewhat tentative for now,
to change this  diag(.) behavior.

Martin Maechler

*) and possibly something we "can not" change in R, because too
   much code implicitely may be depending on it,  but now I hope
   we can still...

**) BTW, also including the somewhat amusing case of diag(c("A","B")).

More information about the R-devel mailing list