高性能数字格式

时间:2013-12-09 17:51:28

标签: r

对于我的json编码器,我想打印一组带有n小数的数字。有两种方式:

x <- c(1,2,pi)
n <- 2
format(x, digits = n, nsmall = n, trim = TRUE, drop0trailing = TRUE)
formatC(x, digits = n, format = "f", drop0trailing = TRUE)

然而,drop0trailing参数似乎引入了一个大的(~10x)性能回归:

x <- rnorm(1e6)
system.time(format(x, digits = n, nsmall = n, trim = TRUE))
   user  system elapsed 
  0.584   0.000   0.584
system.time(format(x, digits = n, nsmall = n, trim = TRUE, drop0trailing = TRUE))
   user  system elapsed 
  5.763   0.040   5.799 

是否有另一种方法可以打印n小数更快的数字?

2 个答案:

答案 0 :(得分:5)

命令

as.character(round(x, n))
# [1] "1"    "2"    "3.14"

应该快得多。 options(scipen = k)控制是否以及何时跳转到科学记数法。

另一种选择是

sub("\\.0+$", "", sprintf(paste0("%.", n, "f"), x))
# [1] "1"    "2"    "3.14"

此命令的优点是结果不是科学记数法。

绩效考核:

f1 <- function() format(x, digits = n, nsmall = n, trim = TRUE, drop0trailing = TRUE)
f2 <- function() formatC(x, digits = n, format = "f", drop0trailing = TRUE)
f3 <- function() as.character(round(x, n))
f4 <- function() sub("\\.0+$", "", sprintf(paste0("%.", n, "f"), x))

library(microbenchmark)
microbenchmark(f1(), f2(), f3(), f4())
# Unit: microseconds
#  expr     min       lq   median      uq      max neval
# f1() 288.594 294.6525 298.5165 302.5325 544.610   100
# f2() 319.022 324.4970 327.0815 331.4695 600.179   100
# f3()   9.799  12.4140  13.6315  13.9910 142.313   100
# f4()  40.198  42.6590  45.9945  46.6180 342.098   100

答案 1 :(得分:0)

我不确定这是否有效(如果您想要三位数整体):

as.numeric(formatC(x, flag="#", digits=3))

如果您的数字都在0到1之间,那么指定as.numeric(formatC(x, flag="#", digits=(n+1)))会给您答案。