2012-07-05 2 views
6

C'è una funzione R (o qualsiasi pacchetto) che permette di formattare i numeri (interi) usando prefisso unità standard (Kilo, Mega ecc ...), cosìEsiste una funzione R per numero formato utilizzando unità prefisso

10 -> 10 
100 -> 1K 
0.01 - > 10m 

ecc ... Posso farlo da solo ma preferirei non reinventare la ruota.

+0

'utils ::: print.object_size' implementa per alcune unità binarie – James

+0

vorrei solo essere attenti a fare questo w/o correzione di bozze. Ad esempio, mentre cose come 3.5 mm sono consentite dalla ISO, nell'uso standard tutti vanno con 3.5e3 km. Dal momento che non si usano mai prefissi per valori adimensionali, come pensate di aggiungere le unità fisiche da sole? –

+0

Vedo il tuo punto. Comunque quello che sto facendo non è "serio" e non ho nessuna unità. Sto solo visualizzando il valore in una trama/tabella e ho bisogno di ognuno per adattarlo a 3/4 caratteri. 10k è più compatto di 1000 o 1e + 03. – mb14

risposta

10
require(sitools) 
f2si(80000) 
[1] "80 k" 
f2si(8E12) 
[1] "8 T" 

sembra essere molto semplice in quanto aggiunge due spazi se viene utilizzato alcun prefisso SI:

f2si(80) 
[1] "80 " 

La funzione è facile da modificare includere arrotondamenti. Ho anche risolto il problema con gli spazi aggiunti.

f2si2<-function (number,rounding=F) 
{ 
    lut <- c(1e-24, 1e-21, 1e-18, 1e-15, 1e-12, 1e-09, 1e-06, 
     0.001, 1, 1000, 1e+06, 1e+09, 1e+12, 1e+15, 1e+18, 1e+21, 
     1e+24) 
    pre <- c("y", "z", "a", "f", "p", "n", "u", "m", "", "k", 
     "M", "G", "T", "P", "E", "Z", "Y") 
    ix <- findInterval(number, lut) 
    if (lut[ix]!=1) { 
     if (rounding==T) { 
     sistring <- paste(round(number/lut[ix]), pre[ix]) 
     } 
     else { 
     sistring <- paste(number/lut[ix], pre[ix]) 
     } 
    } 
    else { 
     sistring <- as.character(number) 
    } 
    return(sistring) 
} 

f2si2(12345) 
[1] "12.345 k" 
f2si2(12345,T) 
[1] "12 k" 
+0

