已编辑(基于 cmets):
以下函数适用于有效数字为 15 或更少的数字:
digits<-function(x){
## make sure x is a number, if not stop
tryCatch(
{
x/1
},
error=function(cond) {
stop('x must be a number')
}
)
## use nchar() and strsplit() to determine number of digits before decimal point
fixed<-nchar(strsplit(as.character(x),"\\.")[[1]][1])
## check if negative
if(substr(strsplit(as.character(x),"\\.")[[1]][1],1,1)=="-"){fixed<-fixed-1}
## check if -1<x<1
if(as.numeric(strsplit(as.character(x),"\\.")[[1]][1])==0){fixed<-fixed-1}
## use nchar() and strsplit() to determine number of digits after decimal point
decimal<-nchar(strsplit(as.character(x),"\\.")[[1]][2])
## for integers, replace NA decimal result with 0
if(is.na(nchar(strsplit(as.character(x),"\\.")[[1]][2]))){decimal<-0}
## return results
print(paste0("fixed: ",fixed," and decimal: ", decimal))
}
如果您想将负号 (-) 计为数字,则需要删除:
## check if negative
if(substr(strsplit(as.character(x),"\\.")[[1]][1],1,1)=="-"){fixed<-fixed-1}
注意:15 位或更少有效数字的限制基于 8 字节浮点表示。
我能够克服这个问题的唯一方法是使用下面的代码。
digits<-function(x){
tryCatch(
{
as.numeric(x)/1
},
error=function(cond) {
stop('x must be a number')
}
)
j <- 0
num <- x
fixed <- 0
decimal <- 0
for(i in 1:nchar(x)){
if(substr(num, i, i) == "."){
j <- 1
} else if(j==0){
fixed <- fixed + 1
} else{
decimal <- decimal + 1
}
}
if(substr(x,1,1)=="-" & substr(as.numeric(x),2,2)==0){
fixed<-fixed-2
}else if(substr(x,1,1)=="-"){
fixed<-fixed-1
}else if(substr(as.numeric(x),1,1)==0){
fixed<-fixed-1
}else{}
print(paste0("fixed: ",fixed," and decimal: ", decimal))
}
但是,此代码需要将数字作为字符串传递给函数,以便计算传递的 15 位有效数字,如下所示:
x<-"111111111111111111111111111111111111.22222222222222222222222222222222222222222222222"
digits(x)
返回:
[1]“固定:36,十进制:47”
这会限制此函数的应用程序,因为它不能在dplyr 管道中使用,并且您将不会收到先前四舍五入的数字的准确结果。例如,使用与上面相同的数字,但将其存储为数字而不是字符串会产生以下结果:
x<-111111111111111111111111111111111111.22222222222222222222222222222222222222222222222
digits(x)
[1]“固定:1,十进制:18”
我希望这至少会有所帮助!