长数字作为字符串

Long Numbers As A Character String

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

示例:

bigonumber <- 429382748394831049284934

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

options(digits=...) 将无法使用,因为号码超过 22 位。

当我做

as.character(bigonumber) 

我得到的是“4.29382748394831e+23”

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

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

(是的,在完美的世界中,我的上游数据提供者会使用散列而不是长数字和每个月保持不变的静态列数,但我不能向他们发号施令.)

您可以使用

取消科学记数法
options(scipen=999)

如果你定义数字那么

bigonumber <- 429382748394831049284934

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

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

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

#[1] "429382748394831019507712"

如@SabDeM 所指出的,最后的数字没有保留。偶数设置

options(digits=22)

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

作为旁注,有一个名为 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

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

在 bigonumber 上使用 digest::digest 自行生成数字的 md5 散列?

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

使用 "scan" 读取文件 - "what" 参数可让您定义每列的输入类型。

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

options( digits = 22 )

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

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

bignums
429382748394831049284934
429382748394831049284935
429382748394831049284936
429382748394831049284937
429382748394831049284938
429382748394831049284939

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

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

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

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