我想计算数字向量x的小数点前的位数,数字大于或等于1.例如,如果向量是
x <- c(2.85, 356.01, 66.1, 210.0, 1445.11, 13.000)
Run Code Online (Sandbox Code Playgroud)
我的代码应该返回一个包含整数1,3,2,3,4,2的向量
有谁知道怎么做?
Gre*_*gor 16
我想将评论留在评论中是没有意义的,但这些都有效:
floor(log10(x)) + 1
nchar(trunc(x))
Run Code Online (Sandbox Code Playgroud)
和那样的变种.
对于小问题,我最喜欢该nchar()解决方案,对负值进行一次修改:
nDigits <- function(x) nchar( trunc( abs(x) ) )
# Test
nDigits(100)
nDigits(-100)
# both have 3 digits
nDigits(3)
nDigits(-3)
nDigits(0.1)
nDigits(-0.1)
# all have 1 digit
nDigits(1 / .Machine$double.eps)
nDigits(-1 / .Machine$double.eps)
# both have 16 digits
Run Code Online (Sandbox Code Playgroud)
如果要使对数解有效,则需要考虑负值和0到1之间的值。对我而言,此解有点复杂:
nDigits2 <- function(x){
truncX <- floor(abs(x))
if(truncX != 0){
floor(log10(truncX)) + 1
} else {
1
}
}
Run Code Online (Sandbox Code Playgroud)
这是微基准比较的输出(100,000次)。字符计数解决方案的代码更简单,但是更慢(减少了3-4倍):
对于大于1的整数(单位:纳秒):
expr min lq mean median uq max neval
nDigits(100) 1711 2139 2569.2819 2566 2994 2234046 1e+05
nDigits2(100) 0 428 861.5435 856 856 5670216 1e+05
Run Code Online (Sandbox Code Playgroud)
对于非常小的小数点(单位:纳秒):
expr min lq mean median uq max neval
nDigits(1/.Machine$double.eps) 2994 4277 5066.321 4705 4705 4477928 1e+05
nDigits2(1/.Machine$double.eps) 428 1283 1588.382 1284 1711 2042458 1e+05
Run Code Online (Sandbox Code Playgroud)