【问题标题】:Long Numbers As A Character String长数字作为字符串
【发布时间】:2015-11-27 03:55:51
【问题描述】:

作为我的数据集的一部分,其中一列是一系列 24 位数字。

例子:

bigonumber <- 429382748394831049284934

当我使用data.table::freadread.csv 导入它时,它以指数格式显示为数字(例如:4.293827e+23)。

options(digits=...) 不起作用,因为该号码超过 22 位。

当我这样做时

as.character(bigonumber) 

我得到的是“4.29382748394831e+23”

有没有办法将bigonumber 转换为字符串并将所有数字显示为字符?我不需要对其进行任何数学运算,但我确实需要对其进行搜索并对其进行dplyr joins。

导入后我需要这样做,因为列号每个月都不同。

(是的,在完美的世界中,我的上游数据提供者会使用散列而不是长数字和静态列数,每个月都保持不变,但我无法向他们规定。)

【问题讨论】:

  • ?fread?read.csv 都包含并解释了colClasses

标签: r data.table


【解决方案1】:

您可以在 fread 或 read.csv 语句中指定 colClasses。

bignums
429382748394831049284934
429382748394831049284935
429382748394831049284936
429382748394831049284937
429382748394831049284938
429382748394831049284939

bignums <- read.csv("~/Desktop/bignums.txt", sep="", colClasses = 'character')

【讨论】:

  • 这是正确的答案。 colClasses 也适用于 fread
  • 您甚至可以通过read.csv("~/Desktop/bignums.txt", sep="", colClasses = c(bignums='character')) 只保留一列。
【解决方案2】:

你可以用

压制科学记数法
options(scipen=999)

如果你定义了数字那么

bigonumber <- 429382748394831049284934

你可以把它转换成字符串:

big.o.string <- as.character(bigonumber)

不幸的是,这不起作用,因为 R 将数字转换为双精度数,从而失去精度:

#[1] "429382748394831019507712"

正如@SabDeM 所指出的那样,不保留最后一位数字。偶数设置

options(digits=22)

没有帮助,无论如何,22 是允许的最大数字;在您的情况下,有 24 位数字。因此,您似乎必须直接将数据作为字符或因子读取。已经发布了很好的答案,展示了如何实现这一点。

附带说明,有一个名为gmp 的包允许使用任意大的整数。但是,有一个问题:它们必须被读取为字符(同样,为了防止 R 的内部转换为双精度)。

library(gmp)
bigonumber <- as.bigz("429382748394831049284934")
> bigonumber
Big Integer ('bigz') :
[1] 429382748394831049284934
> class(bigonumber)
[1] "bigz"

优点是您确实可以将这些条目视为数字并在保留所有数字的同时执行计算。

> bigonumber * 2
#Big Integer ('bigz') :
#[1] 858765496789662098569868

这个包和我在这里的回答可能无法解决您的问题,因为直接将数字作为字符读取是实现目标的更简单方法,但我想我可能会将其发布为可能需要使用大的用户的信息超过 22 位的整数。

【讨论】:

    【解决方案3】:

    在 bigonumber 上使用 digest::digest 自己生成数字的 md5 哈希?

    bigonumber <- 429382748394831049284934
    hash_big <- digest::digest(bigonumber)
    hash_big
    # "e47e7d8a9e1b7d74af6a492bf4f27193"
    

    【讨论】:

    • 那太好吃了。我认为今后我会在新专栏中这样做。
    • 但这仅适用于您还没有因为尝试将过多的数字存储为数字而丢失精度...
    【解决方案4】:

    我在发布答案之前看到了这个,但这里不再看到了。

    options(scipen) 设置为较大的值,这样就不会被截断:

    options(scipen = 999)
    bigonumber <- 429382748394831049284934
    bigonumber
    # [1] 429382748394831019507712
    as.character(bigonumber)
    # [1] "429382748394831019507712"
    

    【讨论】:

    • 这看起来是几个不错的选择中最好的一个。谢谢!埃塔:嗯。最后几个确实是错误的。不知道是什么原因造成的。
    【解决方案5】:

    使用“scan”读取文件——“what”参数让您定义每列的输入类型。

    【讨论】:

      【解决方案6】:

      如果您希望将数字作为数字,则无法打印所有值。 digits 选项最多允许 22 位数字。范围是从 1 到 22。它使用print.default 方法。你可以设置它:

      options( digits = 22 )
      

      即使使用此选项,数字也会改变。我忽略了为什么会发生这种情况,很可能是因为您要打印的对象(数字)比允许的数字长,所以 R 做了一些奇怪的事情。我会调查一下。

      【讨论】:

        猜你喜欢
        • 2012-10-23
        • 1970-01-01
        • 1970-01-01
        • 2016-01-01
        • 2014-08-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多