Bri*_*n D 8 memory csv r sqldf data.table
对此的简单回答是"购买更多内存",但我希望得到更具建设性的答案,并在此过程中学到一些东西.
我运行Windows 7 64位,内存为8GB.
我有几个非常大的.csv.gz文件(大约450MB未压缩),它们具有我读入R并执行一些处理的完全相同的标题信息.然后,我需要将处理过的R对象组合成一个主对象,并在磁盘上写回.csv.
我在多组文件上执行相同的操作.例如,我有5个文件夹,每个文件夹中包含6个csv.gz文件.我需要最终得到5个主文件,每个文件夹一个.
我的代码如下所示:
for( loop through folders ){
master.file = data.table()
for ( loop through files ) {
filename = list.files( ... )
file = as.data.table ( read.csv( gzfile( filename ), stringsAsFactors = F ))
gc()
...do some processing to file...
# append file to the running master.file
if ( nrow(master.file) == 0 ) {
master.file = file
} else {
master.file = rbindlist( list( master.file, file) )
}
rm( file, filename )
gc()
}
write.csv( master.file, unique master filename, row.names = FALSE )
rm( master.file )
gc()
}
Run Code Online (Sandbox Code Playgroud)
此代码不起作用.我cannot allocate memory在写出最终的csv之前得到了错误.我在运行此代码时正在观察资源监视器,并且不明白为什么要使用8GB的RAM来执行此处理.所有文件大小的总和大约是2.7GB,所以我期望R将使用的最大内存为2.7GB.但write.csv操作似乎使用与您正在编写的数据对象相同的内存量,因此如果您在内存中有一个2.7GB的对象并尝试将其写出来,那么您将使用5.6 GB的内存.
这个明显的现实,加上使用一个for循环,其中内存似乎没有得到充分释放似乎是问题.
我怀疑我可以使用这里和这里sqldf提到的包但是当我将语句设置为等于R变量时,我最终得到了相同的内存不足错误.sqldf
2013年12月23日更新 - 以下解决方案可在R中运行而不会耗尽内存(感谢@AnandaMahto).
这种方法的主要警告是,您必须绝对确保每次读入和写出的文件具有完全相同的标题列,或者R处理代码必须确保这一点,因为write.table确实如此不要为你检查.
for( loop through folders ){
for ( loop through files ) {
filename = list.files( ... )
file = as.data.table ( read.csv( gzfile( filename ), stringsAsFactors = F ))
gc()
...do some processing to file...
# append file to the running master.file
if ( first time through inner loop) {
write.table(file,
"masterfile.csv",
sep = ",",
dec = ".",
qmethod = "double",
row.names = "FALSE")
} else {
write.table(file,
"masterfile.csv",
sep = ",",
dec = ".",
qmethod = "double",
row.names = "FALSE",
append = "TRUE",
col.names = "FALSE")
}
rm( file, filename )
gc()
}
gc()
}
Run Code Online (Sandbox Code Playgroud)
我的初步解决方案
for( loop through folders ){
for ( loop through files ) {
filename = list.files( ... )
file = as.data.table ( read.csv( gzfile( filename ), stringsAsFactors = F ))
gc()
...do some processing to file...
#write out the file
write.csv( file, ... )
rm( file, filename )
gc()
}
gc()
}
Run Code Online (Sandbox Code Playgroud)
然后我下载并安装了GnuWin32的sed软件包,并使用Windows命令行工具附加文件,如下所示:
copy /b *common_pattern*.csv master_file.csv
Run Code Online (Sandbox Code Playgroud)
这会将名称中包含文本模式"common_pattern"的所有单个.csv文件,标题和所有文件一起附加在一起.
然后我使用sed.exe删除除第一个标题行以外的所有标题行,如下所示:
"c:\Program Files (x86)\GnuWin32\bin\sed.exe" -i 2,${/header_pattern/d;} master_file.csv
Run Code Online (Sandbox Code Playgroud)
-i告诉sed只是覆盖指定的文件(就地).
2,$告诉sed查看从第2行到最后一行的范围($)
{/header_pattern/d;}告诉sed查找范围内的所有行,其中包含文本"header_pattern"并d删除这些行为了
确保这样做我想要它要做的,我先打印出我打算删除的行.
"c:\Program Files (x86)\GnuWin32\bin\sed.exe" -n 2,${/header_pattern/p;} master_file.csv
Run Code Online (Sandbox Code Playgroud)
像魅力一样,我只是希望我能在R中做到这一切.
| 归档时间: |
|
| 查看次数: |
1282 次 |
| 最近记录: |