自定义轮数函数
Custom round number function
我正在尝试创建一个函数 (my.func
) 可以将 number/numeric vector/matrix/data.frame 有条件地舍入到它的值。
例如:my.func(1630.123)
将给出 1630 而 my.func(0.123)
将 return 0.12
我试过:
my.func <- function(x0, ...) {
unlist(lapply(x0, function(x) {
if(x >= 100) return(round(x, 0))
if(x >= 10 & x < 100) return(round(x, 1))
if(x >= 0.1 & x < 10) return(round(x, 2))
if(x >= 0.01 & x < 0.1) return(round(x, 3))
if(x >= 0.001 & x < 0.01) return(round(x, 4))
if(x >= 0.0001 & x < 0.001) return(round(x, 5))
if(x >= 0.00001 & x < 0.0001) return(round(x, 6))
if(x >= 0.000001 & x < 0.00001) return(round(x, 7))
if(x >= 0.0000001 & x < 0.000001) return(round(x, 8))
if(x < 0.0000001) return(x)
}))
}
适用于数字和矢量但不适用于 matrix/data.frame.
我可以放入 if
并循环 matrix/df 但可能还有另一种方法可以做到这一点,更快更容易
另一个例子:
my.func(c(1.314315, 125135.1234, 0.0124133, .00000234))
期望 return 1.31, 125135, 0.012, 0.0000023
您可能希望 signif
四舍五入到给定的有效数字位数。
x <- runif(16) * 10^(7*runif(16)-5)
cbind(x, mx = my.func(x), sx = signif(x, 3))
x mx sx
[1,] 1.395044e-01 1.40e-01 1.40e-01
[2,] 9.751368e-06 9.80e-06 9.75e-06
[3,] 3.451619e-04 3.50e-04 3.45e-04
[4,] 2.203204e-03 2.20e-03 2.20e-03
[5,] 6.660684e-05 6.70e-05 6.66e-05
[6,] 3.143732e-02 3.10e-02 3.14e-02
[7,] 1.976514e-05 2.00e-05 1.98e-05
[8,] 3.747693e+00 3.75e+00 3.75e+00
[9,] 4.099091e-03 4.10e-03 4.10e-03
[10,] 3.124711e-02 3.10e-02 3.12e-02
[11,] 3.162478e-04 3.20e-04 3.16e-04
[12,] 1.029170e-05 1.00e-05 1.03e-05
[13,] 6.746715e-04 6.70e-04 6.75e-04
[14,] 7.667078e-03 7.70e-03 7.67e-03
[15,] 2.002506e-03 2.00e-03 2.00e-03
[16,] 2.164340e-03 2.20e-03 2.16e-03
或者是否有特殊原因需要 0 以上的额外数字? IE。你为什么不想要
if(x >= 10 & x < 100) return(round(x, 1))
if(x >= 1 & x < 10) return(round(x, 2))
if(x >= 0.1 & x < 1) return(round(x, ?)) # <----- This line
if(x >= 0.01 & x < 0.1) return(round(x, 3))
if(x >= 0.001 & x < 0.01) return(round(x, 4))
更新
如果您只想要一个输出易于阅读的数字的函数,我建议您使用 signif
对数字进行四舍五入,使用 sprintf
进行打印,并使用 trim 关闭尾部零和小数分隔符 sub
.
sub("\.$", "", sub(".0+$", "", sprintf("%f", signif(x, 3))))
[1] "0.000226" "3.8" "363" "1380" "0.0016" "0.000331"
[7] "0.000047" "0.20" "0.047" "105" "22" "0.000013"
[13] "0.000013" "0.054" "2.6" "0.31"
可能对 formatC
感兴趣的另一个函数,但您必须忍受非常大或非常小的值的科学记数法。
formatC(x, digits=3)
[1] "0.000226" "3.82" " 363" "1.38e+03" "0.00163" "0.000331"
[7] "4.68e-05" "0.208" "0.0479" " 105" "22.6" "1.25e-05"
[13] "1.25e-05" "0.0542" "2.69" "0.311"
它不适用于 data.frame,因为 R 不能用不同的数字舍入不同的行。因此,您必须 select 变量中要应用函数的数字,例如最大值,像这样:
myfun = function(val) {
cutvec = 10^(-7:2)
cutvec = cutvec[!cutvec == 1]
rounding = 8:0
find.round = rounding[max(which(val > cutvec))]
return(find.round)
}
data(mtcars)
digits = myfun(max(mtcars$disp))
round(mtcars$disp, digits)
我正在尝试创建一个函数 (my.func
) 可以将 number/numeric vector/matrix/data.frame 有条件地舍入到它的值。
例如:my.func(1630.123)
将给出 1630 而 my.func(0.123)
将 return 0.12
我试过:
my.func <- function(x0, ...) {
unlist(lapply(x0, function(x) {
if(x >= 100) return(round(x, 0))
if(x >= 10 & x < 100) return(round(x, 1))
if(x >= 0.1 & x < 10) return(round(x, 2))
if(x >= 0.01 & x < 0.1) return(round(x, 3))
if(x >= 0.001 & x < 0.01) return(round(x, 4))
if(x >= 0.0001 & x < 0.001) return(round(x, 5))
if(x >= 0.00001 & x < 0.0001) return(round(x, 6))
if(x >= 0.000001 & x < 0.00001) return(round(x, 7))
if(x >= 0.0000001 & x < 0.000001) return(round(x, 8))
if(x < 0.0000001) return(x)
}))
}
适用于数字和矢量但不适用于 matrix/data.frame.
我可以放入 if
并循环 matrix/df 但可能还有另一种方法可以做到这一点,更快更容易
另一个例子:
my.func(c(1.314315, 125135.1234, 0.0124133, .00000234))
期望 return 1.31, 125135, 0.012, 0.0000023
您可能希望 signif
四舍五入到给定的有效数字位数。
x <- runif(16) * 10^(7*runif(16)-5)
cbind(x, mx = my.func(x), sx = signif(x, 3))
x mx sx [1,] 1.395044e-01 1.40e-01 1.40e-01 [2,] 9.751368e-06 9.80e-06 9.75e-06 [3,] 3.451619e-04 3.50e-04 3.45e-04 [4,] 2.203204e-03 2.20e-03 2.20e-03 [5,] 6.660684e-05 6.70e-05 6.66e-05 [6,] 3.143732e-02 3.10e-02 3.14e-02 [7,] 1.976514e-05 2.00e-05 1.98e-05 [8,] 3.747693e+00 3.75e+00 3.75e+00 [9,] 4.099091e-03 4.10e-03 4.10e-03 [10,] 3.124711e-02 3.10e-02 3.12e-02 [11,] 3.162478e-04 3.20e-04 3.16e-04 [12,] 1.029170e-05 1.00e-05 1.03e-05 [13,] 6.746715e-04 6.70e-04 6.75e-04 [14,] 7.667078e-03 7.70e-03 7.67e-03 [15,] 2.002506e-03 2.00e-03 2.00e-03 [16,] 2.164340e-03 2.20e-03 2.16e-03
或者是否有特殊原因需要 0 以上的额外数字? IE。你为什么不想要
if(x >= 10 & x < 100) return(round(x, 1))
if(x >= 1 & x < 10) return(round(x, 2))
if(x >= 0.1 & x < 1) return(round(x, ?)) # <----- This line
if(x >= 0.01 & x < 0.1) return(round(x, 3))
if(x >= 0.001 & x < 0.01) return(round(x, 4))
更新
如果您只想要一个输出易于阅读的数字的函数,我建议您使用 signif
对数字进行四舍五入,使用 sprintf
进行打印,并使用 trim 关闭尾部零和小数分隔符 sub
.
sub("\.$", "", sub(".0+$", "", sprintf("%f", signif(x, 3))))
[1] "0.000226" "3.8" "363" "1380" "0.0016" "0.000331" [7] "0.000047" "0.20" "0.047" "105" "22" "0.000013" [13] "0.000013" "0.054" "2.6" "0.31"
可能对 formatC
感兴趣的另一个函数,但您必须忍受非常大或非常小的值的科学记数法。
formatC(x, digits=3)
[1] "0.000226" "3.82" " 363" "1.38e+03" "0.00163" "0.000331" [7] "4.68e-05" "0.208" "0.0479" " 105" "22.6" "1.25e-05" [13] "1.25e-05" "0.0542" "2.69" "0.311"
它不适用于 data.frame,因为 R 不能用不同的数字舍入不同的行。因此,您必须 select 变量中要应用函数的数字,例如最大值,像这样:
myfun = function(val) {
cutvec = 10^(-7:2)
cutvec = cutvec[!cutvec == 1]
rounding = 8:0
find.round = rounding[max(which(val > cutvec))]
return(find.round)
}
data(mtcars)
digits = myfun(max(mtcars$disp))
round(mtcars$disp, digits)