R에서 숫자를 백분율로 포맷하는 방법은 무엇입니까?


135

R을 처음 접했을 때 나를 당황하게 한 것 중 하나는 인쇄를 위해 숫자를 백분율로 포맷하는 방법이었습니다.

예를 들어, 표시 0.1234512.345%. 나는 이것에 대한 많은 해결 방법이 있지만 이것들 중 어느 것도 "친숙한"것처럼 보이지 않습니다. 예를 들면 다음과 같습니다.

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있지만 반올림 정확도를 제어 할 수 없습니다.


5
sprintf메일 링리스트에서 가장 좋아하는 솔루션 인 것 같습니다. 더 나은 솔루션을 보지 못했습니다. 내장 함수가 호출하기가 훨씬 간단하지 않습니까?
michel-slm

1
필자가보기 sprintf에는 프로그래머이기도하다. 나는 COBOL (shudder)과 fortran (나이를 보여줌)을 포함하여 내 인생에서 많은 것을 코딩했습니다. 그러나 나는 sprintf서식 규칙을 명백하게 고려하지 않습니다 (번역 : WTF?). 물론 전용 래퍼는 sprintf보다 호출하기가 더 쉽습니다.format_percent(x=0.12345, digits=2)
Andrie

@hircus 나는 그 자체로 짧은 카레 기능을 가질 가치가 있다고 생각합니다. \ Sexpr {sprintf (% 1.2f %% ,, myvar)}이 \ Sexpr {pct (myvar)}보다 훨씬 못하거나 더 짧은 기능이 무엇이든 Sweave의 경우 특히 문제입니다.
Ari B. Friedman

2
사용자가 원하는 도구를 사용하는 방법을 배우지 않습니까? foosprintf() 패키지에 포함되어 있는지 확인하는 것보다 사용 방법을 배우는 데 시간이 많이 걸리지 않습니다 . 사용자가 백분율로 포맷하지 않고 유사한 다른 것을 포맷하면 어떻게됩니까? 다른 래퍼를 찾아야합니다. 장기 학습에서는 기본 도구가 유용합니다. format_percent()
개빈 심슨

1
%LaTeX의 주석 문자에는 R에 대한 "기본"보고 형식 인 약간의 문제점이 있습니다 . 따라서 그래프를 레이블링하는 데 유용 할 수 있지만 형식화 된 숫자를 스윕 할 때는주의를 기울여야합니다.
제임스

답변:


118

심지어 나중에 :

@DzimitryM이 지적했듯이 이전 함수 와 동의어 인을 위해 percent()"퇴직"되었습니다 .label_percent()percent_format()

label_percent() 함수를 반환하므로이를 사용하려면 추가 괄호 쌍이 필요합니다.

library(scales)
x <- c(-1, 0, 0.1, 0.555555, 1, 100)
label_percent()(x)
## [1] "-100%"   "0%"      "10%"     "56%"     "100%"    "10 000%"

첫 번째 괄호 안에 인수를 추가하여이를 사용자 정의하십시오.

label_percent(big.mark = ",", suffix = " percent")(x)
## [1] "-100 percent"   "0 percent"      "10 percent"    
## [4] "56 percent"     "100 percent"    "10,000 percent"

몇 년 후 업데이트 :

요즘에는 krlmlr의 답변에 설명 된대로 패키지에 percent기능이 scales있습니다. 내 수동 솔루션 대신 사용하십시오.


같은 것을 시도하십시오

percent <- function(x, digits = 2, format = "f", ...) {
  paste0(formatC(100 * x, format = format, digits = digits, ...), "%")
}

예를 들어 사용법

x <- c(-1, 0, 0.1, 0.555555, 1, 100)
percent(x)

원하는 경우 형식을에서 (으) "f"로 변경하십시오 "g".


2
예, 이것은 효과가 있으며 질문에 제공 한 해결 방법의 약간 더 일반적인 버전입니다. 그러나 내 진짜 질문은 이것이 R에 존재하는지 여부입니다.
Andrie

백분율 을 나열하는 데 도움이 되지만 통계 또는 그래프 명령에서 "x"를 "percent (x)"로 바꾸면 오류 메시지가 나타납니다.
rolando2

