[Rd] prettyNum digits=0 not compatible with scientific notation
peter dalgaard
pd@|gd @end|ng |rom gm@||@com
Fri Mar 22 17:30:19 CET 2019
FWIW, it doesn't seem to be happening on Mac OS:
> format(2^30, digits=0)
[1] "1.e+09"
> prettyNum(12345.6, digits=0)
[1] "1.e+04"
A glibc misfeature?
-pd
> On 22 Mar 2019, at 10:10 , Martin Maechler <maechler using stat.math.ethz.ch> wrote:
>
> Thank you, Robert for raising this here !
>
>>>>>> Robert McGehee
>>>>>> on Thu, 21 Mar 2019 20:56:19 +0000 writes:
>
>> R developers,
>> Seems I get a bad result ("%#4.0-1e" in particular) when trying to use prettyNum digits=0 with scientific notation. I tried on both my Linux box and on an online R evaluator and saw the same problem, so it's not limited to my box at least. I see the problem in both R 3.5.3 and R 3.3.2.
>
>> options(scipen= -100)
>
> The above is extreme: You're basically setting an option to
> always see non-integer numbers in "scientific" format ..
> But read below about what 'digits' means in this case.
>
>> prettyNum(1, digits=0)
>> [1] "%#4.0-1e"
>> prettyNum(2, digits=0)
>> [1] "%#4.0-1e"
>> prettyNum(1, digits=0, scientific=FALSE) # Works
>> [1] "1"
>> prettyNum(1:2, digits=0) # Works
>> [1] "1" "2"
>> prettyNum(c(1.1, 2.1), digits=0)
>> [1] "%#4.0-1e" "%#4.0-1e"
>> prettyNum(c(1.1, 2.1), digits=1) # Works
>> [1] "1e+00" "2e+00"
>
> I'm the scape goat / culprit /.. : I have worked on tweaking the
> formatting of (non integer) numbers in R for a long time, on the
> way introducing prettyNum(), also already long ago...
> but then it's actually not prettyNum() but rather format() here :
>
> Have you read its help page - *with* care?
>
> If you do, you'd notice that 'digits' is not among the formal arguments
> of prettyNum() *and* that prettyNum() passes all its `...` to format().
> And if you read ?format [which then you should to understand 'digits' !]
> you see
>
>> digits: how many significant digits are to be used for numeric and
>> complex ‘x’. The default, NULL, uses ‘getOption("digits")’.
>> This is a suggestion: enough decimal places will be used so that
>> the smallest (in magnitude) number has this many significant
>> digits, and also to satisfy ‘nsmall’.
>
>> [.....]
>
> So, for the real numbers you use in your example, digits are
> *significant* digits as in 'options(digits= *)' or
> 'print(.., digits= *)'
>
> ------ Excursion about 'integer' and format()ing ------------
> -- and you now may also understand why prettyNum(1:2, digits=0) works
> as you expect: integer formatting behaves differently ....
> but I acknowledge that the ?format help page does not say so
> explicitly yet: it 'real and complex' numbers for the
> 'scientific' argument, and 'numeric and complex' numbers for
> the 'format' argument.
> If you replac numeric by reald, what this entails (by logic)
> that 'integer' numbers are *not* affected by 'digits' nor 'scientific'.
>
> But there's yet more subtlety: 'integer' here means class/type "integer"
> and not just an integer number, i.e., the difference of 1L and 1 :
>
>> str(1)
> num 1
>> str(1L)
> int 1
>> str(1:3)
> int [1:3] 1 2 3
>> str(1:3 + 0)
> num [1:3] 1 2 3
>>
> ------ end of Excursion{'integer' ..} -------------------------------
>
> Back to real numbers : 'digits' are used as *significant* digits
> (and are only a suggestion: format() and prettyNum() ensure
> a common width for their resulting strings so printing will be
> nicely aligned), see e.g.
>
>> format(3.14, scientific=FALSE)
> [1] "3.14"
>> format(3.14*c(1, 1e-7), scientific=FALSE)
> [1] "3.140000000" "0.000000314"
>>
>
> So back to your examples : What would you mean with
> ``0 significant digits'' ?
> It really does not make sense to show *no* significant digits ..
>
> Intuitively, without spending enough time, I'd say that the bug
> in format.default() -- which is called by prettyNum() in
> this case -- is that it does *not* treat
> 'digits = 0' as 'digits = 1' in this case.
>
> NB: digits = 0 has been valid in options(digits = 0) etc,
> "forever" I think, possibly inherited from S, but I don't
> really know and I wonder if we should not make it invalid eventually
> requiring at least 1.
> So we could make it raise a *warning* (and set it to '1') for now.
> What do others think?
>
> Anyone with S(-PLUS) or Terr or .. who can report if digits=0
> is allowed there and what it does in a simple situation like
>
>> format(as.integer(2^30), digits=0) # digits not used at all
> [1] "1073741824"
>> format(2^30, digits=0)
> [1] "%#4.0-1e"
>>
>
>
> Last but not least: If you really want to use exponential
> format, you should typically use sprintf() or formatC() where
> you can tweak to get what you want.
>
> ______________________________________________
> R-devel using r-project.org mailing list
> https://stat.ethz.ch/mailman/listinfo/r-devel
--
Peter Dalgaard, Professor,
Center for Statistics, Copenhagen Business School
Solbjerg Plads 3, 2000 Frederiksberg, Denmark
Phone: (+45)38153501
Office: A 4.23
Email: pd.mes using cbs.dk Priv: PDalgd using gmail.com
More information about the R-devel
mailing list