ОТРЕДАКТИРОВАНО (на основе комментариев):
Следующая функция будет работать для чисел с 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"
Я надеюсь, что это хоть немного поможет!
person
Joshua Mire
schedule
08.06.2020
v1 <- c(12, 12.657, 12.1)
, каким будет вывод, т.е. значения печати равныv1# [1] 12.000 12.657 12.100
- person akrun   schedule 09.06.2020sapply
все время может стать утомительным, когда оно должно было быть векторизовано заранее.) - person r2evans   schedule 09.06.2020format(0.3/0.1, digits=17)
показывает вам2.999...96
, вы говорите, что пять девяток, за которыми следует что-то, нужно округлить в большую сторону? А как насчет1.000...1
, что пять нулей, за которыми следует что-то, нужно округлить в меньшую сторону? Отсюда скользкий склон может только круче. - person r2evans   schedule 09.06.2020