我有一个4 Gb csv文件要加载到我的16Gb机器中,fread
和read.csv
无法一次加载它们,它们会返回内存错误。
所以我决定用块读取文件,它工作(大约一个小时后),如果我信任{{1}中的环境选项卡,我会得到一个{G}的列表,需要2.5 Gb保存为RDS时,和1.2 Gb。
我现在遇到的问题是将所有内容连接成一个大的data.frames
。从我的理解RStudio
是最有效的解决方案(或者它是data.frame
?),但在我的情况下它仍然使用太多的内存。
我想我可以通过rbindlist
对列表项bind_rows
使用rbindlist
来解决这个问题,然后递归到我的最终列表时。这个n
号码必须手动校准,而且这个过程非常难看(除了烦人的csv输入之外)。
我想到的另一个想法是找到一种方法从我加载的数据中提供SQLite数据库,然后从R查询它(我只会n
,n
和{{ 1}}对数据的操作。)
我能做得比这更好吗?
我的数据仅由subset
和min
组成,如果它有所不同。
答案 0 :(得分:2)
听起来像bigmemory
可能只有足够的功能来解决您的问题
require(bigmemory)
您可以使用
以big.matrix
的形式阅读文件
read.big.matrix(filename, sep = ",", header = FALSE, col.names = NULL,
row.names = NULL, has.row.names = FALSE, ignore.row.names = FALSE,
type = NA, skip = 0, separated = FALSE, backingfile = NULL,
backingpath = NULL, descriptorfile = NULL, binarydescriptor = FALSE,
extraCols = NULL, shared = TRUE)
即使使用像iris
这样的简单示例,您也可以看到内存节省
x <- as.big.matrix(iris)
options(bigmemory.allow.dimnames=TRUE)
colnames(x) <- c("A", "B", "C", "D", "E")
object.size(x)
# 664 bytes
object.size(iris)
# 7088 bytes
子集big.matrices
有限,但mwhich
子集column 1 is <= 5
,和column 2 <= 4
x[mwhich(x, 1:2, list(c(5), c(4)), list(c('le'), c('le')), 'AND'),]
# A B C D E
# 2 4.9 3.0 1.4 0.2 1
# 3 4.7 3.2 1.3 0.2 1
# 4 4.6 3.1 1.5 0.2 1
# 5 5.0 3.6 1.4 0.2 1
# etc
注意子集操作的结果是常规矩阵。您可以使用as.big.matrix()
biganalytics
为big.matrices
require(biganalytics)
colmin(x, cols = 1:2, na.rm = FALSE)
# A B
# 4.3 2.0
colmax(x, cols = 1:2, na.rm = FALSE)
# A B
# 7.9 4.4
最后,您可以使用
输出big.matrix
write.big.matrix(...)
答案 1 :(得分:0)
在评论中提示后,我最终检查了这个solution,虽然我最终可能会最终接受@ CPak的解决方案(我会及时编辑这篇文章的最终信息)。
对于我的具体情况,我这样使用它,首先创建数据库并用我的表格提供它:
library(RSQLite)
library(dplyr)
# define dbpath (ending with ".SQLite" to be clean), my_table_name, csv_path
db <- dbConnect(SQLite(), dbname = dbpath) # will create databse if it doesn't exist, and a connection
dbWriteTable(conn=db, name=my_table_name, value=csv_path, row.names=FALSE, header=TRUE) # creates table in DB
dbDisconnect(db)
然后访问它:
db <- dbConnect(SQLite(), dbname= dbpath) # creates a connection to db
my_table <- tbl(db, my_table_name)
然后my_table的行为非常像data.frame
,我认为有一些限制,但对于基本操作,它可以正常工作。
创建的数据库与csv
源的大小大致相同,因此或多或少是RDS
文件的4倍,但是具有很大的优势,不需要加载它在记忆中。
编辑:可能值得调查readr::read_csv_chunked
和chunked::read_csv_chunkwise