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?


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

5
N'utilisez pas scan(); vous pouvez utiliser read.table()et al directement sur une connexion. Voir ma réponse modifiée,
Dirk Eddelbuettel


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

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

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.


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")
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.