> c <- -4.2e+10 + 2.4e-10i
> c1 <- eval(parse(text = deparse(c)))
> c == c1
Note that the actual components of the number are correct, it's only string representation that is broken:
The default display rounds complex values according to options('digits'), where the larger of Im(x) and Re(x) determines the scale. If you want something closer to a faithful display of values where the scales differ, you'll need to use deparse(x, control = "digits17").
I've tried "digits17", but that produces undesirable whitespace padding in the same scenario:
> deparse(c, control = "digits17")
 "-42000000000 + 2.4e-10i"
Ideally, I'd also like for the output to prefer the exponent notation if it's shorter (as %g usually does), rather than having it try to actually spell it out in full - i.e. as close to the original input as possible.
Is there any way to do so with deparse function family, without special-casing complex?
As Duncan says this is "by design" (from Aug.2005) and is also documented ... though that documentation is in ?round (base/man/Round.Rd) and hence pretty hidden when you search the help pages ?deparse, ?print, ?format, ?as.character.
I'd accept it as both "documentation bug" and "wishlist", the latter because I do believe we can do better. This indeed is only P5 priority.
Let me clarify what I'm actually trying to do here - perhaps there's an altogether different and better way to achieve that.
I'm a developer working on RTVS (R Tools for Visual Studio). As part of that, we've implemented a debugger, including support for the IDE Locals tool window, that displays local variables with their values and types for a given stack frame / environment.
Variable values are meant to be editable, and so, in general, language plugins in VS use the same representation for values in Locals as the syntax of the language itself, and where there's no literal for that value, use the best available parseable representation - such that, when the user edits the value, the edited representation can be re-evaluated and assigned.
The secondary consideration is that the value should also have the most compact representation possible, because it is displayed in a small window with many other values, so information density is important.
For Python, for example, this representation is provided by repr().
For R, our assumption, based on the documentation, has been that deparse() is the best candidate. It does seem to work really well in most cases - obviously, it's not always 100% round-trippable, nor does it guarantee to be - but for pretty much all basic types, and even many aggregates, it works great in practice. Except for this particular corner case, where the default behavior is not round-trippable (and so user is limited in their ability to edit the value); and using "digits17" results in a significantly longer representation, even though the shorter exponential form would be just as accurate.
Did we go wrong with using deparse() for this purpose? Or is it just a special case that needs to be handled as such?