Как отформатировать от 7 до 2 знаков после запятой

#r

#r

Вопрос:

Я изучаю пакет tidyverse.

Меня устраивает приведенный ниже код:

 library(dslabs)
data("murders")

murders <- mutate(murders, rate = total / population * 100000)
murders

filter(murders, rate <= 0.71)
 

The pipe — Используя канал, код выглядит следующим образом:

 murders %>% select(state, region, rate) %>% filter(rate <= 0.71)
 

Как я могу отформатировать скорость с текущих 7 знаков после запятой до 2?

Комментарии:

1. Вы хотите, чтобы в напечатанном результате было 2 знака после запятой, но данные сохраняли свою точность, или вы хотите округлить данные до 2 знаков после запятой?

2. Вопрос был с отступом в напечатанном результате, чтобы иметь 2 знака после запятой, но данные сохраняют свою точность, однако вы также можете обратиться к адресу округления данных до 2 знаков после запятой.

Ответ №1:

Я полагаю, что вы хотите просто распечатать эти данные с двумя десятичными знаками, а не округлять их? Если вы хотите округлить данные, это просто:

Округление

 library(dplyr)
library(dslabs)
data("murders")

murders %>% 
  select(state, region, rate) %>% 
  filter(rate <= 0.71) %>% 
  mutate(rate = round(rate, 2))

          state        region rate
1        Hawaii          West 0.51
2          Iowa North Central 0.69
3 New Hampshire     Northeast 0.38
4  North Dakota North Central 0.59
5       Vermont     Northeast 0.32
 

обходной путь tibble

Если вы не хотите округлять данные, но хотите напечатать только две цифры, вы можете сделать это, преобразовав свои данные в a tibble и установив этот pillar.sigfig параметр. Обратите внимание, что options(pillar.sigfig = 2) явно выводятся две значащие цифры, а не десятичные разряды. Так что, если бы ваши данные имели значение 1.23345 , они бы печатались 1.2 . Однако все ваши ставки меньше единицы, поэтому это должно действовать как обходной путь. Вы можете точно управлять десятичными знаками, используя vctrs пакет, и этот подход приведен ниже.

 library(dplyr)
library(tibble)
library(dslabs)
data("murders")
options(pillar.sigfig = 2)

murders2 <- murders %>% 
  select(state, region, rate) %>% 
  filter(rate <= 0.71) %>% 
  tibble()
murders2

# A tibble: 5 x 3
  state         region         rate
  <chr>         <fct>         <dbl>
1 Hawaii        West           0.51
2 Iowa          North Central  0.69
3 New Hampshire Northeast      0.38
4 North Dakota  North Central  0.59
5 Vermont       Northeast      0.32
 

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

 murders2$rate[3]
[1] 0.3798036
 

Настройка options(pillar.sigfig = ) изменяет глобальную опцию для печати всех tibbles . Чтобы возобновить нормальное поведение, установите options(pillar.sigfig = NULL) .

Обратите внимание, что установка аналогичной опции для десятичных знаков и несущественных цифр была запросом функции для tibble пакета (https://github.com/tidyverse/tibble/issues/772 ), но представляется маловероятным, что он будет реализован в настоящее время.

Лучшее решение с использованием vctrs

Есть надежда, если ваши данные более сложные! vctrs Пакет позволяет вам определять новые векторные классы с различным поведением (включая печать определенного количества знаков после запятой). Фактически, установка десятичных разрядов является одним из двух примеров использования в vignette("s3-vector") . Запустите код из виньетки (воспроизведенный ниже), чтобы создать новый класс, а затем mutate ваш столбец.

 library(vctrs)
new_decimal <- function(x = double(), digits = 2L) {
  vec_assert(x, ptype = double())
  vec_assert(digits, ptype = integer(), size = 1)

  new_vctr(x, digits = digits, class = "vctrs_decimal")
}

decimal <- function(x = double(), digits = 2L) {
  x <- vec_cast(x, double())
  digits <- vec_recycle(vec_cast(digits, integer()), 1L)

  new_decimal(x, digits = digits)
}

digits <- function(x) attr(x, "digits")

format.vctrs_decimal <- function(x, ...) {
  sprintf(paste0("%-0.", digits(x), "f"), x)
}

vec_ptype_abbr.vctrs_decimal <- function(x, ...) {
  "dec"
}

murders3 <- murders %>% 
  select(state, region, rate) %>% 
  filter(rate <= 0.71) %>% 
  mutate(rate = decimal(rate, 2))
murders3

          state        region rate
1        Hawaii          West 0.51
2          Iowa North Central 0.69
3 New Hampshire     Northeast 0.38
4  North Dakota North Central 0.59
5       Vermont     Northeast 0.32
 

Преимущество этого vctrs подхода заключается в том, что он обрабатывает любое значение и может быть выполнен без преобразования в a tibble , если вы этого не хотите.

 decimal(1.2345, 2)

<vctrs_decimal[1]>
[1] 1.23
 

Опять же, полное значение сохраняется, хотя вам нужно удалить класс или изменить digits атрибут, чтобы увидеть больше знаков после запятой:

 unclass(num) 
  
[1] 1.2345
attr(,"digits")
[1] 2

attributes(num)$digits <- 4
num

<vctrs_decimal[1]>
[1] 1.2345