[R] number of decimal

Marc Schwartz marc_schwartz at me.com
Thu Jan 28 18:08:38 CET 2010


On Jan 28, 2010, at 10:04 AM, David Winsemius wrote:

> 
> On Jan 28, 2010, at 10:55 AM, Marc Schwartz wrote:
> 
>> Ivan,
>> 
>> The default behavior for print()ing objects to the console in an R session is via the use of the print.* methods. For real numerics, print.default() is used and the format is based upon the number of significant digits, not the number of decimal places. There is also an interaction with par("scipen"), which influences when scientific notation is used. See ?print.default for more information on defaults and behavior, taking note of the 'digits' argument, which is influenced by options("digits").
>> 
>> Importantly, you need to differentiate between how R stores numeric real values and how it displays or prints them. Internally, R stores real numbers using a double precision data type by default.
>> 
>> The internal storage is not truncated by default and is stored to full precision for doubles, within binary representation limits. You can of course modify the values using functions such as round() or truncate(), etc. See ?round for more information.
>> 
>> For display, Peter has already pointed you to sprintf() and related functions, which allow you to format output for "pretty printing" to things like column aligned tables and such. Those do not however, affect the default output to the R console.
> 
> If one alters print.default, one can get different behavior, for instance:
> 
> print.default <- function (x, digits = NULL, quote = TRUE, na.print = NULL, print.gap = NULL,
>    right = FALSE, max = NULL, useSource = TRUE, ...)
> {if (is.numeric(x)) {x <- as.numeric(sprintf("%7.3f", x))}
>    noOpt <- missing(digits) && missing(quote) && missing(na.print) &&
>        missing(print.gap) && missing(right) && missing(max) &&
>        missing(useSource) && length(list(...)) == 0L
>    .Internal(print.default(x, digits, quote, na.print, print.gap,
>        right, max, useSource, noOpt))
> }
> 
> This will have the requested effect for numeric vectors, but does not seem to be altering the behavior of print.data.frame().
> 
> > print(ac2)
>       score pt times trt
> 1  28.825139  1     0   1
> 2  97.458521  1     3   1
> 3  26.217289  1     6   1
> 4  80.636507  2     0   1
> 5  99.729364  2     3   1
> 6  85.812312  2     6   1
> 7   2.515870  3     0   1
> 8   3.893545  3     3   1
> 9  55.666848  3     6   1
> 10 21.966027  4     0   1
> > print(ac2$score)
> [1] 28.825 97.459 26.217 80.637 99.729 85.812  2.516  3.894 55.667 21.966
> 


David,

The issue there is that when printing the vector, you are using print.default() directly, so you get the desired result with a numeric vector. 

When you print the data frame, internally print.data.frame() calls format.data.frame(), which then internally uses format() on a column-by-column basis and there is the rub. format() brings you back to using significant digits on numeric vectors and of course returns a character vector. By the time the output is actually print()ed to the console, the original data frame has been converted to a formatted character matrix and that is what gets printed.

> str(format.data.frame(ac2))
'data.frame':	10 obs. of  4 variables:
 $ score:Class 'AsIs'  chr [1:10] "28.825139" "97.458521" "26.217289" "80.636507" ...
 $ pt   :Class 'AsIs'  chr [1:10] "1" "1" "1" "2" ...
 $ times:Class 'AsIs'  chr [1:10] "0" "3" "6" "0" ...
 $ trt  :Class 'AsIs'  chr [1:10] "1" "1" "1" "1" ...


> str(format.data.frame(ac2, digits = 2))
'data.frame':	10 obs. of  4 variables:
 $ score:Class 'AsIs'  chr [1:10] " 28.8" " 97.5" " 26.2" " 80.6" ...
 $ pt   :Class 'AsIs'  chr [1:10] "1" "1" "1" "2" ...
 $ times:Class 'AsIs'  chr [1:10] "0" "3" "6" "0" ...
 $ trt  :Class 'AsIs'  chr [1:10] "1" "1" "1" "1" ...


This is why changing print.default() by itself is not sufficient. Other object classes are formatted and printed in varying ways and print methods have been defined for them which may not use it directly. 

HTH,

Marc Schwartz



More information about the R-help mailing list