我正在使用fread()
中的data.table
来有效地将大型矩形CSV文件读取到R
个double
(并且只有double
)个值 - 没有遗漏的元素。
然而,如果我的科学记数法中的数字非常小,它将被转换为破坏整个阅读的字符。这是错误消息(例如,每个小数字都有多个):
16:在恐惧中(“SomeCSVFile”):
Bumped column 560在数据行16799上键入字符,字段包含'-2.1412168512924677E-308'。将此列中先前读取的值从整数或数字强制转换回可能不是无损的字符;例如,如果'00'和'000'发生之前它们现在只是'0',并且可能与',,'和',NA'的处理不一致(如果它们发生在碰撞之前的这一列中) )。如果这很重要,请重新运行并为此列设置'colClasses'为'character'。请注意,列类型检测使用前5行,中间5行和后5行,所以希望此消息非常罕见。如果向datatable-help报告,请重新运行并包含verbose = TRUE的输出。
我希望函数将它们设置为零或以最小可能值截断它们(两者都很好)。
答案 0 :(得分:6)
为了重现这一点,我把这个内容放在一个文本文件中:
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
正如Ben Bolker siad在评论中所说的那样。如果您不关心微小数字,只想将它们视为零,则将列作为字符导入,然后使用as.numeric
。
the_data <- fread("the file.txt", colClasses = "character")
the_data$DodgyColumn <- as.numeric(the_data$DodgyColumn)