From m@ech|er @end|ng |rom @t@t@m@th@ethz@ch  Mon Nov  6 12:08:22 2023
From: m@ech|er @end|ng |rom @t@t@m@th@ethz@ch (Martin Maechler)
Date: Mon, 6 Nov 2023 12:08:22 +0100
Subject: [Rd] c(NA, 0+1i) not the same as c(as.complex(NA), 0+1i)?
In-Reply-To: <CAPRVBcx4OxpWDH_cyunMfZ=eLhQCD3V62ka1yQV4y5jCoEXL6A@mail.gmail.com>
References: <CAPRVBcx4OxpWDH_cyunMfZ=eLhQCD3V62ka1yQV4y5jCoEXL6A@mail.gmail.com>
Message-ID: <25928.51494.41600.713713@stat.math.ethz.ch>

>>>>> Michael Chirico 
>>>>>     on Sun, 5 Nov 2023 09:41:42 -0800 writes:

    > This is another follow-up to the thread from September
    > "Recent changes to as.complex(NA_real_)".

    > A test in data.table was broken by the changes for NA
    > coercion to complex; the breakage essentially comes from

    > c(NA, 0+1i)
    > # vs
    > c(as.complex(NA), 0+1i)

    > The former is the output we tested against; the latter is essentially (via
    > coerceVector() in C) what's generated by our data.table::shift()

    > However, these are now (r85472) different:

    > Im(c(NA, 0+1i))
    > # [1] NA  1
    > Im(c(as.complex(NA), 0+1i))
    > # [1] 0 1


    > The former matches the behavior of directly using NA_complex_:

    > Im(c(NA_complex_, 0+1i))
    > # [1] NA  1

    > On R4.3.2, they both match the NA_complex_ behavior:
    > Im(c(NA, 0+1i))
    > # [1] NA  1
    > Im(c(as.complex(NA), 0+1i))
    > # [1] NA 1

    > Is this intended behavior, does something need to be updated for c() as
    > well?

    > Certainly it's messing with my understanding of how c() behaves, e.g. in ?c

    >> All arguments are coerced to a common type which is the type of the
    > returned value

I think you have confused yourself, and everything behaves as expected:

As we now have (in R-devel, since {r85233 | maechler | 2023-09-29 })

  ? ?as.complex(x)? now returns ?complex(real=x, imaginary=0)?
    for _all_ numerical and logical ?x?, notably also for ?NA?
    or ?NA_integer_?.

==> as.complex(NA) is indeed  complex(real = NA, imaginary = 0)

And now, in your

   c(as.complex(NA), 0+1i)

you are calling c() on two complex numbers, i.e., there is *no* coercion
(and c(.) is rather "trivial"),  and the same is true for

   c(NA_complex_, 0+1i)


However, in 85233, I had only modified & added examples to  ?as.complex, 
and now have added more (corresponding to the above NEWS entry);
-> svn rev 85475

.............

The underlying "dilemma" that nobody can help us with is that
"almost infinitely" many different complex numbers z fulfill
 is.na(z) |--> TRUE
and only one of them is  NA_complex_  and that may be unintuitive.

OTOH, we already have for the doubles that there are at least two
different x fulfulling is.na(x), namely  NaN and NA
and from C's point of view there are even considerably more
different NaN's .. but now I'm definitely digressing.
 
Martin



[Rd] c(NA, 0+1i) not the same as c(as.complex(NA), 0+1i)?
Martin Maechler