R 将数字转换为SI前缀
是否有R函数(或任何包)允许使用标准单位前缀(千、兆等)格式化数字(整数),所以 等等。。。 我可以自己做,但我宁愿不重新发明轮子R 将数字转换为SI前缀,r,number-formatting,R,Number Formatting,是否有R函数(或任何包)允许使用标准单位前缀(千、兆等)格式化数字(整数),所以 等等。。。 我可以自己做,但我宁愿不重新发明轮子 require(sitools) f2si(80000) [1] "80 k" f2si(8E12) [1] "8 T" 如果不使用SI前缀,它会附加两个空格,这似乎是非常简单的: f2si(80) [1] "80 " 该函数易于修改以包含舍入。我还通过附加空格解决了这个问题 f2si2<-function (number,rounding=F)
require(sitools)
f2si(80000)
[1] "80 k"
f2si(8E12)
[1] "8 T"
如果不使用SI前缀,它会附加两个空格,这似乎是非常简单的:
f2si(80)
[1] "80 "
该函数易于修改以包含舍入。我还通过附加空格解决了这个问题
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"
f2si2我带着同样的问题来到这里。感谢罗兰的回答;我在他的代码的基础上做了一些修改:
- 允许在舍入=FALSE时指定有效数字(默认值为6,与“signif”内置函数类似)
- 不会抛出值低于1e-24的错误
- 输出1e27以上数值的科学符号(无单位)
希望这是有帮助的
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)
f2si稍微修改版本,以考虑负数:
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)
f2si我在寻找千(K)、百万(M)和十亿(B)数字转换器。我修改了这个例程,以获取一个数字向量/单个数字,输出所需的输出
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)
}
}
当使用dplyr中的
时,使用
case_进行矢量化非常简单,而且对眼睛来说更容易:
library(dplyr)
si_number = function(x, digits) {
compress = function(x, n) {
signif(x * 10^(-n), digits)
}
case_when(
x >= 1e6 ~ paste0(compress(x, 6), "M"),
x >= 1000 ~ paste0(compress(x, 3), "k"),
x >= 1 ~ as.character(compress(x, 0)),
x >= 0.001 ~ paste0(compress(x, -3), "m"),
x >= 1e-6 ~ paste0(compress(x, -6), "u")
)
}
utils:::print.object\u size
为一些二进制单位实现它。我只需要小心,不需要校对。例如,虽然ISO允许使用3.5毫米,但在标准使用中,每个人都使用3.5e3公里。既然人们从不使用前缀来表示无量纲值,那么你打算如何附加物理单位呢?我明白你的意思。然而,我所做的不是“认真的”,我没有任何单位。我只是在一个绘图/表格中显示值,我需要每个值匹配3/4个字符。10k比1000或1e+03更紧凑。?scales::label_number_si
。似乎正是我想要的,但由于某些原因,我无法安装它:-(好吧,哪个R版本,哪个CRAN镜像…?更新R。当前版本是2.15.1。工作正常,唯一的问题是它没有截断(12345->12.345 K)因此,这是一个有点无用的重新发明轮子的东西。我在gdata
包中找到了humanReadable
,它甚至可以进行额外的控制。唯一的问题是它添加了一个易于删除的“B”(代表字节)。
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"
library(dplyr)
si_number = function(x, digits) {
compress = function(x, n) {
signif(x * 10^(-n), digits)
}
case_when(
x >= 1e6 ~ paste0(compress(x, 6), "M"),
x >= 1000 ~ paste0(compress(x, 3), "k"),
x >= 1 ~ as.character(compress(x, 0)),
x >= 0.001 ~ paste0(compress(x, -3), "m"),
x >= 1e-6 ~ paste0(compress(x, -6), "u")
)
}