Использование R для загрузки сжатого файла данных, извлечения и импорта данных

@EZGraphs в Твиттере пишет: "Многие онлайновые csvs заархивированы. Есть ли способ загрузить, распаковать архив и загрузить данные в data.frame, используя R? #Rstats"

Я также пытался сделать это сегодня, но в итоге просто скачал zip-файл вручную.

Я попробовал что-то вроде:

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

но я чувствую, как будто я далеко Какие-нибудь мысли?

10 ответов

Решение

Zip-архивы на самом деле являются "файловой системой" с метаданными контента и т. Д. help(unzip) для деталей. Таким образом, чтобы сделать то, что вы набросали выше, вам нужно

  1. Создать темп. имя файла (например, tempfile())
  2. использование download.file() чтобы получить файл в темп. файл
  3. использование unz() извлечь целевой файл из темп. файл
  4. Удалить временный файл через unlink()

который в коде (спасибо за базовый пример, но это проще) выглядит

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

Сжатый (.z) или сжатый (.gz) или bzip2ed (.bz2) файлы - это просто файлы и те, которые вы можете прочитать непосредственно из соединения. Так что попросите провайдера данных использовать это вместо этого:)

Просто для записи, я попытался перевести ответ Дирка в код:-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)

Я использовал пакет загрузчика CRAN, который можно найти по адресу http://cran.r-project.org/web/packages/downloader/index.html. Намного легче.

download(url, dest="dataset.zip", mode="wb") 
unzip ("dataset.zip", exdir = "./")

Для Mac (и я предполагаю, Linux)...

Если zip-архив содержит один файл, вы можете использовать команду bash funzip, В связке с fread от data.table пакет:

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

В случаях, когда архив содержит несколько файлов, вы можете использовать tar вместо этого, чтобы извлечь конкретный файл в стандартный вывод:

dt <- fread("curl http://www.newcl.org/data/zipfiles/a1.zip | tar -xf- --to-stdout *a1.dat")

Вот пример, который работает для файлов, которые не могут быть прочитаны с read.table функция. Этот пример читает файл.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))

С использованиемlibrary(archive)также можно прочитать определенный CSV-файл в архиве, не распаковывая его предварительно;read_csv(archive_read("http://www.newcl.org/data/zipfiles/a1.zip", file = 1), col_types = cols())который я считаю более удобным и быстрее.

Он также поддерживает все основные форматы архивов и немного быстрее, чем базовый R untar или unz — он поддерживает файлы tar, ZIP, 7-zip, RAR, CAB, gzip, bzip2, Compress, lzma, xz и uuencoded.

Чтобы разархивировать все, что можно использоватьarchive_extract("http://www.newcl.org/data/zipfiles/a1.zip", dir=XXX)

Это работает на всех платформах, и, учитывая превосходную производительность, для меня это был бы предпочтительный вариант.

Для этого с помощью data.table я обнаружил, что работает следующее. К сожалению, ссылка больше не работает, поэтому я использовал ссылку для другого набора данных.

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)

Я знаю, что это возможно в одной строке, так как вы можете передать bash-скрипты fread, но я не уверен, как загрузить файл.zip, извлечь и передать из него один файл fread,

Попробуйте этот код. Меня устраивает:

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

Пример:

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

rio()был бы очень подходящим для этого - он использует расширение имени файла, чтобы определить, что это за файл, поэтому он будет работать с большим разнообразием типов файлов. Я также использовал unzip() чтобы перечислить имена файлов в zip-файле, поэтому нет необходимости указывать имена файлов вручную.

      library(rio)

# create a temporary directory
td <- tempdir()

# create a temporary file
tf <- tempfile(tmpdir=td, fileext=".zip")

# download file from internet into temporary location
download.file("http://download.companieshouse.gov.uk/BasicCompanyData-part1.zip", tf)

# list zip archive
file_names <- unzip(tf, list=TRUE)

# extract files from zip file
unzip(tf, exdir=td, overwrite=TRUE)

# use when zip file has only one file
data <- import(file.path(td, file_names$Name[1]))

# use when zip file has multiple files
data_multiple <- lapply(file_names$Name, function(x) import(file.path(td, x)))

# delete the files and directories
unlink(td)

Я обнаружил, что у меня сработало следующее. Эти шаги взяты из видео BTD на YouTube, Управление Zip-файлами в 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)
Другие вопросы по тегам