R数值到char精度损失 [英] R numeric to char precision loss

查看:139
本文介绍了R数值到char精度损失的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将多位数的数字矢量转换为字符.我在此处尝试了以下解决方案,该解决方案适用于一个数字,但不适用于矢量.没关系

I want to convert my many-digit numeric vector to character. I tried the following solutions here which works for one number but not for a vector. This is OK

options(digits=20)
options(scipen=99999)
x<-129483.19999999999709;format(round(x, 12), nsmall = 12)
[1] "129483.199999999997"

但这不是.如何保持数字矢量字符的数字精度?

But this is not. how to keep numeric precision in characters for numeric vectors?

> y <- c(129483.19999999999709, 1.3546746874,687676846.2546746464)

特别有问题的是687676846.2546746464也尝试过:

Specially problematic is 687676846.2546746464 Also tried:

> specify_decimal(y, 12)
[1] "129483.199999999997"    "1.354674687400"         "687676846.254674673080"
> formatC(y, digits = 12, format = "f")
[1] "129483.199999999997"    "1.354674687400"         "687676846.254674673080"
> formattable(y, digits = 12, format = "f")
[1] 129483.199999999997    1.354674687400         687676846.254674673080
> sprintf(y, fmt='%#.12g')
[1] "129483.200000" "1.35467468740" "687676846.255"
> sprintf(y, fmt='%#.22g')
[1] "129483.1999999999970896" "1.354674687399999966075" "687676846.2546746730804"

预期结果:

[1] "129483.199999999997" "1.354674687400" "687676846.254674646400"

精度损失似乎只发生一次,不再重复.

It seems that precision loss occurs once only, it is not repeated.

> require(dplyr)
> convert <- function(x) as.numeric(as.character(x))
> 687676846.2546746464 %>% convert
[1] 687676846.25467503
> 687676846.2546746464 %>% convert %>% convert %>% convert
[1] 687676846.25467503

这里我只有5位数的精度,但是更麻烦的是我事先不知道要达到什么精度.

Here I only have 5-digit precision, but more problematic I can't know beforehand what precision I am going to get..

推荐答案

最后,我可以使用这些功能来完成我想做的事情. addtrailingzeroes会将十进制后的零添加到x.

At the end I could do what I wanted using these functions. addtrailingzeroes will add a number of zeroes after decimal to x.

nbdec <- function(x) {
  x1 <- as.character(x)
  xsplit <- strsplit(x1,"\\.")
  xlength <- sapply(xsplit, function(d) nchar(d)[2])
  xlength <- ifelse(is.na(xlength), 0, xlength)
  return(xlength)
}

trailingzeroes <- function(x, dig) {
  res <- rep(NA, length(x))
  for( i in 1:length(x)) {
    if(!is.na(x[i])) res[i] <- { paste0(rep(0,max(0,dig-nbdec(x[i]))), collapse="") }
    else { res[i] <- ""}
    }
return(res)
}

trailingcommas <- function(x) ifelse(is.na(x), NA, ifelse(nbdec(x)==0, ".",""))

addtrailingzeroes <- function(x, digits) {
  return(ifelse(!is.na(x), paste0(x, trailingcommas(x), trailingzeroes(x, digits)),NA))
}

但是,要抑制错误和舍入错误,必须先使用roundnumerics.max裁剪x:

However to suppress inaccuracies and rounding mistakes, x has to be cropped first using roundnumerics.max:

roundnumerics.max <- function(df, startdig=12) {
  for(icol in 1:ncol(df)) {
    if( is.numeric(df[,icol])) {
      dig <- startdig
      while(any(!as.numeric(as.character(df[,icol])) %==% df[,icol])) {
        dig <- dig-1
        df[,icol] <- round(df[,icol], digits=dig)
        if(dig==0) {
          break
          pprint("ERROR: zero numeric accuracy")
        }
      } 
      pprint("Numeric accuracy for column ",icol," ", colnames(df)[icol], " is ", dig)
    }
  }
  return(data.frame(df, stringsAsFactors = F))
}

这是缓慢的过程,远非优雅...我仍然认为很难相信R对16个有效数字有这样的精度限制,并且添加了不准确的噪声,当您尝试增加digits选项... 不提供,让您知道...

This is slow and far from elegant... I still think it hard to believe that R has such an accuracy limitation to 16 significant digits, and adds inaccurate noise that causes divergences when you try to increase the digits option...Without letting you know...

这篇关于R数值到char精度损失的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