2015-01-26 82 views
10

我需要一個簡單的函數或包,將格式化:格式化大貨幣或美元價值上百萬/十億

1 6,000,000 
2 75,000,400 
3 743,450,000 
4 340,000 
5 4,300,000 

要:

1 6.0 M 
2 75.0 M 
3 743.5 M 
4 0.3 M 
5 4.3 M 

或以其他方式大值(千萬,上億)在桌面上打印更清晰。

+1

我想你可以做這樣的事情'膏(as.numeric(GSUB( 「」, 「」,X))/ 1E6,「M 「),但我不確定這有多漂亮...... – 2015-01-26 22:36:56

+0

工程符號是科學記數法的一個子集,它試圖讓10的指數爲3的倍數。而且,有人爲此寫了一些R代碼: http://r.789695.n4.nabble.com/engineering-notation-format-td803373.html - 建議從那裏開始並改變打印報表。 – Paul 2015-01-26 22:37:41

+0

@Paul在我問這個問題之前,我真的看到了這個帖子......但是不知道發生了什麼...... – emehex 2015-01-26 22:39:41

回答

20

如果你開始這個數字矢量x

x <- c(6e+06, 75000400, 743450000, 340000, 4300000) 

你可以做到以下幾點。

paste(format(round(x/1e6, 1), trim = TRUE), "M") 
# [1] "6.0 M" "75.0 M" "743.5 M" "0.3 M" "4.3 M" 

如果你不關心尾隨零,只是刪除format()電話。

paste(round(x/1e6, 1), "M") 
# [1] "6 M"  "75 M" "743.5 M" "0.3 M" "4.3 M" 

另外,你可以指定與打印方法的S3級,並保持y作爲數字下方。這裏我使用paste0()來使結果更清晰。

print.million <- function(x, quote = FALSE, ...) { 
    x <- paste0(round(x/1e6, 1), "M") 
    NextMethod(x, quote = quote, ...) 
} 
## assign the 'million' class to 'x' 
class(x) <- "million" 
x 
# [1] 6M  75M 743.5M 0.3M 4.3M 
x[] 
# [1] 6000000 75000400 743450000 340000 4300000 

您也可以爲億萬和萬億做同樣的事情。有關如何將其放入數據框的信息,請參閱this answer,因爲您需要使用format()as.data.frame()方法。

+0

這正是我需要的。所以如果我的數字已經是數字,我會拿出gsub位並保持:round(x/1e6,1)? – emehex 2015-01-26 22:46:56

+0

沒問題!我明白我將有字符值作爲輸出。但是,我有數字輸入。 – emehex 2015-01-26 22:50:48

7

另一種選擇,從數字(而不是字符)開始,並且適用於數百萬和數十億(及以下)。您可以將更多參數傳遞給formatC以自定義輸出,並在需要時擴展到萬億。

m_b_format = function(x) { 
    b.index = x >= 1e9 
    m.index = x >= 1e5 & x < 1e9 

    output = formatC(x, format = "d", big.mark = ",") 
    output[b.index] = paste(formatC(x[b.index]/1e9, digits = 1, format = "f"), "B") 
    output[m.index] = paste(formatC(x[m.index]/1e6, digits = 1, format = "f"), "M") 
    return(output) 
} 

your_x = c(6e6, 75e6 + 400, 743450000, 340000, 43e6) 
> m_b_format(your_x) 
[1] "6.0 M" "75.0 M" "743.5 M" "0.3 M" "43.0 M" 

big_x = c(123, 500, 999, 1050, 9000, 49000, 105400, 998000, 
      1.5e6, 2e7, 313402182, 453123634432) 
> m_b_format(big_x) 
[1] "123"  "500"  "999" "1,050" "9,000" "49,000" 
[7] "0.1 M" "1.0 M" "1.5 M" "20.0 M" "313.4 M" "453.1 B" 
17

這使用findInterval來定義後綴並確定分母。可在任一方向很容易地擴展,如果一個想去低於1.0或高於1萬億:

comprss <- function(tx) { 
     div <- findInterval(as.numeric(gsub("\\,", "", tx)), 
          c(1, 1e3, 1e6, 1e9, 1e12)) 
     paste(round(as.numeric(gsub("\\,","",tx))/10^(3*(div-1)), 2), 
      c("","K","M","B","T")[div])} 

您不必刪除as.numeric或GSUB如果輸入的是數字。毫無疑問,這是多餘的,但會成功。這與Grgor的示例的結果:(這實際上是一個因子可變)

> comprss (big_x) 
[1] "123 "  "500 "  "999 "  "1.05 K" "9 K"  
[6] "49 K"  "105.4 K" "998 K" "1.5 M" "20 M"  
[11] "313.4 M" "453.12 B" 

並與原來的輸入

comprss (dat$V2) 
[1] "6 M"  "75 M"  "743.45 M" "340 K" "4.3 M" 

當然,這些的並且可以在不使用一個顯式的報價被打印print命令和引號= FALSE或使用cat

+0

好的解決方案,但你需要添加「T」到兆的後綴數組。此外,爲了保持完整性,您應該在絕對值上找到間隔來處理負值(但請注意,它與圓整底片的ISO行爲不一致)。 – C8H10N4O2 2015-05-05 19:15:04

+0

感謝您的洞察力評論。我猜測國際標準組織在各個英語國家對「十億」的定義差異沒有什麼可說的。 (我確實看到維基百科的這篇文章截至這個日期宣稱英文版已經放棄了他們以前的位置,但我從來沒有收到過這樣的備忘錄。) – 2015-05-05 19:25:37

+0

啊對不起,我只是在談論處理負數和從零變圓(會發生什麼如果您對tx的絕對值使用了findInterval),而不是向正無窮大舍入。 – C8H10N4O2 2015-05-05 19:32:13

0

借用其他答案並添加它們的主要目的是爲ggplot2軸生成漂亮的標籤。是的,只有正值(負值將保持不變),因爲通常我只希望這些後綴用於正數量。易於擴展到負數。

# Format numbers with suffixes K, M, B, T and optional rounding. Vectorized 
# Main purpose: pretty formatting axes for plots produced by ggplot2 
# 
# Usage in ggplot2: scale_x_continuous(labels = suffix_formatter) 

suffix_formatter <- function(x, digits = NULL) 
{ 
    intl <- c(1e3, 1e6, 1e9, 1e12); 
    suffixes <- c('K', 'M', 'B', 'T'); 

    i <- findInterval(x, intl); 

    result <- character(length(x)); 

    # Note: for ggplot2 the last label element of x is NA, so we need to handle it 
    ind_format <- !is.na(x) & i > 0; 

    # Format only the elements that need to be formatted 
    # with suffixes and possible rounding 
    result[ind_format] <- paste0(
     formatC(x[ind_format]/intl[i[ind_format]], format = "f", digits = digits) 
     ,suffixes[i[ind_format]] 
    ); 
    # And leave the rest with no changes 
    result[!ind_format] <- as.character(x[!ind_format]); 

    return(invisible(result)); 
} 

使用示例。

x <- seq(1:10); 
d <- data.frame(x = x, y = 10^x); 
ggplot(aes(x=x, y=y), data = d) + geom_line() + scale_y_log10() 

without suffix formatter

ggplot(aes(x=x, y=y), data = d) + geom_line() + scale_y_log10(labels = suffix_formatter) 

with suffix formatter