Utilisation de R pour télécharger un fichier de données compressé, extraire et importer des données

122

@EZGraphs sur Twitter écrit: "De nombreux csv en ligne sont compressés. Y a-t-il un moyen de télécharger, décompresser l'archive et charger les données dans un data.frame en utilisant R? #Rstats"

J'essayais également de le faire aujourd'hui, mais j'ai fini par télécharger le fichier zip manuellement.

J'ai essayé quelque chose comme:

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

mais j'ai l'impression d'être loin. Des pensées?

Jeromy Anglim
la source
Cela a-t-il fonctionné? Si oui, pourquoi ressentiriez-vous encore que vous êtes loin?
FrustratedWithFormsDesigner
@Frustré ... Non. le code dans ma question ne fonctionne pas. Voir les réponses ci-dessous.
Jeromy Anglim

Réponses:

176

Les archives Zip sont en fait plus un «système de fichiers» avec des métadonnées de contenu, etc. Voir help(unzip)pour plus de détails. Donc, pour faire ce que vous esquissez ci-dessus, vous devez

  1. Créez un temp. nom de fichier (par exemple tempfile())
  2. Utilisez download.file()pour récupérer le fichier dans le fichier temp. fichier
  3. Utilisez unz()pour extraire le fichier cible de temp. fichier
  4. Supprimez le fichier temporaire via unlink()

qui dans le code (merci pour l'exemple de base, mais c'est plus simple) ressemble à

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

Les fichiers compressés ( .z) ou gzippés ( .gz) ou bzip2ed ( .bz2) ne sont que le fichier et ceux que vous pouvez lire directement à partir d'une connexion. Alors demandez au fournisseur de données de l'utiliser à la place :)

Dirk Eddelbuettel
la source
Dirk, cela vous dérangerait-il d'expliquer comment extraire des données d'une .zarchive? Je peux lire à partir d'une connexion URL avec readBin(url(x, "rb"), 'raw', 99999999), mais comment extraire les données contenues? Le uncompresspaquet a été supprimé de CRAN - est-ce possible dans la base R (et si oui, est-il limité aux systèmes * nix?)? Heureux de publier une nouvelle question le cas échéant.
jbaums
3
Voir help(gzfile)- Je pensais que le protocole gzip peut maintenant décompresser les fichiers .z (vieux de pierre) aussi maintenant que le brevet a expiré depuis longtemps. Ce n'est peut-être pas le cas. Qui utilise .z de toute façon? Les années 1980 ont appelé, ils veulent leur compression ;-)
Dirk Eddelbuettel
Merci - Je ne peux pas le faire fonctionner, alors peut-être que ce n'est pas pris en charge après tout. Le Bureau australien de météorologie fournit certaines de ses données en .z, malheureusement!
jbaums
FYI Cela ne fonctionne pas avec readRDS()(du moins pour moi). D'après ce que je peux dire, le fichier doit être dans une sorte de fichier que vous pouvez lire read.table().
jessi
1
vous voudrez également fermer la connexion. R ne peut avoir que 125 ouverts à la fois. Quelque chose comme con <- unz (temp, "a1.dat"); données <- read.table (con); fermer (con);
pdb
28

Juste pour mémoire, j'ai essayé de traduire la réponse de Dirk en code :-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
la source
5
N'utilisez pas scan(); vous pouvez utiliser read.table()et al directement sur une connexion. Voir ma réponse modifiée,
Dirk Eddelbuettel
17

J'ai utilisé le package CRAN "downloader" trouvé à http://cran.r-project.org/web/packages/downloader/index.html . Beaucoup plus facile.

download(url, dest="dataset.zip", mode="wb") 
unzip ("dataset.zip", exdir = "./")
unixcreeper
la source
2
J'utilise juste utils :: unzip pas besoin du package de téléchargement pour moi
mtelesha
à partir de 2019 - je devais dire exdir = '.'
userJT
9

Pour Mac (et je suppose Linux) ...

Si l'archive zip contient un seul fichier, vous pouvez utiliser la commande bash funzip, en conjonction avec à freadpartir du data.tablepackage:

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

Dans les cas où l'archive contient plusieurs fichiers, vous pouvez utiliser à la tarplace pour extraire un fichier spécifique vers stdout:

dt <- fread("curl http://www.newcl.org/data/zipfiles/a1.zip | tar -xf- --to-stdout *a1.dat")
dnlbrky
la source
lorsque j'ai essayé votre solution pour plusieurs fichiers, File is empty:
j'obtiens
9

Voici un exemple qui fonctionne pour les fichiers qui ne peuvent pas être lus avec la read.tablefonction. Cet exemple lit un fichier .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))
ColinTea
la source
5

Pour ce faire à l'aide de data.table, j'ai trouvé que ce qui suit fonctionne. Malheureusement, le lien ne fonctionne plus, j'ai donc utilisé un lien pour un autre ensemble de données.

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)

Je sais que cela est possible en une seule ligne car vous pouvez transmettre des scripts bash à fread, mais je ne sais pas comment télécharger un fichier .zip, extraire et transmettre un seul fichier à partir de celui-ci fread.

Mallick Hossain
la source
4

Essayez ce code. Ça marche pour moi:

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

Exemple:

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