2012-09-12 6 views
6

Leggendo in giro, ho scoperto che il modo migliore per leggere un file csv più grande della memoria è usare read.csv.sql dal pacchetto sqldf. Questa funzione leggerà i dati direttamente in un database SQLite e, di conseguenza, eseguirà un'istruzione SQL.La lettura di file csv enormi in R con sqldf funziona ma il file sqlite occupa il doppio dello spazio necessario e necessita di "passare l'aspirapolvere"

Ho notato quanto segue: sembra che i dati letti in sqlite siano archiviati in una tabella temporanea, in modo che, per renderlo accessibile per un uso futuro, debba essere richiesto così nell'istruzione sql.

Come esempio, il codice seguente legge alcuni dati di esempio in 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 = ",") 

I dati possono poi essere raggiunti con sqldf("select * from data limit 5", dbname = "sample_db").

Il problema è il seguente: il file sqlite occupa il doppio dello spazio necessario. La mia ipotesi è che contenga i dati due volte: una volta per la lettura temporanea e una volta per la tabella memorizzata. È possibile pulire il database con sqldf("vacuum", dbname = "sample_db"). Questo recupererà lo spazio vuoto, ma richiede molto tempo, specialmente quando il file è grande.

C'è una soluzione migliore a questo che non crea questa duplicazione di dati nel primo tempo?

+3

È probabile che desidera utilizzare RSQLite direttamente per questo come suggerito da un risponditore ma ho aggiornato Esempi 9 e 10 sulla sqldf home page per mostrare come usa le connessioni persistenti di sqldf per fare ciò senza duplicare. Vedi specialmente l'esempio 10c. Si noti inoltre che sqldf accetta un vettore di istruzioni SQL e non distruggerà il database fino a quando non è stata eseguita l'ultima istruzione nel vettore. –

risposta

9

using RSQLite senza passare attraverso 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 = ",") 
Problemi correlati