I came here with the same question. Thanks to Roland for his reply; I built his code with a few changes:
- Allows you to specify significant digits when rounding = FALSE (the default value is 6, just like the built-in signif function)
- Does not cause an error with values ββbelow 1e-24
- Displays scientific notation (without units) for values ββabove 1e27
Hope this will be helpful.
f2si<-function (number, rounding=F, digits=ifelse(rounding, NA, 6)) { lut <- c(1e-24, 1e-21, 1e-18, 1e-15, 1e-12, 1e-09, 1e-06, 0.001, 1, 1000, 1e+06, 1e+09, 1e+12, 1e+15, 1e+18, 1e+21, 1e+24, 1e+27) pre <- c("y", "z", "a", "f", "p", "n", "u", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y", NA) ix <- findInterval(number, lut) if (ix>0 && ix<length(lut) && lut[ix]!=1) { if (rounding==T && !is.numeric(digits)) { sistring <- paste(round(number/lut[ix]), pre[ix]) } else if (rounding == T || is.numeric(digits)) { sistring <- paste(signif(number/lut[ix], digits), pre[ix]) } else { sistring <- paste(number/lut[ix], pre[ix]) } } else { sistring <- as.character(number) } return(sistring) } f2si(12345) [1] "12.345 k" f2si(12345, T) [1] "12 k" f2si(10^31) [1] "1e+31" # (previous version would output "1e+07 Y" f2si(10^-25) [1] "1e-25" # (previous version would throw error) f2si(123456789) [1] "123.457 M" # (previous version would output ""123.456789 M" f2si(123456789, digits=4) [1] "123.5 M" # (note .456 is rounded up to .5)
From this code, it is quite easy to write a similar function for commonly used financial units (K, MM, Bn, Tr).