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?


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

5
Nie używaj scan(); możesz użyć read.table()et al bezpośrednio na połączeniu. Zobacz moją zredagowaną odpowiedź
Dirk Eddelbuettel


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

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

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.


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

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)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.