Использование 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)
для деталей. Таким образом, чтобы сделать то, что вы набросали выше, вам нужно
- Создать темп. имя файла (например,
tempfile()
) - использование
download.file()
чтобы получить файл в темп. файл - использование
unz()
извлечь целевой файл из темп. файл - Удалить временный файл через
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)