Как отформатировать число в процентах в R?



одна из вещей, которые раньше озадачивали меня как новичка в R, заключалась в том, как форматировать число в процентах для печати.



например, display 0.12345 как 12.345%. У меня есть несколько обходных путей для этого, но ни один из них не кажется "Newby friendly". Например:



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

paste(round(100*m, 2), "%", sep="")
[1] "26.55%" "37.21%" "57.29%" "90.82%" "20.17%"

sprintf("%1.2f%%", 100*m)
[1] "26.55%" "37.21%" "57.29%" "90.82%" "20.17%"


вопрос: есть ли базовая функция R для этого? Кроме того, есть широко используемый пакет, который обеспечивает удобный обертка?





несмотря на поиск чего-то подобного в ?format,?formatC и ?prettyNum, мне еще предстоит найти подходящую удобную обертку в базе R. ??"percent" не дали ничего полезного. library(sos); findFn("format percent") возвращает 1250 хитов-так что опять не полезно. ggplot2 оснащен функцией percent но это не дает никакого контроля над точностью округления.

995   9  

9 ответов:

обновление, несколько лет спустя:

в эти дни есть percent

Проверьте scales пакета. Раньше он был частью ggplot2, Я думаю.

library('scales')
percent((1:10) / 100)
#  [1] "1%"  "2%"  "3%"  "4%"  "5%"  "6%"  "7%"  "8%"  "9%"  "10%"

встроенная логика для обнаружения точности должна работать достаточно хорошо для большинства случаев.

percent((1:10) / 1000)
#  [1] "0.1%" "0.2%" "0.3%" "0.4%" "0.5%" "0.6%" "0.7%" "0.8%" "0.9%" "1.0%"
percent((1:10) / 100000)
#  [1] "0.001%" "0.002%" "0.003%" "0.004%" "0.005%" "0.006%" "0.007%" "0.008%"
#  [9] "0.009%" "0.010%"
percent(sqrt(seq(0, 1, by=0.1)))
#  [1] "0%"   "32%"  "45%"  "55%"  "63%"  "71%"  "77%"  "84%"  "89%"  "95%" 
# [11] "100%"
percent(seq(0, 0.1, by=0.01) ** 2)
#  [1] "0.00%" "0.01%" "0.04%" "0.09%" "0.16%" "0.25%" "0.36%" "0.49%" "0.64%"
# [10] "0.81%" "1.00%"

Проверьте

Я сделал некоторые бенчмаркинг для скорости на эти ответы и был удивлен, увидев percent на scales пакет так рекламируется, учитывая его вялость. Я предполагаю, что преимуществом является его автоматический детектор для правильного форматирования, но если вы знаете, как выглядят ваши данные, кажется, что этого следует избегать.

вот результаты от попытки форматировать список из 100 000 процентов в (0,1) до процента в 2 цифры:

library(microbenchmark)
x = runif(1e5)
microbenchmark(times = 100L, andrie1(), andrie2(), richie(), krlmlr())
# Unit: milliseconds
#   expr       min        lq      mean    median        uq       max
# 1 andrie1()  91.08811  95.51952  99.54368  97.39548 102.75665 126.54918 #paste(round())
# 2 andrie2()  43.75678  45.56284  49.20919  47.42042  51.23483  69.10444 #sprintf()
# 3  richie()  79.35606  82.30379  87.29905  84.47743  90.38425 112.22889 #paste(formatC())
# 4  krlmlr() 243.19699 267.74435 304.16202 280.28878 311.41978 534.55904 #scales::percent()

так sprintf выступает как явный победитель когда мы хотим добавить знак процента. С другой стороны, если мы хотим только умножить число и округлить (перейти от пропорции к проценту без"%", ТО round() быстрый:

# Unit: milliseconds
#        expr      min        lq      mean    median        uq       max
# 1 andrie1()  4.43576  4.514349  4.583014  4.547911  4.640199  4.939159 # round()
# 2 andrie2() 42.26545 42.462963 43.229595 42.960719 43.642912 47.344517 # sprintf()
# 3  richie() 64.99420 65.872592 67.480730 66.731730 67.950658 96.722691 # formatC()

вот мое решение для определения новой функции (в основном, чтобы я мог играть с Карри и сочинять: -)):

library(roxygen)
printpct <- Compose(function(x) x*100, Curry(sprintf,fmt="%1.2f%%"))

видя, как scalable::percent уже было показано, что он самый медленный, и Лилиана Пачеко предложила другое решение, я пошел вперед и попытался сравнить его с некоторыми другими вариантами, основанными на примере Майкла:

library(microbenchmark)
library(scales)
library(formattable)

x<-runif(1e5)

lilip <- function() formattable::percent(x,2)
krlmlr <- function() scales::percent(x)
andrie1 <- function() paste0(round(x,4) * 100, '%')

microbenchmark(times=100L,lilip(), krlmlr(), andrie1())

вот результаты, которые я получил:

Unit: microseconds
      expr        min          lq        mean      median          uq        max neval
   lilip()    194.562    373.7335    772.5663    889.7045    950.4035   1611.537   100
  krlmlr() 226270.845 237985.6560 260194.9269 251581.0235 280704.2320 373022.180   100
 andrie1()  87916.021  90437.4820  92791.8923  92636.8420  94448.7040 102543.252   100

Я понятия не имею, хотя, почему мой krlmlr() и andrie1() выступал намного хуже, чем в Примере Михаэльчирико. Какие-нибудь улики?

вы можете использовать пакет scales только для этой операции (без загрузки его с require или библиотекой)

scales::percent(m)
try this~

data_format <- function(data,digit=2,type='%'){
if(type=='d') {
    type = 'f';
    digit = 0;
}
switch(type,
    '%' = {format <- paste("%.", digit, "f%", type, sep='');num <- 100},
    'f' = {format <- paste("%.", digit, type, sep='');num <- 1},
    cat(type, "is not a recognized type\n")
)
sprintf(format, num * data)
}

эта функция может преобразовывать данные в проценты по столбцам

percent.colmns = function(base, columnas = 1:ncol(base), filas = 1:nrow(base)){
    base2 = base
    for(j in columnas){
        suma.c = sum(base[,j])
        for(i in filas){
            base2[i,j] = base[i,j]*100/suma.c
        }
    }
    return(base2)
}

Comments

    Ничего не найдено.