Verwenden von R zum Herunterladen von komprimierten Datendateien, Extrahieren und Importieren von Daten

122

@EZGraphs auf Twitter schreibt: "Viele Online-CSVs werden komprimiert. Gibt es eine Möglichkeit, das Archiv mit R? #Rstats herunterzuladen, zu entpacken und die Daten in einen data.frame zu laden?"

Ich habe heute auch versucht, dies zu tun, aber am Ende habe ich die Zip-Datei nur manuell heruntergeladen.

Ich habe so etwas versucht wie:

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

aber ich fühle mich, als wäre ich weit weg. Irgendwelche Gedanken?

Jeromy Anglim
quelle
Hat es funktioniert? Wenn ja, warum würden Sie immer noch das Gefühl haben, weit weg zu sein?
FrustratedWithFormsDesigner
@Frustrated ... Nein. Der Code in meiner Frage funktioniert nicht. Siehe Antworten unten.
Jeromy Anglim

Antworten:

176

Zip-Archive sind eigentlich eher ein "Dateisystem" mit Inhaltsmetadaten usw. Siehe help(unzip)für Details. Um das zu tun, was Sie oben skizzieren, müssen Sie

  1. Erstellen Sie eine temporäre. Dateiname (zB tempfile())
  2. Verwenden Sie download.file()diese Option, um die Datei in die temporäre Datei abzurufen. Datei
  3. Verwenden Sie unz()diese Option, um die Zieldatei aus temp zu extrahieren. Datei
  4. Entfernen Sie die temporäre Datei über unlink()

was im Code aussieht (danke für das einfache Beispiel, aber das ist einfacher)

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

Komprimierte ( .z) oder gzipped ( .gz) oder bzip2ed ( .bz2) Dateien sind nur die Dateien und diejenigen, die Sie direkt von einer Verbindung lesen können. Lassen Sie den Datenanbieter das stattdessen verwenden :)

Dirk Eddelbuettel
quelle
Dirk, würde es Ihnen etwas ausmachen, das Extrahieren von Daten aus einem .zArchiv zu erweitern? Ich kann aus einer URL-Verbindung mit lesen readBin(url(x, "rb"), 'raw', 99999999), aber wie würde ich die enthaltenen Daten extrahieren? Das uncompressPaket wurde aus CRAN entfernt - ist dies in Base R möglich (und wenn ja, ist es auf * nix-Systeme beschränkt?)? Gerne als neue Frage gegebenenfalls posten.
Jbaums
3
Siehe help(gzfile)- Ich dachte, dass das gzip-Protokoll jetzt, da das Patent längst abgelaufen ist, möglicherweise auch (Stein alte) .z-Dateien dekomprimiert. Es darf nicht. Wer benutzt überhaupt .z? Die 1980er riefen an, sie wollen ihre Kompression zurück ;-)
Dirk Eddelbuettel
Danke - ich kann es nicht zum Laufen bringen, also wird es vielleicht doch nicht unterstützt. Das Australian Bureau of Meteorology stellt leider einige ihrer Daten als .z zur Verfügung!
Jbaums
Zu Ihrer Information Es funktioniert nicht mit readRDS()(zumindest für mich). Soweit ich das beurteilen kann, muss sich die Datei in einer Art Datei befinden, mit der Sie lesen können read.table().
Jessi
1
Sie möchten auch die Verbindung schließen. R kann nur 125 gleichzeitig geöffnet haben. So etwas wie con <- unz (temp, "a1.dat"); Daten <- read.table (con); schließen (con);
pdb
28

Nur zur Veranschaulichung, ich habe versucht, Dirks Antwort in Code zu übersetzen :-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)
George Dontas
quelle
5
Nicht benutzen scan(); Sie können read.table()et al direkt auf einer Verbindung verwenden. Siehe meine bearbeitete Antwort,
Dirk Eddelbuettel
17

Ich habe das CRAN-Paket "downloader" verwendet, das unter http://cran.r-project.org/web/packages/downloader/index.html zu finden ist . Viel einfacher.

download(url, dest="dataset.zip", mode="wb") 
unzip ("dataset.zip", exdir = "./")
Unixcreeper
quelle
2
Ich benutze nur utils :: entpacke keine Notwendigkeit für das Downlaoder-Paket für mich
mtelesha
ab 2019 - ich musste exdir = 'sagen.'
userJT
9

Für Mac (und ich nehme Linux an) ...

Wenn das Zip-Archiv eine einzelne Datei enthält, können Sie den Befehl bash funzipin Verbindung mit freaddem data.tablePaket verwenden:

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

In Fällen, in denen das Archiv mehrere Dateien enthält, können Sie tarstattdessen eine bestimmte Datei in stdout extrahieren:

dt <- fread("curl http://www.newcl.org/data/zipfiles/a1.zip | tar -xf- --to-stdout *a1.dat")
dnlbrky
quelle
Als ich Ihre Lösung für mehrere Dateien ausprobiert habe, wird eine Fehlermeldung angezeigt File is empty:
erhalte
9

Hier ist ein Beispiel, das für Dateien read.tablefunktioniert, die mit der Funktion nicht eingelesen werden können. In diesem Beispiel wird eine XLS-Datei gelesen.

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))
ColinTea
quelle
5

Um dies mit data.table zu tun, stellte ich fest, dass das Folgende funktioniert. Leider funktioniert der Link nicht mehr, daher habe ich einen Link für einen anderen Datensatz verwendet.

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)

Ich weiß, dass dies in einer einzigen Zeile möglich ist, da Sie Bash-Skripte an übergeben können fread, aber ich bin nicht sicher, wie ich eine ZIP-Datei herunterladen, extrahieren und eine einzelne Datei von dieser an übergeben soll fread.

Mallick Hossain
quelle
4

Versuchen Sie diesen Code. Für mich geht das:

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

Beispiel:

unzip(zipfile="./data/Data.zip",exdir="./data")
Marcelo Tibau
quelle