2012-03-03 15 views
14

Sto cercando di scaricare un czv con gzip e caricarlo come oggetto R senza salvarlo prima sul disco. Posso farlo con i file compressi ma non riesco a farlo funzionare con gzfile o gzcon.Leggi gzip csv direttamente da un URL in R

Esempio:

grabRemote <- function() { 
     temp <- tempfile() 
     download.file("http://dumps.wikimedia.org/other/articlefeedback/aa_combined-20110321.csv.gz", temp) 
     aap.file <- read.csv(gzfile(temp), as.is = TRUE) 
     unlink(temp) 
     return(aap.file) 
    } 

che scarica un (piccolo) gz file compresso contenente Wikipedia article feedback data (non è importante, ma solo per indicare che non è gigante o nefasto).

Il codice che ho funziona bene ma sento che mi manca qualcosa di molto ovvio ricorrendo alla creazione e alla distruzione di un file temporaneo.

risposta

16

Sono quasi certo di aver risposto a questa domanda una volta. Il risultato è che Connessioni API di R (file(), url(), pipe(), ...) possono eseguire la decompressione al volo, non penso che sia possibile farlo per gli oggetti http remoti.

Quindi, fare il doppio passaggio descritto: utilizzare download.file() con un risultato tempfile() come secondo argomento per recuperare il file compresso, quindi leggerlo da esso. Come oggetto tempfile(), verrà ripulito automaticamente alla fine della sessione R in modo che la piccola correzione che posso suggerire è saltare il unlink() (ma poi mi piacciono le pulizie esplicite, quindi puoi anche tenerlo).

Edit: capito:

con <- gzcon(url(paste("http://dumps.wikimedia.org/other/articlefeedback/", 
         "aa_combined-20110321.csv.gz", sep=""))) 
txt <- readLines(con) 
dat <- read.csv(textConnection(txt)) 

dim(dat) 
# [1] 1490 19 

summary(dat[,1:3]) 
# aa_page_id  page_namespace     page_title 
# Min. :  324 Min. :0  United_States  : 79 
# 1st Qu.: 88568 1st Qu.:0  2011_NBA_Playoffs : 52 
# Median : 2445733 Median :0  IPad_2    : 43 
# Mean : 8279600 Mean :0  IPod_Touch   : 38 
# 3rd Qu.:16179920 3rd Qu.:0  True_Grit_(2010_film): 38 
# Max. :31230028 Max. :0  IPhone_4    : 26 
# (Other)    :1214 

La chiave è stato il suggerimento del gzcon aiuto che si può mettere la decompressione attorno uno stream esistente. Abbiamo quindi bisogno della leggera deviazione di readLines e la lettura tramite textConnection da quello come read.csv vuole andare avanti e indietro nei dati (per convalidare la larghezza della colonna, presumo).

+0

Sì, sono quasi sicuro al 70% che tu o JD abbiate risposto a qualcosa di simile. Ho effettivamente ottenuto l'idea di 'tempfile' da una tua precedente risposta relativa alle cartelle compresse. Ma non riesco a trovare qualcosa w/gzfile/gzcon, che sembrano comportarsi in modo diverso da alcune delle altre funzioni relative ai file o alle connessioni. –

+0

Puoi distillarlo? In realtà ho usato lo stesso trucco dello 'streaming' da un file gzip'to nei primi anni '90, quando lo spazio su disco era scarso e ho mantenuto i risultati della simulazione gzip'ed. Quindi la capacità di ottenere in modo trasparente la funzionalità "gunzip" in una libreria C è piuttosto vecchia e standard. –

+0

Segnalo come risposta per ora. Potrei tornare indietro e darmi una risposta migliore dopo qualche scherzo in giro con w/gzcon (che sembra l'angolo più promettente). –