2012-09-12 1 views
6

Чтение, я узнал, что лучший способ читать файл csv размером более чем с памятью - использовать read.csv.sql из пакета sqldf. Эта функция будет считывать данные непосредственно в базе данных sqlite и, следовательно, выполнять оператор sql.Чтение огромных CSV-файлов в R с sqldf-работами, но sqlite-файл занимает в два раза больше места, которое ему нужно, и нуждается в «вакуумировании»

Я заметил следующее: кажется, что данные, считываемые в sqlite, хранятся во временной таблице, поэтому, чтобы сделать ее доступной для будущего использования, ее необходимо задать так в инструкции sql.

В качестве примера, следующий код читает некоторые образцы данных в SQLite:

# generate sample data 
sample_data <- data.frame(col1 = sample(letters, 100000, TRUE), col2 = rnorm(100000)) 
# save as csv 
write.csv(sample_data, "sample_data.csv", row.names = FALSE) 
# create a sample sqlite database 
library(sqldf) 
sqldf("attach sample_db as new") 
# read the csv into the database and create a table with its content 
read.csv.sql("sample_data.csv", sql = "create table data as select * from file", 
      dbname = "sample_db", header = T, row.names = F, sep = ",") 

Затем данные могут быть доступны с sqldf("select * from data limit 5", dbname = "sample_db").

Проблема заключается в следующем: файл sqlite занимает в два раза больше места, чем должен. Я предполагаю, что он содержит данные дважды: один раз для временного чтения и один раз для хранимой таблицы. Можно очистить базу данных с помощью sqldf("vacuum", dbname = "sample_db"). Это позволит вернуть пустое пространство, но это занимает много времени, особенно когда файл большой.

Есть ли лучшее решение для этого, которое не создает это дублирование данных в первый раз?

+3

Скорее всего, вы хотите использовать RSQLite непосредственно для этого, как было предложено ответчиком, но я обновил примеры 9 и 10 на sqldf главной страницы, чтобы показать, как используйте постоянные соединения sqldf для выполнения этого без дублирования. См. Особенно пример 10c. Также обратите внимание, что sqldf принимает вектор операторов sql и не будет уничтожать базу данных до тех пор, пока не будет выполнен последний оператор в векторе. –

ответ

9

Решение: используя RSQLite без прохождения через sqldf:

library(RSQLite) 
con <- dbConnect("SQLite", dbname = "sample_db") 
# read csv file into sql database 
dbWriteTable(con, name="sample_data", value="sample_data.csv", 
      row.names=FALSE, header=TRUE, sep = ",")