[R] Format wanted...

Marc Schwartz marc_schwartz at me.com
Sun Mar 25 16:45:38 CEST 2012


On Mar 25, 2012, at 7:14 AM, Duncan Murdoch wrote:

> On 12-03-24 10:47 PM, J Toll wrote:
>> On Sat, Mar 24, 2012 at 7:30 PM, Duncan Murdoch
>> <murdoch.duncan at gmail.com>  wrote:
>>> Do we have a format that always includes a decimal point and a given number
>>> of significant digits, but otherwise drops unnecessary characters?  For
>>> example, if I wanted 5 digits, I'd want the following:
>>> 
>>> Round to 5 digits:
>>> 1.234567  ->  "1.2346"
>>> 
>>> Drop unnecessary zeros:
>>> 1.23      ->  "1.23"
>>> 
>>> Force inclusion of a decimal point:
>>> 1         ->  "1."
>>> 
>> 
>> Duncan,
>> 
>> Maybe sprintf() will work for you.  As it's a wrapper for C sprintf,
>> it should have its functionality.
> 
> Maybe, but with which format string?
> 
> Duncan Murdoch


I don't believe (though could be wrong), that you can do it all with one format string, but can do it conditionally based upon the input. According to the C printf documentation, the use of "#" forces a decimal point to be present, even if there are no trailing digits. Thus:

> sprintf("%#.f", 1)
[1] "1."

The other two values seem to be handled by signif() when applied to each value individually:

> signif(1.234567, 5)
[1] 1.2346

> signif(1.23, 5)
[1] 1.23

But, not when a vector:

> signif(c(1.234567, 1.23), 5)
[1] 1.2346 1.2300


So, wrapping that inside a function, using ifelse() to test for an integer value:

signif.d <- function(x, digits)
{
  ifelse(x == round(x), 
         sprintf("%.#f", x), 
         signif(x, digits))
}


x <- c(1.234567, 1.23, 1)

> signif.d(x, 5)
[1] "1.2346" "1.23"   "1."  

> signif.d(x, 6)
[1] "1.23457" "1.23"    "1."     

> signif.d(x, 7)
[1] "1.234567" "1.23"     "1."      


Not extensively tested of course, but hopefully that might work for your needs Duncan.

Regards,

Marc Schwartz



More information about the R-help mailing list