@ rolando2 내 대답과 krlmlr의 대답은 모두 숫자가 아닌 출력으로 문자 벡터를 반환합니다. 축 레이블 등을 형식화하기위한 것입니다. 아마도 당신은 100을 곱하고 싶습니까?
Richie Cotton

2020로 scales버전. 1.1.0 설명서는 다음과 같이 말합니다 percent(). 숫자 형식에 적합하지 않은label_percent() 대신 사용하십시오 . 수동 롤링 솔루션은 여전히 ​​관련이 있습니다
DzimitryM

74

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%"

2
음수에는 작동하지 않습니다. percent(-0.1)생산NaN%
akhmed

1
@akhmed : 이것은 수정, 이미 사용할 수 있지만, 검토 보류보고되고있다 github.com/hadley/scales/issues/50 . 하나 이상의 음수에서 작동하는 것 같습니다.scales::percent(c(-0.1, -0.2))
krlmlr

링크 주셔서 감사합니다! 그것이 기능인지 버그인지 확실하지 않습니다. 여러 숫자의 경우 때로는 작동하지만 때로는 작동하지 않습니다. 말하지만 , scales::percent(c(-0.1,-0.1,-0.1))생산 "NaN%" "NaN%" "NaN%"하지만 당신의 모범은 효과가 있습니다. 다른 사람들을 참조하기 위해 버그는 아직 수정되지 않았습니다 scales_0.2.4. 또한 오늘 기준으로이를 수정하는 해당 끌어 오기 요청은 아직 기본 분기로 병합되지 않습니다.
akhmed

34

패키지 에서 percent기능을 확인하십시오 formattable.

library(formattable)
x <- c(0.23, 0.95, 0.3)
percent(x)
[1] 23.00% 95.00% 30.00%

4
+1을 사용하면 포함 할 자릿수를 지정할 수 scales::percent있으며 처음 두 답변에는 포함되지 않습니다.
Sam Firke

3
+1, 자신의 함수를 롤링하는 것이 쉽지만 자릿수를 선택하는 것이 실제로 유용합니다.
Gang Su

10

좀이 답변에 속도를 벤치마킹 및보고 놀랐다했다 percent에서 scales의 부진 주어진, 그래서 선전 패키지. 적절한 형식 지정을위한 자동 검출기라는 이점이 있다고 생각하지만 데이터가 어떻게 보이는지 알면 피하는 것이 분명합니다.

다음은 (0,1)의 100,000 백분율 목록을 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()

8

이 작업에 대해서만 스케일 패키지를 사용할 수 있습니다 (요청 또는 라이브러리로로드하지 않고).

scales::percent(m)

1
자릿수에 정확도를 부여하는 방법은 무엇입니까?
Elmex80s

6

다음은 새로운 기능을 정의하는 솔루션입니다 (주로 Curry 및 Compose :-) 사용할 수 있습니다).

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

3

어떻게 보면 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()너무 MichaelChirico의 예에서보다 훨씬 더 수행. 단서가 있습니까?


0
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)
}

0

이 함수는 데이터를 열 단위로 백분율로 변환 할 수 있습니다

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)
}

기본 산술은 벡터화됩니다. 내부 for 루프는 비효율적이고 불필요합니다. 로 교체 할 수 있습니다 base2[, j] = base[ , j] * 100 / suma.c. 또한 이것이 질문에 대한 정답이 아니라는 점에 주목할 가치가 있습니다 ... 질문은 0.5"50.0 %" 와 같은 형식을 지정하는 것이 아니라 계산을하는 것이 아니라 ...
Gregor Thomas

0

tidyverse버전은 이것이다 :

> library(tidyverse)

> set.seed(1)
> m <- runif(5)
> dt <- as.data.frame(m)

> dt %>% mutate(perc=scales::percent(m,accuracy=0.001))
          m    perc
1 0.2655087 26.551%
2 0.3721239 37.212%
3 0.5728534 57.285%
4 0.9082078 90.821%
5 0.2016819 20.168%

평소처럼 깔끔하게 보입니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.