Sembra essere esattamente quello che ho annuito, ma per qualche motivo, non riesco a installarlo :-( – mb14

+0

Bene, quale versione R, quale CRAN specchio, ...? – Roland

+0

R 2.9.0, Regno Unito (Londra) – mb14

7

Sono venuto qui con la stessa domanda. Grazie a Roland per la sua risposta; Ho costruito il suo codice con alcune modifiche:

  • Consente cifre significative da specificare quando si aggira = FALSE (default a 6, proprio come la funzione built-in 'signif')
  • non Vuol genera un errore con i valori sotto 1e-24
  • Uscite notazione scientifica (nessuna unità) per i valori di cui sopra 1e27

Spero che questo è utile.

f2si<-function (number, rounding=F, digits=ifelse(rounding, NA, 6)) 
{ 
    lut <- c(1e-24, 1e-21, 1e-18, 1e-15, 1e-12, 1e-09, 1e-06, 
     0.001, 1, 1000, 1e+06, 1e+09, 1e+12, 1e+15, 1e+18, 1e+21, 
     1e+24, 1e+27) 
    pre <- c("y", "z", "a", "f", "p", "n", "u", "m", "", "k", 
     "M", "G", "T", "P", "E", "Z", "Y", NA) 
    ix <- findInterval(number, lut) 
    if (ix>0 && ix<length(lut) && lut[ix]!=1) { 
     if (rounding==T && !is.numeric(digits)) { 
      sistring <- paste(round(number/lut[ix]), pre[ix]) 
     } 
     else if (rounding == T || is.numeric(digits)) { 
      sistring <- paste(signif(number/lut[ix], digits), pre[ix]) 
     } 
     else { 
      sistring <- paste(number/lut[ix], pre[ix]) 
     } 
    } 
    else { 
     sistring <- as.character(number) 
    } 
    return(sistring) 
} 

f2si(12345) 
[1] "12.345 k" 
f2si(12345, T) 
[1] "12 k" 
f2si(10^31) 
[1] "1e+31" # (previous version would output "1e+07 Y" 
f2si(10^-25) 
[1] "1e-25" # (previous version would throw error) 
f2si(123456789) 
[1] "123.457 M" # (previous version would output ""123.456789 M" 
f2si(123456789, digits=4) 
[1] "123.5 M" # (note .456 is rounded up to .5) 

Da questo codice è abbastanza facile scrivere una funzione simile per le unità finanziarie comunemente usati (K, MM, Bn, Tr), anche.

1

versione leggermente modificata per tenere conto di numeri negativi:

f2si<-function (number, rounding=F, digits=ifelse(rounding, NA, 6)) 
{ 
mysign <- "" 
if (number<0) { 
    mysign <- "-" 
} 
number <- abs(number) 
lut <- c(1e-24, 1e-21, 1e-18, 1e-15, 1e-12, 1e-09, 1e-06, 
    0.001, 1, 1000, 1e+06, 1e+09, 1e+12, 1e+15, 1e+18, 1e+21, 
    1e+24, 1e+27) 
pre <- c("y", "z", "a", "f", "p", "n", "u", "m", "", "k", 
    "M", "G", "T", "P", "E", "Z", "Y", NA) 
ix <- findInterval(number, lut) 
if (ix>0 && ix<length(lut) && lut[ix]!=1) { 
    if (rounding==T && !is.numeric(digits)) { 
     sistring <- paste(mysign,mysign,round(number/lut[ix]), pre[ix]) 
    } 
    else if (rounding == T || is.numeric(digits)) { 
     sistring <- paste(mysign,signif(number/lut[ix], digits), pre[ix],sep="") 
    } 
    else { 
     sistring <- paste(mysign,number/lut[ix], pre[ix],sep="") 
    } 
} else { 
    sistring <- paste(mysign,as.character(number),sep="") 
} 
return(sistring) 

}

1

ero alla ricerca di migliaia (K), milioni (M) e Billion (B) convertitore numero. Ho modificato questa routine per prendere un vettore numerico/numero singolo che sputa l'output richiesto.

CurrencyFormat <-function (number,rounding=F) 
{ 
    first <- TRUE 
    lut <- c(1, 1000, 1000000, 1000000000,1000000000000) 
    pre <- c("", "K", "M", "B", "T") 
    if (length(number) > 1) { 
     for (cnt in 1:length(number)){   
      ix <- findInterval(number[cnt], lut) 
      if (ix != 0 | ix != 1){ 
       if (rounding==T) { 
        sistring <- paste(round(number[cnt]/lut[ix]), pre[ix]) 
       } 
       else { 
        sistring <- paste(signif(number[cnt]/lut[ix],digits=5), pre[ix]) 
       } 
       if (first){ 
        tnumber <- sistring 
        fnumber <- tnumber 
        first <- FALSE 
       } 
       else 
        fnumber <- append(fnumber, sistring) 
      } 
      else { 
       sistring <- number[cnt] 
       if (first){ 
        tnumber <- sistring 
        fnumber <- tnumber 
        first <- FALSE 
       } 
       else 
        fnumber <- append(fnumber, sistring) 
      } 
     } 
     return(fnumber) 
    } 
    else{ 
     ix <- findInterval(number, lut) 
     if (ix != 0 | ix != 1){ 
      if (rounding==T) { 
       sistring <- paste(round(number/lut[ix]), pre[ix]) 
      } 
      else { 
       sistring <- paste(signif(number/lut[ix],digits=5), pre[ix]) 
      } 
      return(sistring) 
     }  
     else 
      return(number) 
    } 
} 

Esempi:

CurrencyFormat(1.25,F) 
[1] "1.25 " 

CurrencyFormat(1000.25,F) 
[1] "1.0002 K" 

CurrencyFormat(c(1,45,1234, 4.36e+06, 2.84e+04, 2.01e+06),F) 
[1] "1 "  "45 "  "1.234 K" "4.36 M" "28.4 K" "2.01 M"