Usando R para fazer download de arquivos de dados compactados, extrair e importar dados

122

A @EZGraphs no Twitter escreve: "Muitos csvs online são compactados. Existe uma maneira de baixar, descompactar o arquivo morto e carregar os dados em um data.frame usando R? #Rstats"

Eu também estava tentando fazer isso hoje, mas acabei baixando o arquivo zip manualmente.

Eu tentei algo como:

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

mas sinto como se estivesse longe. Alguma ideia?

Jeromy Anglim
fonte
Funcionou? Se sim, por que você ainda acha que está longe?
FrustratedWithFormsDesigner
@Frustrated ... Não. o código na minha pergunta não funciona. Veja as respostas abaixo.
Jeromy Anglim

Respostas:

176

Na verdade, os arquivos zip são mais um 'sistema de arquivos' com metadados de conteúdo, etc. Veja help(unzip)para detalhes. Então, para fazer o que você esboçou acima, você precisa

  1. Crie uma temperatura. nome do arquivo (por exemplo tempfile())
  2. Use download.file()para buscar o arquivo na temperatura Arquivo
  3. Use unz()para extrair o arquivo de destino de temp. Arquivo
  4. Remova o arquivo temporário via unlink()

que no código (obrigado pelo exemplo básico, mas isso é mais simples) parece

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

Compactados ( .z) ou gzipped ( .gz) ou bzip2ed ( .bz2arquivos) são apenas o arquivo e aqueles que você pode ler diretamente a partir de uma conexão. Portanto, faça com que o provedor de dados use isso em vez disso :)

Dirk Eddelbuettel
fonte
Dirk, você se importaria em expandir como extrair dados de um .zarquivo? Posso ler a partir de uma conexão de URL readBin(url(x, "rb"), 'raw', 99999999), mas como extrair os dados contidos? O uncompresspacote foi removido do CRAN - isso é possível na base R (e, nesse caso, é restrito aos sistemas * nix?)? É um prazer postar como uma nova pergunta, se apropriado.
jbaums
3
Veja help(gzfile)- eu estava pensando que o protocolo gzip agora pode descompactar arquivos .z (agora antigos) também agora que a patente expirou. Não pode. Quem usa .z de qualquer maneira? A década de 1980 chamadas, eles querem a sua volta compressão ;-)
Dirk Eddelbuettel
Obrigado - não consigo fazê-lo funcionar, por isso talvez não seja suportado, afinal. O Australian Bureau of Meteorology fornece alguns de seus dados como .z, infelizmente!
jbaums
FYI Não funciona com readRDS()(pelo menos para mim). Pelo que sei, o arquivo precisa estar em um tipo de arquivo com o qual você possa ler read.table().
jessi
1
você também vai querer fechar a conexão. R só pode ter 125 abertos de uma vez. Algo como con <- unz (temp, "a1.dat"); data <- read.table (con); fechar (contra);
Pdb
28

Só para constar, tentei traduzir a resposta de Dirk no 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)
George Dontas
fonte
5
Não use scan(); você pode usar read.table()et al diretamente em uma conexão. Veja minha resposta editada,
Dirk Eddelbuettel
17

Eu usei o pacote CRAN "downloader" encontrado em http://cran.r-project.org/web/packages/downloader/index.html . Muito facil.

download(url, dest="dataset.zip", mode="wb") 
unzip ("dataset.zip", exdir = "./")
unixcreeper
fonte
2
Eu só uso utils :: unzip nenhuma necessidade para o pacote downlaoder para mim
mtelesha
a partir de 2019 - eu tinha que dizer exdir = '.'
userJT
9

Para Mac (e eu assumo Linux) ...

Se o arquivo zip contiver um único arquivo, você poderá usar o comando bash funzip, em conjunto com freado data.tablepacote:

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

Nos casos em que o archive contém vários arquivos, você pode usar tarpara extrair um arquivo específico para o stdout:

dt <- fread("curl http://www.newcl.org/data/zipfiles/a1.zip | tar -xf- --to-stdout *a1.dat")
dnlbrky
fonte
quando eu tentei sua solução para vários arquivos, eu estou recebendo um erro queFile is empty:
bshelt141
9

Aqui está um exemplo que funciona para arquivos que não podem ser lidos com a read.tablefunção Este exemplo lê um arquivo .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
fonte
5

Para fazer isso usando data.table, descobri que o seguinte funciona. Infelizmente, o link não funciona mais, então usei um link para outro conjunto de dados.

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)

Eu sei que isso é possível em uma única linha, pois você pode passar scripts bash para fread, mas não sei como baixar um arquivo .zip, extrair e passar um único arquivo disso para fread.

Mallick Hossain
fonte
4

Experimente este código. Funciona para mim:

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

Exemplo:

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