Форматирование больших валютных или долларовых значений в миллионы / миллиарды
Мне нужна простая функция или пакет, который будет форматировать:
1 6,000,000 2 75,000,400 3 743,450,000 4 340,000 5 4,300,000
Для того, чтобы:
1 6.0 M 2 75.0 M 3 743.5 M 4 0.3 M 5 4.3 M
Или иначе сделать большие значения (миллионы, миллиарды) более parsingчивыми для распечатки в таблице.
- Градиент из n цветов, начиная от цвета 1 и цвета 2
- Как мне назвать столбец имен строк в r
- Lapply для добавления столбцов в каждый Dataframe в списке
- Подавить вывод одной команды в R
- Как назначить значения динамическим именам переменных
- Как вы конвертируете даты / время из одного часового пояса в другой в R?
- Измените class с коэффициента на числовое число столбцов в кадре данных
- Не удалось установить пакеты в последней версии RStudio и R версии.3.1.1
- R Ошибка в операторе x $ ed: $ недействительна для атомных векторов
- Формат чисел до значительных цифр в R
- Выбор только числовых столбцов из кадра данных
- Отбор проб в R из вектора различной длины
- Извлечение строк для первого вхождения переменной в фрейм данных
Если вы начнете с этого числового вектора x
,
x <- c(6e+06, 75000400, 743450000, 340000, 4300000)
вы можете сделать следующее.
paste(format(round(x / 1e6, 1), trim = TRUE), "M") # [1] "6.0 M" "75.0 M" "743.5 M" "0.3 M" "4.3 M"
И если вас не интересуют конечные нули, просто удалите вызов format()
.
paste(round(x / 1e6, 1), "M") # [1] "6 M" "75 M" "743.5 M" "0.3 M" "4.3 M"
Кроме того, вы можете назначить class S3 методом печати и сохранить y
как числовое под ним. Здесь я использую paste0()
чтобы сделать результат более понятным.
print.million <- function(x, quote = FALSE, ...) { x <- paste0(round(x / 1e6, 1), "M") NextMethod(x, quote = quote, ...) } ## assign the 'million' class to 'x' class(x) <- "million" x # [1] 6M 75M 743.5M 0.3M 4.3M x[] # [1] 6000000 75000400 743450000 340000 4300000
Вы могли бы сделать то же самое и для миллиардов и триллионов. Для получения информации о том, как поместить это в кадр данных, см. Этот ответ , поскольку вам понадобятся как метод format()
и метод as.data.frame()
.
Это использует findInterval
для определения суффикса и определения знаменателя. Может быть легко продлен в любом направлении, если нужно идти ниже 1.0 или выше 1 трлн:
comprss <- function(tx) { div <- findInterval(as.numeric(gsub("\\,", "", tx)), c(1, 1e3, 1e6, 1e9, 1e12) ) paste(round( as.numeric(gsub("\\,","",tx))/10^(3*(div-1)), 2), c("","K","M","B","T")[div] )}
Вам не нужно удалять as.numeric или gsub, если ввод является числовым. Это, по общему признанию, лишнее, но будет успешным. Это результат с примером Григора:
> comprss (big_x) [1] "123 " "500 " "999 " "1.05 K" "9 K" [6] "49 K" "105.4 K" "998 K" "1.5 M" "20 M" [11] "313.4 M" "453.12 B"
И с исходным вводом (который на самом деле является переменной фактора).
comprss (dat$V2) [1] "6 M" "75 M" "743.45 M" "340 K" "4.3 M"
И, конечно, их можно распечатать без кавычек, используя либо явную команду print
либо quotes = FALSE или используя cat
.
Другой вариант, начиная с числовых (а не символьных) номеров и работает как для миллионов, так и для миллиардов (и ниже). Вы можете передать больше аргументов в formatC
для настройки вывода и в случае необходимости перейти к Trillions.
m_b_format = function(x) { b.index = x >= 1e9 m.index = x >= 1e5 & x < 1e9 output = formatC(x, format = "d", big.mark = ",") output[b.index] = paste(formatC(x[b.index] / 1e9, digits = 1, format = "f"), "B") output[m.index] = paste(formatC(x[m.index] / 1e6, digits = 1, format = "f"), "M") return(output) } your_x = c(6e6, 75e6 + 400, 743450000, 340000, 43e6) > m_b_format(your_x) [1] "6.0 M" "75.0 M" "743.5 M" "0.3 M" "43.0 M" big_x = c(123, 500, 999, 1050, 9000, 49000, 105400, 998000, 1.5e6, 2e7, 313402182, 453123634432) > m_b_format(big_x) [1] "123" "500" "999" "1,050" "9,000" "49,000" [7] "0.1 M" "1.0 M" "1.5 M" "20.0 M" "313.4 M" "453.1 B"
Заимствование из других ответов и добавление к ним с основным намерением создания ярких меток для осей ggplot2. И да, только положительные значения (отрицательные будут оставлены как есть), так как обычно я хочу эти суффиксы только для положительных величин. Легко распространяться на отрицательные числа.
# Format numbers with suffixes K, M, B, T and optional rounding. Vectorized # Main purpose: pretty formatting axes for plots produced by ggplot2 # # Usage in ggplot2: scale_x_continuous(labels = suffix_formatter) suffix_formatter <- function(x, digits = NULL) { intl <- c(1e3, 1e6, 1e9, 1e12); suffixes <- c('K', 'M', 'B', 'T'); i <- findInterval(x, intl); result <- character(length(x)); # Note: for ggplot2 the last label element of x is NA, so we need to handle it ind_format <- !is.na(x) & i > 0; # Format only the elements that need to be formatted # with suffixes and possible rounding result[ind_format] <- paste0( formatC(x[ind_format]/intl[i[ind_format]], format = "f", digits = digits) ,suffixes[i[ind_format]] ); # And leave the rest with no changes result[!ind_format] <- as.character(x[!ind_format]); return(invisible(result)); }
И пример использования.
x <- seq(1:10); d <- data.frame(x = x, y = 10^x); ggplot(aes(x=x, y=y), data = d) + geom_line() + scale_y_log10()
без форматирования суффиксов
ggplot(aes(x=x, y=y), data = d) + geom_line() + scale_y_log10(labels = suffix_formatter)
с форматированием суффиксов
Я переписываю функцию @ 42- для размещения% чисел, например
compress <- function(tx) { tx <- as.numeric(gsub("\\,", "", tx)) int <- c(1e-2, 1, 1e3, 1e6, 1e9, 1e12) div <- findInterval(tx, int) paste(round( tx/int[div], 2), c("%","", "K","M","B","T")[div] ) } >tx total_reads total_bases q20_rate q30_rate gc_content 3.504660e+05 1.051398e+08 6.648160e-01 4.810370e-01 5.111660e-01 > compress(tx) [1] "350.47 K" "105.14 M" "66.48 %" "48.1 %" "51.12 %"
Это может быть полезно для аналогичной проблемы