【发布时间】:2014-02-08 19:40:58
【问题描述】:
[这是一篇文章中的多个错误报告/功能请求,但它们不一定是孤立的。提前为怪物帖子道歉。按照帮助(data.table)的建议在此处发布。另外,我是 R 新手;如果我没有在下面的代码中遵循最佳实践,请道歉。我在努力。]
1。 rbindlist 在 6 * 8GB 文件上崩溃(我有 128GB 内存)
首先我想报告使用 rbindlist 附加大型 data.tables 会导致 R 出现段错误(ubuntu 13.10,打包的 R 版本 3.0.1-3ubuntu1,从 CRAN 的 R 中安装的 data.table)。该机器具有 128 GiB 的 RAM;所以,考虑到数据的大小,我不应该用完内存。
我的代码:
append.tables <- function(files) {
moves.by.year <- lapply(files, fread)
move <- rbindlist(moves.by.year)
rm(moves.by.year)
move[,week_end := as.Date(as.character(week_end), format="%Y%m%d")]
return(move)
}
崩溃消息:
append.tables crashes with this:
> system.time(move <- append.tables(files))
*** caught segfault ***
address 0x7f8e88dc1d10, cause 'memory not mapped'
Traceback:
1: rbindlist(moves.by.year)
2: append.tables(files)
3: system.time(move <- append.tables(files))
有 6 个文件,每个大约 8 GiB 或 1 亿行长,包含 8 个变量,制表符分隔。
2。 fread 可以接受多个文件名吗?
无论如何,我认为这里更好的方法是允许 fread 将文件作为文件名的向量:
files <- c("my", "files", "to be", "appended")
dt <- fread(files)
据推测,您可以在幕后节省更多的内存,而不必同时保留所有这些对象,因为作为 R 的用户似乎是必要的。
3。 colClasses 给出错误信息
我的第二个问题是我需要为我的一种数据类型指定a custom coercion handler,但这失败了:
dt <- fread(tfile, colClasses=list(date="myDate"))
Error in fread(tfile, colClasses = list(date = "myDate")) :
Column name 'myDate' in colClasses not found in data
是的,在日期的情况下,一个简单的:
dt[,date := as.Date(as.character(date), format="%Y%m%d")]
有效。
但是,我有一个不同的用例,即在从字符转换之前从其中一个数据列中去除小数点。这里的精度非常重要(因此我们需要使用整数类型),从 double 类型强制转换为整数会导致精度丢失。
现在,我可以通过一些 system() 调用来附加文件并通过一些 sed 魔法(此处简化)(其中 tfile 是另一个临时文件)来处理这些文件:
if (has_header) {
tfile2 <- tempfile()
system(paste("echo fakeline >>", tfile2))
system(paste("head -q -n1", files[[1]], ">>", tfile2))
system(paste("tail -q -n+2", tfile2, paste(files, collapse=" "),
" | sed 's/\\.//' >>", tfile), wait=wait)
unlink(tfile2)
} else {
system(paste("cat", paste(files, collapse=" "), ">>", tfile), wait=wait)
}
但这涉及一个额外的读/写周期。我有 4 TiB 的数据要处理,这是很多额外的读写(不,不是全部到一个 data.table。大约 1000 个。)
4。 fread 认为命名管道是空文件
我通常离开 wait=TRUE。但我试图通过使 tfile 成为命名管道system('mkfifo', tfile)、设置 wait=FALSE,然后运行 fread(tfile) 来查看是否可以避免额外的读/写周期。然而, fread 抱怨管道是一个空文件:
system(paste("tail -q -n+2", tfile2, paste(files, collapse=" "),
" | sed 's/\\.//' >>", tfile), wait=FALSE)
move <- fread(tfile)
Error in fread(tfile) : File is empty: /tmp/RtmpbxNI1L/file78a678dc1999
无论如何,这有点小题大做。
如果我有我的愿望清单的简化代码
理想情况下,我可以这样做:
setClass("Int_Price")
setAs("character", "Int_Price",
function (from) {
return(as.integer(gsub("\\.", "", from)))
}
)
dt <- fread(files, colClasses=list(price="Int_Price"))
然后我会得到一个很好的长 data.table 与正确强制数据。
【问题讨论】:
-
太棒了!感谢您花时间写下这些要点。如果您可以将它们提交到data.table project page,那将会更有帮助。向下滚动以获取指向 bugs 和 feature requests 的链接。在 bugs 上,除非我们有一个可重现的示例,否则很难对此做任何事情。由于违反 SO 政策,这些许多问题都不太可能得到回答(甚至关闭)。
-
您应该将这些作为单独的功能请求 (FR)/错误提交,即使它们在您看来是集体的。
标签: r append data.table fread