Usando R para descargar archivos de datos comprimidos, extraer e importar datos


122

@EZGraphs en Twitter escribe: "Muchos csvs en línea están comprimidos. ¿Hay alguna manera de descargar, descomprimir el archivo y cargar los datos en un data.frame usando R? #Rstats"

También estaba tratando de hacer esto hoy, pero terminé descargando el archivo zip manualmente.

Intenté algo como:

fileName <- "http://www.newcl.org/data/zipfiles/a1.zip"
con1 <- unz(fileName, filename="a1.dat", open = "r")

pero siento que estoy muy lejos. ¿Alguna idea?


¿Funcionó? Si es así, ¿por qué aún sentirías que estás muy lejos?
FrustratedWithFormsDesigner

@ Frustrado ... No. El código en mi pregunta no funciona. Ver las respuestas a continuación.
Jeromy Anglim

Respuestas:


176

Los archivos zip son en realidad más un 'sistema de archivos' con metadatos de contenido, etc. Consulte help(unzip)para más detalles. Entonces, para hacer lo que bosquejas arriba necesitas

  1. Crea una temperatura. nombre de archivo (por ejemplo tempfile())
  2. Use download.file()para buscar el archivo en la temperatura. expediente
  3. Use unz()para extraer el archivo de destino de temp. expediente
  4. Eliminar el archivo temporal a través de unlink()

que en el código (gracias por el ejemplo básico, pero esto es más simple) parece

temp <- tempfile()
download.file("http://www.newcl.org/data/zipfiles/a1.zip",temp)
data <- read.table(unz(temp, "a1.dat"))
unlink(temp)

Los archivos comprimidos ( .z) o gzipped ( .gz) o bzip2ed ( .bz2) son solo el archivo y los que puede leer directamente desde una conexión. Así que haga que el proveedor de datos lo use en su lugar :)


Dirk, ¿te importaría ampliar cómo extraer datos de un .zarchivo? Puedo leer desde una conexión URL con readBin(url(x, "rb"), 'raw', 99999999), pero ¿cómo extraería los datos contenidos? El uncompresspaquete se ha eliminado de CRAN. ¿Es esto posible en la base R (y si es así, ¿está restringido a los sistemas * nix?)? Feliz de publicar como una nueva pregunta, si corresponde.
jbaums

3
Mira help(gzfile), estaba pensando que el protocolo gzip ahora también puede descomprimir (viejos) archivos .z ahora que la patente ha expirado hace mucho tiempo. Puede que no. ¿Quién usa .z de todos modos? Los años 80 llamaron, quieren recuperar su compresión ;-)
Dirk Eddelbuettel

Gracias, no puedo hacer que funcione, así que tal vez no sea compatible después de todo. ¡La Oficina Australiana de Meteorología proporciona algunos de sus datos como .z, por desgracia!
jbaums

FYI No funciona con readRDS()(al menos para mí). Por lo que puedo decir, el archivo debe estar en un tipo de archivo con el que pueda leer read.table().
jessi

1
También querrás cerrar la conexión. R solo puede tener 125 abiertos a la vez. Algo así como con <- unz (temp, "a1.dat"); datos <- read.table (con); cerrar (con);
pdb

28

Solo para que conste, intenté traducir la respuesta de Dirk al código :-P

temp <- tempfile()
download.file("http://www.newcl.org/data/zipfiles/a1.zip",temp)
con <- unz(temp, "a1.dat")
data <- matrix(scan(con),ncol=4,byrow=TRUE)
unlink(temp)

55
No utilizar scan(); puede usar read.table()et al directamente en una conexión. Vea mi respuesta editada,
Dirk Eddelbuettel


9

Para Mac (y supongo que Linux) ...

Si el archivo zip contiene un solo archivo, puede usar el comando bash funzip, junto con freadel del data.tablepaquete:

library(data.table)
dt <- fread("curl http://www.newcl.org/data/zipfiles/a1.zip | funzip")

En los casos en que el archivo contiene varios archivos, puede usar taren su lugar para extraer un archivo específico para stdout:

dt <- fread("curl http://www.newcl.org/data/zipfiles/a1.zip | tar -xf- --to-stdout *a1.dat")

cuando probé su solución para varios archivos, recibo un error queFile is empty:
bshelt141

9

Aquí hay un ejemplo que funciona para archivos que no se pueden leer con la read.tablefunción. Este ejemplo lee un archivo .xls.

url <-"https://www1.toronto.ca/City_Of_Toronto/Information_Technology/Open_Data/Data_Sets/Assets/Files/fire_stns.zip"

temp <- tempfile()
temp2 <- tempfile()

download.file(url, temp)
unzip(zipfile = temp, exdir = temp2)
data <- read_xls(file.path(temp2, "fire station x_y.xls"))

unlink(c(temp, temp2))

5

Para hacer esto usando data.table, descubrí que lo siguiente funciona. Desafortunadamente, el enlace ya no funciona, así que usé un enlace para otro conjunto de datos.

library(data.table)
temp <- tempfile()
download.file("https://www.bls.gov/tus/special.requests/atusact_0315.zip", temp)
timeUse <- fread(unzip(temp, files = "atusact_0315.dat"))
rm(temp)

Sé que esto es posible en una sola línea, ya que puede pasar scripts de bash a fread, pero no estoy seguro de cómo descargar un archivo .zip, extraer y pasar un solo archivo desde allí fread.


4

Prueba este código. Esto funciona para mi:

unzip(zipfile="<directory and filename>",
      exdir="<directory where the content will be extracted>")

Ejemplo:

unzip(zipfile="./data/Data.zip",exdir="./data")
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.