2013-12-09 5 views
1

Для моего кодера 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 знаков после запятой, что быстрее?

ответ

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 
+0

Могу ли я предотвратить его формы поспешных научной нотации? 'as.character (round (0.0001, 4))' – Jeroen

+0

@Jeroen См. обновление моего ответа. –

+0

@Jeroen Я объединил 'sprintf' с' sub'. См. Обновление. –

0

Я не уверен, если это работает (если вы хотите иметь три цифры общая):

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

Если ваши номера все в диапазоне от 0 до 1, то с указанием as.numeric(formatC(x, flag="#", digits=(n+1))) дает ответ.

Смежные вопросы