2

Background

Due to a bug in Renjin, the format family of functions are unavailable, but sprintf works.

Code

Here is a replacement function that converts a number to a comma-delimited string:

commas <- function( n ) {
  s <- sprintf( "%03.0f", n %% 1000 )
  n <- n %/% 1000

  while( n > 0 ) {
    s <- concat( sprintf( "%03.0f", n %% 1000 ), ',', s )
    n <- n %/% 1000
  }

  gsub( '^0*', '', s )
}

Question

While the code does the job, how can the implementation be sped up? That is, how can the code be written so as to make use of R vernacular (without using format, formatC, prettyNum, and the like) and without broken Renjin packages (i.e., no dependencies)?

bad_coder
  • 11,289
  • 20
  • 44
  • 72
Dave Jarvis
  • 30,436
  • 41
  • 178
  • 315

2 Answers2

2

There is a slick one-liner you can use to add thousands comma separators to the whole number digits of a number, without adding them to the decimal portion. Using str_replace_all from the stringr package, we can use this:

num <- "1234567890.12345"
str_replace_all(num, "[0-9](?=(?:[0-9]{3})+(?![0-9])(?=\\.))", "\\0,")
[1] "1,234,567,890.12345"

Demo

Tim Biegeleisen
  • 502,043
  • 27
  • 286
  • 360
  • `str_replace_all` is also broken in Renjin. See: http://packages.renjin.org/package/org.renjin.cran/stringr/1.2.0/build/18#test-str_replace-examples – Dave Jarvis Oct 13 '17 at 16:55
  • @DaveJarvis I'm not familiar with `stringr` being broken. My basic answer is to use a regex. If that doesn't meet your expectations you can try something else. – Tim Biegeleisen Oct 14 '17 at 01:10
0

Unfortunately, a number of Renjin packages are not fully implemented, so until a fix is in place, the code in the question is a decent work around:

commas <- function( n ) {
  s <- sprintf( "%03.0f", n %% 1000 )
  n <- n %/% 1000

  while( n > 0 ) {
    s <- concat( sprintf( "%03.0f", n %% 1000 ), ',', s )
    n <- n %/% 1000
  }

  gsub( '^0*', '', s )
}
Dave Jarvis
  • 30,436
  • 41
  • 178
  • 315