2012-03-03 15 views
14

Estoy buscando descargar un gzip csv y cargarlo como un objeto R sin guardarlo primero en el disco. Puedo hacer esto con archivos comprimidos pero parece que no funciona con gzfile o gzcon.Leer gzipped csv directamente desde una url en R

Ejemplo:

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) 
    } 

que descarga un archivo (pequeño) gz comprimido que contiene Wikipedia article feedback data (no es importante, pero sólo para indicar que no es gigante o nefasto).

El código que tengo funciona bien pero siento que me falta algo muy obvio al recurrir a la creación y destrucción de un archivo temporal.

Respuesta

16

Estoy casi seguro de haber respondido esta pregunta una vez. El resultado es que Conexiones API de R (file(), url(), pipe(), ...) pueden hacer descompresión sobre la marcha, no creo que puedas hacerlo para objetos http remotos.

Así que haga los dos pasos que ha descrito: use download.file() con un resultado tempfile() como segundo argumento para recuperar el archivo comprimido, y luego lea de él. Como objeto tempfile(), se limpiará automáticamente al final de su sesión R, por lo que la única solución menor que puedo sugerir es omitir el unlink() (pero me gustan las limpiezas explícitas, por lo que es mejor que lo guarde).

Editar: ¡Gracias:

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 clave fue la sugerencia del gzcon ayuda que se puede poner alrededor de la descompresión un flujo existente. Entonces necesitamos un ligero desvío de readLines y leer a través de textConnection, ya que read.csv quiere ir y venir en los datos (para validar el ancho de la columna, supongo).

+0

Sí, estoy casi 70% seguro de que usted o JD han respondido algo similar. De hecho, obtuve la idea 'tempfile' de una respuesta anterior suya con respecto a las carpetas comprimidas. Pero no puedo encontrar algo con/gzfile/gzcon, que parecen comportarse de manera diferente a otras funciones relacionadas con el archivo o la conexión. –

+0

¿Puedes destilar esto? De hecho, utilicé el mismo truco de "transmisión" de un archivo comprimido gzip a principios de la década de 1990 cuando el espacio en el disco era más escaso y mantuve gzip'ed los resultados de la simulación. Por lo tanto, la capacidad de obtener de forma transparente la funcionalidad "gunzip" en una biblioteca C fread es bastante antigua y estándar. –

+0

Voy a marcar esto como la respuesta por ahora. Podría volver y darme una mejor respuesta después de perder el tiempo con w/gzcon (que parece ser el ángulo más prometedor). –

Cuestiones relacionadas