[Rd] Recent changes to as.complex(NA_real_)
Mikael Jagan
j@g@nmn2 @end|ng |rom gm@||@com
Fri Sep 22 14:14:36 CEST 2023
On 2023-09-22 6:38 am, Martin Maechler wrote:
>>>>>> Mikael Jagan
>>>>>> on Thu, 21 Sep 2023 00:47:39 -0400 writes:
>
> > Revisiting this thread from April:
>
> > https://stat.ethz.ch/pipermail/r-devel/2023-April/082545.html
>
> > where the decision (not yet backported) was made for
> > as.complex(NA_real_) to give NA_complex_ instead of
> > complex(r=NA_real_, i=0), to be consistent with
> > help("as.complex") and as.complex(NA) and as.complex(NA_integer_).
>
> > Was any consideration given to the alternative?
> > That is, to changing as.complex(NA) and as.complex(NA_integer_) to
> > give complex(r=NA_real_, i=0), consistent with
> > as.complex(NA_real_), then amending help("as.complex")
> > accordingly?
>
> Hmm, as, from R-core, mostly I was involved, I admit to say "no",
> to my knowledge the (above) alternative wasn't considered.
>
> > The principle that
> > Im(as.complex(<real=(double|integer|logical)>)) should be zero
> > is quite fundamental, in my view, hence the "new" behaviour
> > seems to really violate the principle of least surprise ...
>
> of course "least surprise" is somewhat subjective. Still,
> I clearly agree that the above would be one desirable property.
>
> I think that any solution will lead to *some* surprise for some
> cases, I think primarily because there are *many* different
> values z for which is.na(z) is true, and in any case
> NA_complex_ is only of the many.
>
> I also agree with Mikael that we should reconsider the issue
> that was raised by Davis Vaughan here ("on R-devel") last April.
>
> > Another (but maybe weaker) argument is that
> > double->complex coercions happen more often than
> > logical->complex and integer->complex ones. Changing the
> > behaviour of the more frequently performed coercion is
> > more likely to affect code "out there".
>
> > Yet another argument is that one expects
>
> > identical(as.complex(NA_real_), NA_real_ + (0+0i))
>
> > to be TRUE, i.e., that coercing from double to complex is
> > equivalent to adding a complex zero. The new behaviour
> > makes the above FALSE, since NA_real_ + (0+0i) gives
> > complex(r=NA_real_, i=0).
>
> No! --- To my own surprise (!) --- in current R-devel the above is TRUE,
> and
> NA_real_ + (0+0i) , the same as
> NA_real_ + 0i , really gives complex(r=NA, i=NA) :
>
Thank you for the correction - indeed, as.complex(NA_real_) and
NA_real_ + (0+0i) are identical in both R-patched and R-devel,
both giving complex(r=NA_real_, i=0) in R-patched and both giving
NA_complex_ in R-devel. I was hallucating, it seems ...
> Using showC() from ?complex
>
> showC <- function(z) noquote(sprintf("(R = %g, I = %g)", Re(z), Im(z)))
>
> we see (in R-devel) quite consistently
>
>> showC(NA_real_ + 0i)
> [1] (R = NA, I = NA)
>> showC(NA + 0i) # NA is 'logical'
> [1] (R = NA, I = NA)
>>
>
> where as in R 4.3.1 and "R-patched" -- *in*consistently
>
>> showC(NA_real_ + 0i)
> [1] (R = NA, I = 0)
>> showC(NA + 0i)
> [1] (R = NA, I = NA)
>>
>
> .... and honestly, I do not see *where* (and when) we changed
> the underlying code (in arithmetic.c !?) in R-devel to *also*
> produce NA_complex_ in such complex *arithmetic*
>
R_binary() in arithmetic.c has always coerced REALSXP->CPLXSXP when
encountering one of each. Surely then the changes in coerce.c are the
cause and this arithmetic behaviour is just a (bad, IMO) side effect?
>
> > Having said that, one might also (but more naively) expect
>
> > identical(as.complex(as.double(NA_complex_)), NA_complex_)
>
> > to be TRUE.
>
> as in current R-devel
>
> > Under my proposal it continues to be FALSE.
>
> as in "R-release"
>
> > Well, I'd prefer if it gave FALSE with a warning
> > "imaginary parts discarded in coercion", but it seems that
> > as.double(complex(r=a, i=b)) never warns when either of
> > 'a' and 'b' is NA_real_ or NaN, even where "information"
> > {nonzero 'b'} is clearly lost ...
>
> The question of *warning* here is related indeed, but I think
> we should try to look at it only *secondary* to your first
> proposal.
>
> > Whatever decision is made about as.complex(NA_real_),
> > maybe these points should be weighed before it becomes part of
> > R-release ...
>
> > Mikael
>
> Indeed.
>
> Can we please get other opinions / ideas here?
>
Thank you, Martin, for "reopening".
Mikael
> Thank you in advance for your thoughts!
> Martin
>
> ---
>
> PS:
>
> Our *print()*ing of complex NA's ("NA" here meaning NA or NaN)
> is also unsatisfactory, e.g. in the case where all entries of a
> vector are NA in the sense of is.na(.), but their
> Re() and Im() are not all NA:
>
> showC <- function(z) noquote(sprintf("(R = %g, I = %g)", Re(z), Im(z)))
> z <- complex(, c(11, NA, NA), c(NA, 99, NA))
> z
> showC(z)
>
> gives
>
> > z
> [1] NA NA NA
> > showC(z)
> [1] (R = 11, I = NA) (R = NA, I = 99) (R = NA, I = NA)
>
> but that (printing of complex) *is* another issue,
> in which we have the re-opened bugzilla PR#16752
> ==> https://bugs.r-project.org/show_bug.cgi?id=16752
>
> on which we also worked during the R Sprint in Warwick three
> weeks ago, and where I want to commit changes in any case {but
> think we should change even a bit more than we got to during the
> Sprint}.
>
More information about the R-devel
mailing list