[Rd] Possible inconsistency between `as.complex(NA_real_)` and the docs
Martin Maechler
m@ech|er @end|ng |rom @t@t@m@th@ethz@ch
Sat Apr 22 18:41:26 CEST 2023
> Hi all,
>
> Surprisingly (at least to me), `as.complex(NA_real_)` results in
> `complex(real = NA_real_, imaginary = 0)` rather than `NA_complex_`.
Well, the logic here is really the mathematical equivalence:
if you turn a real number x in to a complex one, say z,
then z = x + i * 0 , i.e., real part x and imaginary part 0.
> It seems to me that this goes against the docs of `as.complex()`,
> which say this in the Details section:
>
> "Up to R versions 3.2.x, all forms of NA and NaN were coerced to a
> complex NA, i.e., the NA_complex_ constant, for which both the real
> and imaginary parts are NA. Since R 3.3.0, typically only objects
> which are NA in parts are coerced to complex NA, but others with NaN
> parts, are not. As a consequence, complex arithmetic where only NaN's
> (but no NA's) are involved typically will not give complex NA but
> complex numbers with real or imaginary parts of NaN."
The above was written in svn commit 69410 (the github mirror
of which you mention below)
------------------------------------------------------------------------
r69410 | maechler | 2015-09-22 10:11:34 +0200 (Tue, 22 Sep 2015) | 1 line
more consistent behavior of complex number NaN / NA - not back-compatible
------------------------------------------------------------------------
which I had to amend a day later in
------------------------------------------------------------------------
r69423 | maechler | 2015-09-23 19:23:57 +0200 (Wed, 23 Sep 2015) | 1 line
even NaN + NA_complex_ is platform dependent
------------------------------------------------------------------------
just with adding the following at the end of
example(as.complex) :
showC <- function(z) noquote(sprintf("(R = \%g, I = \%g)", Re(z), Im(z)))
## The exact result of this *depends* on the platform, compiler, math-library:
(NpNA <- NaN + NA_complex_) ; str(NpNA) # *behaves* as 'cplx NA' ..
stopifnot(is.na(NpNA), is.na(NA_complex_), is.na(Re(NA_complex_)), is.na(Im(NA_complex_)))
showC(NpNA)# but not always is {shows '(R = NaN, I = NA)' on some platforms}
## and this is not TRUE everywhere:
identical(NpNA, NA_complex_)
showC(NA_complex_) # always == (R = NA, I = NA)
And that was a while ago. In the mean time I've become more
aware of the fact that --- to my large chagrin --- our
distinction of NA and NaN unfortunately has more problems in
quite platform-dependent arithmetic than I had still hoped at
the time.
> To me this suggests that `NA_real_`, which is "NA in parts", should
> have been coerced to "complex NA".
>
> `NA_integer_` is actually coerced to `NA_complex_`, which to me is
> further evidence that `NA_real_` should have been as well.
Yeah.. I agree that as.complex(.) should return the same for integer
and double NA.
I see where and how the change would need to happen.
.. we'll see if it is feasible (I guess "yes" with 0.98 subjective probability)
> Here is the original commit where this behavior was changed in R 3.3.0:
> https://github.com/wch/r-source/commit/4a4c2052e5a541981a249d4fcf92b54ca7f0a2df
>
> ```
> # This is expected, based on the docs
> x <- as.complex(NaN)
> Re(x)
> #> [1] NaN
> Im(x)
> #> [1] 0
>
> # This is not expected. The docs say:
> # "Since R 3.3.0, typically only objects which are NA in parts are
> coerced to complex NA"
> # but that doesn't seem true for `NA_real_`.
> x <- as.complex(NA_real_)
> Re(x)
> #> [1] NA
> Im(x)
> #> [1] 0
>
> # It does seem to be the case for `NA_integer_`
> x <- as.complex(NA_integer_)
> Re(x)
> #> [1] NA
> Im(x)
> #> [1] NA
> ```
>
> Thanks,
> Davis Vaughan
>
> ______________________________________________
> R-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
More information about the R-devel
mailing list