числовой формат печати тиблей - PullRequest
0 голосов
/ 25 февраля 2020

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

Оптимально я ищу что-то в строке масштабирует пакет для ggplot2 так, чтобы было возможно следующее:

t <- tibble(
    surface = c(98000, 178000000000, 254000000), 
    price = c(517244, 939484, 1340612), 
    rate = c(0.12, 0.07, 0.045)
)
print(t,
    label = c(
        surface = label_number_si(),
        price = label_dollar(),
        rate = label_percent()
    )
)
# A tibble: 3 x 3
    surface   price    rate
     <dbl>    <dbl>    <dbl>
1      98k $  517 244  12.0% 
2     178B $  939 484   7.0% 
3     254M $1 340 612   4.5%

в настоящее время при печати тиббла я получаю следующий вывод, который довольно сложно прочитать, особенно для столбца цены :

print(t)
# A tibble: 3 x 3
       surface   price  rate
         <dbl>   <dbl> <dbl>
1        98000  517244 0.12 
2 178000000000  939484 0.07 
3    254000000 1340612 0.045

все найденные похожие вопросы, такие как здесь или там , похоже, вращаются вокруг научной нотации c с использованием options(scipen = xxx), который не действительно позволяет определять выходные данные по желанию.

Я также пытался искать другие пакеты, такие как единиц , но они также не обеспечивают заданное c форматирование чисел, только прикрепление единица к типу столбца.

Ответы [ 3 ]

1 голос
/ 25 февраля 2020

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

Вы можете использовать небольшую нестандартную оценку, чтобы передать любые функции, которые вы хотите применить к каждому столбцу. Это очень близко к тому, что вы хотели, я думаю:

library(tidyverse)
library(scales)

format_tibble <- function(tbl, ...)
{
  functions <- rlang::dots_list(...)
  if(length(functions) > 0)
  {
    if(length(tbl) < length(functions)) functions <- functions[seq_along(tbl)]
    columns <- names(functions)
    for(i in seq_along(columns))
    {
      fun <- functions[[i]]
      col <- as.name(columns[i])
      tbl <- mutate(tbl, !!quo_name(col) := fun(!!enquo(col)))
    }
  }
  print(tbl)
}

Итак, теперь, принимая ваш кусок:

t <- tibble( surface = c(98000, 178000000000, 254000000), 
             price   = c(517244, 939484, 1340612), 
             rate    = c(0.12, 0.07, 0.045))

Нам нужно только сделать это:

t %>%
format_tibble(surface = label_number_si(),
              price   = label_dollar(),
              rate    = label_percent())
#> # A tibble: 3 x 3
#>   surface price      rate 
#>   <chr>   <chr>      <chr>
#> 1 98K     $517,244   12.0%
#> 2 178B    $939,484   7.0% 
#> 3 254M    $1,340,612 4.5%

Создано в 2020-02-25 пакетом представ (v0.3.0)

1 голос
/ 25 февраля 2020

Обходной путь путем массирования данных в виде символьных векторов:

library(tibble)

options(scipen = 12)

t <- tibble(
  surface = c(98000, 178000000000, 254000000), 
  price = c(517244, 939484, 1340612), 
  rate = c(0.12, 0.07, 0.045)
)
# temp vars
t$KMB <- ifelse(t$surface >= 10^3 & t$surface < 10^6, "K",
  ifelse(t$surface >= 10^6 & t$surface < 10^9, "M", "B"))
t$surface_char <- gsub("0", "", as.character(t$surface))

# paste elements together
t$surface <- paste0(t$surface_char, t$KMB)        
t$price <- paste0("$ ", t$price)
t$rate <- paste0(as.character(format(t$rate *100, nsmall = 1)), "%")

# remove temp vars
t$KMB <- NULL
t$surface_char <- NULL

print(t)
1 голос
/ 25 февраля 2020

Вы можете использовать scales::dollar() для форматирования цены, sprintf() для курса и вспомогательную функцию для форматирования surface (я позаимствовал одну из здесь ).

library(dplyr)

t <- tibble(
  surface = c(98000, 178000000000, 254000000), 
  price = c(517244, 939484, 1340612), 
  rate = c(0.12, 0.07, 0.045)
)

si_number = function(x, digits) {

  compress = function(x, n) {
    signif(x * 10^(-n), digits)
  }

  case_when(
    x >= 1e9   ~ paste0(compress(x, 9), "B"),
    x >= 1e6   ~ paste0(compress(x, 6), "M"),
    x >= 1000  ~ paste0(compress(x, 3), "k"),
    x >= 1     ~ as.character(compress(x, 0))
  )
}

t2 <- t %>%
  mutate(
    surface = si_number(surface, 3),
    price   = scales::dollar(price),
    rate    = sprintf("%.1f%%", rate * 100)
  )

t2
#> # A tibble: 3 x 3
#>   surface price      rate 
#>   <chr>   <chr>      <chr>
#> 1 98k     $517,244   12.0%
#> 2 178B    $939,484   7.0% 
#> 3 254M    $1,340,612 4.5%

Создано в 2020-02-24 пакетом представ. (v0.3.0)

...