fread from data.table软件包可以';不要读小数字

fread from data.table软件包可以';不要读小数字,r,csv,memory-management,data.table,R,Csv,Memory Management,Data.table,我正在使用data.table中的fread()有效地将大型矩形CSV文件读入R,这些文件都是double(并且只有double)值,没有缺少的元素 然而,如果科学记数法中有非常小的数字,它会被转换成字符,这会破坏整个阅读。以下是错误消息(例如,每个小数字有多个): 16:在fread(“SomeCSVFile”): 将列560撞击到数据行16799上的类型字符,字段包含“-2.1412168512924677E-308”。将此列中以前读取的值从整数或数字强制返回到可能不会丢失的字符;e、 例如

我正在使用
data.table
中的
fread()
有效地将大型矩形CSV文件读入
R
,这些文件都是
double
(并且只有
double
)值,没有缺少的元素

然而,如果科学记数法中有非常小的数字,它会被转换成字符,这会破坏整个阅读。以下是错误消息(例如,每个小数字有多个):

16:在fread(“SomeCSVFile”):
将列560撞击到数据行16799上的类型字符,字段包含“-2.1412168512924677E-308”。将此列中以前读取的值从整数或数字强制返回到可能不会丢失的字符;e、 例如,如果“00”和“000”在碰撞之前出现,则它们现在将仅为“0”,并且对“、”和“、NA”的处理可能也不一致(如果它们在碰撞之前出现在本列中)。如果这很重要,请重新运行并将此列的“colClasses”设置为“character”。请注意,列类型检测使用前5行、中间5行和最后5行,因此希望此消息非常罕见。如果向datatable帮助报告,请重新运行并包含verbose=TRUE的输出


我希望函数将它们设置为零,或将它们截断为最小可能值(两者都可以)。

要再现这一点,我将此内容放在文本文件中:

x
1
1
1
1
1
1e-309
然后我调用了
fread(“that file.txt”)


R可以存储的最小正数的大小为

format(.Machine$double.xmin, digits = 22)
## [1] "2.2250738585072013828e-308"
您的数据文件包含小于此限制的值
-2.1412168512924677E-308
。为了防止R将值视为零,data.table包已将列转换为字符串。这将阻止数据精度丢失

如果需要使用此大小的值,则使用
Rmpfr
包以更高的精度存储数字。将它们作为字符导入(使用
colClasses
;请参阅数据表警告文本)。然后使用

library(Rmpfr)
mpfr("-2.1412168512924677E-308")
## 1 'mpfr' number of precision  70   bits 
## [1] -2.1412168512924676999992e-308

正如本·博尔克在评论中所说的那样。如果您不关心微小的数字,只想将它们视为零,那么将列作为字符导入,然后使用
作为.numeric

the_data <- fread("the file.txt", colClasses = "character")
the_data$DodgyColumn <- as.numeric(the_data$DodgyColumn)

the_data为了重现这一点,我将此内容放在一个文本文件中:

x
1
1
1
1
1
1e-309
然后我调用了
fread(“that file.txt”)


R可以存储的最小正数的大小为

format(.Machine$double.xmin, digits = 22)
## [1] "2.2250738585072013828e-308"
您的数据文件包含小于此限制的值
-2.1412168512924677E-308
。为了防止R将值视为零,data.table包已将列转换为字符串。这将阻止数据精度丢失

如果需要使用此大小的值,则使用
Rmpfr
包以更高的精度存储数字。将它们作为字符导入(使用
colClasses
;请参阅数据表警告文本)。然后使用

library(Rmpfr)
mpfr("-2.1412168512924677E-308")
## 1 'mpfr' number of precision  70   bits 
## [1] -2.1412168512924676999992e-308

正如本·博尔克在评论中所说的那样。如果您不关心微小的数字,只想将它们视为零,那么将列作为字符导入,然后使用
作为.numeric

the_data <- fread("the file.txt", colClasses = "character")
the_data$DodgyColumn <- as.numeric(the_data$DodgyColumn)


通过提供一些重现问题的样本数据,这个问题可以得到极大的改善。真正的问题是什么?这些小数值有什么实际用途吗?谁首先允许Excel工作表生成它们?如果你想把它们设置为零,只要把它们读入,然后
matrix[is.character(matrix)]@CarlWitthoft我不使用Excel,但谢谢你的解决方案。哎哟,我不好,因为我假设所有的
csv
都是从Excel的卑鄙陷阱中产生的。当我尝试用非常小的指数来输入数字时,它们被解读为0-您需要为您的设置添加一个可复制的示例+操作系统/软件包详细信息-因为这不是一个好问题。通过提供一些重现问题的示例数据,可以极大地改进此问题。真正的问题是什么?这些小数值有什么实际用途吗?谁首先允许Excel工作表生成它们?如果你想把它们设置为零,只要把它们读入,然后
matrix[is.character(matrix)]@CarlWitthoft我不使用Excel,但谢谢你的解决方案。哎哟,我不好,因为我假设所有的
csv
都是从Excel的卑鄙陷阱中产生的。当我尝试用非常小的指数来输入数字时,它们被解读为0-您需要为您的设置添加一个可复制的示例+操作系统/软件包详细信息-因为这不是一个好问题,但这意味着如果我的矩阵不是统一的数字,我甚至不能再使用
fread
。知道
-2.14…E-308
-2.225..E-308
之间的差异对我的用例来说是无关紧要的(即,让它舍入到零或合理的值)。你可以使用
fread
;您只需要指定
colClasses
参数。重新阅读警告文字。你是否真的复制了OP的问题(如果是,请在你的答案中添加一个可复制的例子)?他们所描述的并没有发生在我身上——小数字被解读为0。@eddi回答会按要求更新。将前5个数字设置为合理的数字,这样列将被视为数字,然后提供一个非常小的数字。从1.8.11新闻中:“
fread(“1.46761e-313\n”)
检测到Erage错误,因此以字符形式读取。它现在以数字形式读取,但带有详细警告。感谢Heather Turner提供的详细报告,”但这意味着,如果我的矩阵不是统一的数字,我甚至不能再使用
fread
。知道
-2.14…E-308
-2.225..E-308
之间的差异对我的用例来说是无关紧要的(即,让它舍入到零或合理的值)。你可以使用
fread
;您只需要指定
colClasses
argueme