peter dalgaard
2019-Mar-22 16:30 UTC
[Rd] prettyNum digits=0 not compatible with scientific notation
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 at 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 at 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 at cbs.dk Priv: PDalgd at gmail.com
Martin Maechler
2019-Mar-22 17:07 UTC
[Rd] prettyNum digits=0 not compatible with scientific notation
>>>>> peter dalgaard >>>>> on Fri, 22 Mar 2019 17:30:19 +0100 writes:> 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? It seems (and note we are talking about format.default() here, of which prettyNum() is only a wrapper in this case): Here's an example that shows that 'digits=0' actually can make "sense" contrary to what I've claimed previously:: nn <- 123456*10^(0:-8); dd <- c(10, 7, 2:0); names(dd) <- paste0("d=",dd) sapply(dd, function(dig) sapply(nn, format, digits=dig)) gives (on Linux R 3.5.3, Fedora 28) d=10 d=7 d=2 d=1 d=0 [1,] "123456" "123456" "123456" "1e+05" "%#4.0-1e" [2,] "12345.6" "12345.6" "12346" "12346" "%#4.0-1e" [3,] "1234.56" "1234.56" "1235" "1235" "1235" [4,] "123.456" "123.456" "123" "123" "123" [5,] "12.3456" "12.3456" "12" "12" "12" [6,] "1.23456" "1.23456" "1.2" "1" "1" [7,] "0.123456" "0.123456" "0.12" "0.1" "0" [8,] "0.0123456" "0.0123456" "0.012" "0.01" "0" [9,] "0.00123456" "0.00123456" "0.0012" "0.001" "0" but probably looks better on Mac and on our "Windows Server x64 (build 14393)", for both Platforms i386-w64-mingw32/i386 (32-bit) x86_64-w64-mingw32/x64 (64-bit) is slightly "better": d=10 d=7 d=2 d=1 d=0 [1,] "123456" "123456" "123456" "1e+05" "1.234560e+05" [2,] "12345.6" "12345.6" "12346" "12346" "1.234560e+04" [3,] "1234.56" "1234.56" "1235" "1235" "1235" [4,] "123.456" "123.456" "123" "123" "123" [5,] "12.3456" "12.3456" "12" "12" "12" [6,] "1.23456" "1.23456" "1.2" "1" "1" [7,] "0.123456" "0.123456" "0.12" "0.1" "0" [8,] "0.0123456" "0.0123456" "0.012" "0.01" "0" [9,] "0.00123456" "0.00123456" "0.0012" "0.001" "0" ... interesting ... Martin >> On 22 Mar 2019, at 10:10 , Martin Maechler <maechler at 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 at 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 at cbs.dk Priv: PDalgd at gmail.com
peter dalgaard
2019-Mar-22 23:25 UTC
[Rd] prettyNum digits=0 not compatible with scientific notation
> On 22 Mar 2019, at 18:07 , Martin Maechler <maechler at stat.math.ethz.ch> wrote: > > gives (on Linux R 3.5.3, Fedora 28) > > d=10 d=7 d=2 d=1 d=0 > [1,] "123456" "123456" "123456" "1e+05" "%#4.0-1e" > [2,] "12345.6" "12345.6" "12346" "12346" "%#4.0-1e" > [3,] "1234.56" "1234.56" "1235" "1235" "1235" > [4,] "123.456" "123.456" "123" "123" "123" > [5,] "12.3456" "12.3456" "12" "12" "12" > [6,] "1.23456" "1.23456" "1.2" "1" "1" > [7,] "0.123456" "0.123456" "0.12" "0.1" "0" > [8,] "0.0123456" "0.0123456" "0.012" "0.01" "0" > [9,] "0.00123456" "0.00123456" "0.0012" "0.001" "0" > > but probably looks better on MacYes (3.5.1 though)> nn <- 123456*10^(0:-8); dd <- c(10, 7, 2:0); names(dd) <- paste0("d=",dd) > sapply(dd, function(dig) sapply(nn, format, digits=dig))d=10 d=7 d=2 d=1 d=0 [1,] "123456" "123456" "123456" "1e+05" "1.e+05" [2,] "12345.6" "12345.6" "12346" "12346" "1.e+04" [3,] "1234.56" "1234.56" "1235" "1235" "1235" [4,] "123.456" "123.456" "123" "123" "123" [5,] "12.3456" "12.3456" "12" "12" "12" [6,] "1.23456" "1.23456" "1.2" "1" "1" [7,] "0.123456" "0.123456" "0.12" "0.1" "0" [8,] "0.0123456" "0.0123456" "0.012" "0.01" "0" [9,] "0.00123456" "0.00123456" "0.0012" "0.001" "0" -- 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 at cbs.dk Priv: PDalgd at gmail.com
Reasonably Related Threads
- prettyNum digits=0 not compatible with scientific notation
- prettyNum digits=0 not compatible with scientific notation
- prettyNum digits=0 not compatible with scientific notation
- prettyNum digits=0 not compatible with scientific notation
- prettyNum inserts leading commas (PR#1548)