Używanie R do pobierania spakowanego pliku danych, wyodrębniania i importowania danych

122

@EZGraphs na Twitterze pisze: „Wiele plików CSV online jest spakowanych. Czy istnieje sposób na pobranie, rozpakowanie archiwum i załadowanie danych do data.frame przy użyciu R? #Rstats”

Próbowałem to zrobić dzisiaj, ale skończyło się na ręcznym pobraniu pliku zip.

Próbowałem czegoś takiego:

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

ale czuję się jakbym był daleko. jakieś pomysły?

Jeromy Anglim
źródło
Zadziałało? Jeśli tak, dlaczego nadal miałbyś czuć, że jesteś daleko?
FrustratedWithFormsDesigner
@Frustrated ... Nie. kod w moim pytaniu nie działa. Zobacz odpowiedzi poniżej.
Jeromy Anglim

Odpowiedzi:

176

Archiwa zip są właściwie bardziej „systemem plików” z metadanymi zawartości itp. Zobacz help(unzip)szczegóły. Aby więc zrobić to, co nakreśliłeś powyżej, musisz

  1. Utwórz temp. nazwa pliku (np. tempfile())
  2. Służy download.file()do pobierania pliku do temp. plik
  3. Służy unz()do wyodrębniania pliku docelowego z temp. plik
  4. Usuń plik tymczasowy za pośrednictwem unlink()

który w kodzie (dzięki za podstawowy przykład, ale to jest prostsze) wygląda jak

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

Skompresowane ( .z) lub skompresowane ( .gz) lub bzip2ed ( .bz2) Pliki są tylko plik i może ci czytać bezpośrednio z połączenia. Więc poproś dostawcę danych, aby użył tego zamiast tego :)

Dirk Eddelbuettel
źródło
Dirk, czy zechciałbyś rozwinąć, jak wyodrębniać dane z .zarchiwum? Mogę czytać z połączenia URL z readBin(url(x, "rb"), 'raw', 99999999), ale jak wyodrębnić zawarte dane? uncompressZostała usunięta z CRAN pakiet - jest to możliwe w bazowej R (a jeśli tak, to jest ograniczony do systemów * nixowych?)? W razie potrzeby chętnie opublikuję jako nowe pytanie.
jbaums
3
Widzisz help(gzfile)- myślałem, że protokół gzip może teraz zdekompresować (stare) pliki .z teraz, gdy patent już dawno wygasł. Może nie. Kto w ogóle używa .z? Wezwano lata 80-te, chcą cofnąć kompresję ;-)
Dirk Eddelbuettel
Dzięki - nie mogę zmusić go do pracy, więc może mimo wszystko nie jest obsługiwany. Australijskie Biuro Meteorologii udostępnia niestety część swoich danych jako .z!
jbaums
FYI To nie działa z readRDS()(przynajmniej dla mnie). Z tego, co wiem, plik musi znajdować się w pliku, z którym można czytać read.table().
jessi
1
będziesz także chciał zamknąć połączenie. R może mieć otwartych tylko 125 na raz. Coś jak con <- unz (temp, "a1.dat"); data <- read.table (con); close (con);
pdb
28

Tak dla porządku, spróbowałem przetłumaczyć odpowiedź Dirka na kod :-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
źródło
5
Nie używaj scan(); możesz użyć read.table()et al bezpośrednio na połączeniu. Zobacz moją zredagowaną odpowiedź
Dirk Eddelbuettel
17

Użyłem „downloadera” pakietu CRAN, który można znaleźć pod adresem http://cran.r-project.org/web/packages/downloader/index.html . Dużo łatwiej.

download(url, dest="dataset.zip", mode="wb") 
unzip ("dataset.zip", exdir = "./")
unixcreeper
źródło
2
Właśnie użycie narzędzi :: rozpakować bez potrzeby pakietu downlaoder dla mnie
mtelesha
od 2019 - musiałem powiedzieć exdir = '.'
userJT
9

Na Maca (i zakładam, że Linux) ...

Jeśli archiwum zip zawiera pojedynczy plik, możesz użyć polecenia bash funzipw połączeniu z freadz data.tablepakietu:

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

W przypadkach, gdy archiwum zawiera wiele plików, możesz tarzamiast tego wyodrębnić określony plik na standardowe wyjście:

dt <- fread("curl http://www.newcl.org/data/zipfiles/a1.zip | tar -xf- --to-stdout *a1.dat")
dnlbrky
źródło
kiedy próbuję twojego rozwiązania dla wielu plików, File is empty:
pojawia
9

Oto przykład, który działa dla plików, których nie można wczytać za pomocą read.tablefunkcji. Ten przykład odczytuje plik .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
źródło
5

Aby to zrobić za pomocą data.table, stwierdziłem, że działa to. Niestety link już nie działa, więc użyłem linku do innego zestawu danych.

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)

Wiem, że jest to możliwe w jednej linii, ponieważ możesz przekazać skrypty bash do fread, ale nie jestem pewien, jak pobrać plik .zip, wyodrębnić i przekazać z niego pojedynczy plik fread.

Mallick Hossain
źródło
4

Wypróbuj ten kod. Mi to pasuje:

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

Przykład:

unzip(zipfile="./data/Data.zip",exdir="./data")
Marcelo Tibau
źródło
0

Okazało się, że działa dla mnie następujące. Te kroki pochodzą z filmu BTD na YouTube, Zarządzanie plikami Zipfile w R :

zip.url <- "url_address.zip"

dir <- getwd()

zip.file <- "file_name.zip"

zip.combine <- as.character(paste(dir, zip.file, sep = "/"))

download.file(zip.url, destfile = zip.combine)

unzip(zip.file)
Gian Zlupko
źródło