Всегда округляйте до указанного количества значащих цифр в R

#r

Вопрос:

Можно ли изменить signif() , чтобы всегда округлять?

Ниже приведены некоторые примеры ожидаемого вывода с использованием пользовательской функции, которая округляет до указанного числа значащих цифр, а также вывод signif() :

 down_signif(117, digits = 2)
# 110

signif(117, digits = 2)
# 120

down_signif(3599, digits = 2)
# 3500

signif(3599, digits = 2)
# 3600

down_signif(7890349, digits = 2)
# 7800000

signif(7890349, digits = 2)
# 7900000
 

Ответ №1:

Альтернативой signif() является использование DescTools пакета, если вы хотите иметь возможность округлять и выбирать цифру (т. Е. несколько) для округления. Используя ваши примеры выше:

 library(DescTools)

DescTools::RoundTo(117, multiple = 10, FUN = floor)
# 110

DescTools::RoundTo(3599, multiple = 100, FUN = floor)
# 3500

DescTools::RoundTo(7890349, multiple = 100000, FUN = floor)
# 7800000
 

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

1. Это здорово и обеспечивает гораздо большую гибкость, чем простое округление до указанной значащей цифры. Но я искал пользовательскую функцию, использующую базу R. Спасибо!

Ответ №2:

Вот пользовательская функция для этого

 down_signif <- function(x, digits = 0) {
  m <- 10^(ceiling(log(x, 10)) - digits)
  (x %/% m)*m
}
down_signif(3599, digits = 2)
#> [1] 3500
down_signif(7890349, digits = 2)
#> [1] 7800000
 

Ответ №3:

Вот еще один подход.

 down_signif <- function(x, digits = 6) {
  n <- nchar(x)
  as.numeric(substr(x, 1, digits)) * (10^(n - digits))
} 

x <- 67897
down_signif(x, 3)
# [1] 67800
signif(x, 3)
# [1] 67900
 

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

1. Спасибо! Ваше решение отличное, но медленнее, чем подход @pseudospin. Кроме того, этот подход неправильно обрабатывает десятичные дроби. Например, down_signif(1.17, digits = 2) выдает 100, в то время как я ожидал бы, что он выдаст 1,1. Я должен был добавить пример с десятичной дробью к вопросу. Моя вина!