Utilizzo di R per scaricare file di dati compressi, estrarre e importare dati


122

@EZGraphs su Twitter scrive: "Molti csv online sono compressi. C'è un modo per scaricare, decomprimere l'archivio e caricare i dati in un data.frame usando R? #Rstats"

Ho anche provato a farlo oggi, ma ho finito per scaricare manualmente il file zip.

Ho provato qualcosa del tipo:

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

ma mi sento come se fossi molto lontano. qualche idea?


Ha funzionato? Se è così, perché ti senti ancora molto lontano?
FrustratedWithFormsDesigner

@Frustrated ... No. il codice nella mia domanda non funziona. Vedi le risposte di seguito.
Jeromy Anglim

Risposte:


176

Gli archivi zip sono in realtà più un "filesystem" con metadati di contenuto ecc. Vedere help(unzip)per i dettagli. Quindi, per fare ciò che hai abbozzato sopra, devi

  1. Crea una temp. nome file (ad es. tempfile())
  2. Utilizzare download.file()per recuperare il file nel file temp. file
  3. Utilizzare unz()per estrarre il file di destinazione da temp. file
  4. Rimuovere il file temporaneo tramite unlink()

che nel codice (grazie per l'esempio di base, ma questo è più semplice) assomiglia a

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

I file compressi ( .z) o gzipped ( .gz) o bzip2ed ( .bz2) sono solo i file e quelli che puoi leggere direttamente da una connessione. Quindi chiedi al fornitore di dati di usarlo invece :)


Dirk, ti ​​dispiacerebbe approfondire come estrarre i dati da un .zarchivio? Posso leggere da una connessione URL con readBin(url(x, "rb"), 'raw', 99999999), ma come estrarre i dati contenuti? Il uncompresspacchetto è stato rimosso da CRAN - è possibile nella base R (e in tal caso, è limitato ai sistemi * nix?)? Felice di pubblicare una nuova domanda, se appropriato.
jbaums

3
Vedi help(gzfile)- stavo pensando che il protocollo gzip potrebbe ora decomprimere anche i file .z (vecchi di pietra) ora che il brevetto è scaduto da tempo. Potrebbe non esserlo. Chi usa .z comunque? Gli anni '80 hanno chiamato, vogliono indietro la loro compressione ;-)
Dirk Eddelbuettel

Grazie - Non riesco a farlo funzionare, quindi forse non è supportato dopo tutto. L'Australian Bureau of Meteorology fornisce alcuni dei loro dati come .z, purtroppo!
jbaums

Cordiali saluti, non funziona con readRDS()(almeno per me). Da quello che posso dire, il file deve essere in una specie di file con cui puoi leggere read.table().
jessi

1
vorrai anche chiudere la connessione. R può avere solo 125 aperti contemporaneamente. Qualcosa come con <- unz (temp, "a1.dat"); data <- read.table (con); chiudi (con);
pdb

28

Per la cronaca, ho provato a tradurre la risposta di Dirk in codice :-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)

5
Non usare scan(); puoi usare read.table()et al direttamente su una connessione. Vedi la mia risposta modificata,
Dirk Eddelbuettel


9

Per Mac (e presumo Linux) ...

Se l'archivio zip contiene un singolo file, puoi usare il comando bash funzip, in combinazione con freaddal data.tablepacchetto:

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

Nei casi in cui l'archivio contiene più file, è possibile utilizzare tarinvece per estrarre un file specifico su stdout:

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

quando ho provato la tua soluzione per più file, ricevo un errore cheFile is empty:
bshelt141

9

Ecco un esempio che funziona per i file che non possono essere letti con la read.tablefunzione. Questo esempio legge un file .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

Per farlo usando data.table, ho scoperto che quanto segue funziona. Sfortunatamente, il collegamento non funziona più, quindi ho utilizzato un collegamento per un altro set di dati.

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)

So che è possibile in una singola riga poiché puoi passare gli script bash a fread, ma non sono sicuro di come scaricare un file .zip, estrarre e passare un singolo file da quello a fread.


4

Prova questo codice. Per me funziona:

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

Esempio:

unzip(zipfile="./data/Data.zip",exdir="./data")
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.