Как бы вы написали функцию или класс-оболочку для форматирования чисел в процентах, валюте и т. Д. В R? - PullRequest
11 голосов
/ 22 августа 2011

В предыдущем вопросе я спросил, существует ли удобная оболочка внутри базы R для форматирования чисел в процентах.

Это вызвало три ответа:

  1. Вероятно, нет.
  2. Такая обертка была бы слишком узкой, чтобы быть полезной. Лучше, чтобы useR научились использовать существующие инструменты, такие как sprintf, которые могут очень гибко форматировать числа.
  3. Такая оболочка, в любом случае, проблематична, поскольку вы теряете возможность выполнять вычисления на объекте.

Тем не менее, на мой взгляд, функция sprintf слишком запутана, чтобы ее мог освоить начинающий R (кроме случаев, когда они написаны на C-фоне). Возможно, лучшим решением будет изменить format или prettyNum, чтобы иметь опции для добавления префиксов и суффиксов, чтобы вы могли легко создавать проценты, валюты, градусы и т. Д.


Вопрос:

Как бы вы разработали функцию, класс или набор функций для элегантного управления форматированием чисел в процентах, валютах, градусах и т. Д.?

Ответы [ 4 ]

10 голосов
/ 22 августа 2011

Я бы, наверное, все упростил.format() обычно используется для большинства основных потребностей форматирования.Я бы расширил это с помощью простой оболочки, которая допускает произвольные строки prefix и suffix.Вот простая версия:

formatVal <- function(x, prefix = "", suffix = "", sep = "", collapse = NULL,
                      ...) {
    x <- format(x, ...)
    x <- paste(prefix, x, suffix, sep = sep, collapse = collapse)
    x
}

Если бы я делал это по-настоящему, я бы, вероятно, не имел аргумента collapse в определении formatVal(), но вместо этого обработал бы его из ..., но для иллюстрации я оставил вышеуказанную функцию простой.

Использование:

set.seed(1)
m <- runif(5)

несколько простых примеров использования

> formatVal(m*100, suffix = "%")
[1] "26.55087%" "37.21239%" "57.28534%" "90.82078%" "20.16819%"
> formatVal(m*100, suffix = "%", digits = 2)
[1] "27%" "37%" "57%" "91%" "20%"
> formatVal(m*100, suffix = "%", digits = 2, nsmall = 2)
[1] "26.55%" "37.21%" "57.29%" "90.82%" "20.17%"
> formatVal(m, prefix = "£")
[1] "£0.2655087" "£0.3721239" "£0.5728534" "£0.9082078" "£0.2016819"
> formatVal(m, prefix = "£", digits = 1)
[1] "£0.3" "£0.4" "£0.6" "£0.9" "£0.2"
> formatVal(m, prefix = "£", digits = 1, nsmall = 2)
[1] "£0.27" "£0.37" "£0.57" "£0.91" "£0.20"
8 голосов
/ 22 августа 2011
print.formatted <- function(x)
{
   print(paste(attr(x,"prefix"), sprintf(x*attr(x,"scaleFactor"),fmt=paste("%.",attr(x,"precision"),"f",sep="")), attr(x,"suffix"), sep=""))
}

as.percent <- function(x,precision=3)
{
  class(x) <- c(class(x),"formatted")
  attr(x,"scaleFactor")<-100
  attr(x,"prefix")<-""
  attr(x,"suffix")<-"%"
  attr(x,"precision")<-precision
  return(x)
}

as.currency <- function(x,prefix="£")
{
  class(x) <- c(class(x),"formatted")
  attr(x,"scaleFactor")<-1
  attr(x,"prefix")<-prefix
  attr(x,"suffix")<-""
  attr(x,"precision")<-2
  return(x)
}

as.percent(runif(3))
[1] "21.585%" "12.396%" "37.744%"

x <- as.currency(rnorm(3,500,100))
x
[1] "£381.93" "£339.49" "£521.74"
2*x
[1] "£763.86"  "£678.98"  "£1043.48"
4 голосов
/ 22 августа 2011

Я думаю, что это можно сделать с помощью атрибутов, например, пусть v <- 3.4.Если это фунты стерлингов, мы могли бы использовать что-то вроде:

attributes(v)<-list(style = "descriptor", type = "currency", category = "pound")

Если это процент:

attributes(v)<-list(style = "descriptor", type = "proportion", category = "percentage")

Тогда,специальный метод печати будет необходимо.Можно также включить метод перевода, например, для перевода из фунтов стерлингов в доллары США (фунты в доллары), сантиметры в дюймы и т. Д.

descriptor - это, по сути, мой взгляд на зарезервированный тип флага для указания специальныхобработка для данного номера.Позже это может распространиться на текстовые строки, такие как адреса и имена.Для других номеров, таких как телефонные номера, могут быть специальные разложения на коды стран, внутригородские / региональные коды, вплоть до добавочных номеров.

Такой пакет может бытьСродни ggplot для типов данных - специальные методы для хранения, преобразования и печати вещей внутри типов?

Такая система может обеспечить правильность размеров при умножении значений.Это имеет реальную полезность во многих приложениях.

Насколько мне известно, единственная распространенная обработка единиц в R - это байты (байты, КБ, МБ и т. Д.) И время (часы, секунды и т. Д.).).Несмотря на это, обработка, хотя и проста, не очевидна - я все еще должен указать print единиц, которые будут использоваться.Например, если я хочу напечатать размер объекта в килобайтах, я не могу просто вычислить object.size(v)/1024 - результат выводится в долях байта, а не в килобайтах;Я должен использовать print(object.size(v), units = "K").

2 голосов
/ 22 августа 2011

ggplot2 имеет набор функций для форматирования общих конкретных случаев.Это было бы идеально, но для двух вещей: они не являются достаточно общими, и вам не нужно загружать ggplot2 (со всеми его зависимостями), чтобы получить такие функции.Вы можете попробовать связаться с Хэдли, чтобы изменить подписи, чтобы передать больше вещей для форматирования, и переместить их в пакет более низкого уровня (возможно, plyr, или их собственный пакет, ggtools?).

...