download.file() загрузить поврежденный xls

Я пытаюсь создать пакет для загрузки, импорта и очистки данных с веб-страницы Центрального банка Доминиканской Республики. Я выполнил все кодирование в Rstudio.cloud, и все работает отлично, но когда я пробую функции на своем локальном компьютере, они не работают.

Немного покопавшись в каждой функции, я понял, что проблема была в загруженном файле, он поврежден.

Я включаю первые шаги функции только для того, чтобы проиллюстрировать мою проблему.

URL-адрес файла

# Packages
library(readxl)

# file url. 
url <- paste0("https://cdn.bancentral.gov.do/documents/",
              "estadisticas/precios/documents/",
              "ipc_base_2010.xls?v=1570116997757")

# termporary path
file_path <- tempfile(pattern = "", fileext = ".xls")

# downloading 
download.file(url, file_path, quiet = TRUE)

# reading the file
ipc_general <- readxl::read_excel(
            file_path,
            sheet = 1,
            col_names = FALSE,
            skip = 7
        )

Error: 
  filepath: C:\Users\Johan Rosa\AppData\Local\Temp\RtmpQ1rOT3\2a74778a1a64.xls
  libxls error: Unable to open file

Я использую временные файлы, но это не проблема, вы можете попробовать загрузить файл в свой рабочий каталог, и проблема не исчезнет.

Я хочу знать:

  1. Почему этот код работает в rstudio.clowd, а не локально?
  2. Что я могу сделать, чтобы выполнить работу? (альтернативный подход, пакеты, функции)

Кстати, я использую Windows 10

Изменить

Отвечать:

1- Rstudio.cloud работает на Linux, но для Windows мне нужно внести некоторые коррективы в команду download.file().

2- download.file(url, file_path, quiet = TRUE, mode = "wb")

Это то, что я искал.

Теперь у меня другая проблема. Я должен придумать способ определить, работает ли функция в Linux или Windows, чтобы соответствующим образом установить этот аргумент.

Я могу написать новую функцию загрузки файла, используя if else вызовы результата .Platform$OS.type.

Или я могу установить mode = "wb" для всех вызовов download.file()?

У вас есть какие-нибудь рекомендации?


person Johan Rosa    schedule 11.04.2020    source источник
comment
Это просто вопрос изменения имени файла с течением времени?   -  person markhogue    schedule 11.04.2020
comment
имя файла не меняется со временем, этот URL-адрес исправлен для этого файла.   -  person Johan Rosa    schedule 11.04.2020


Ответы (1)


Из документации download.file()

Выбор двоичной передачи (режим = «wb» или «ab») важен в Windows, поскольку, в отличие от Unix-подобных, он различает текстовые и двоичные файлы, а для передачи текста заменяет окончания строк \n на \r\n (иначе CRLF).

Код, написанный для загрузки двоичных файлов, должен использовать режим = «wb» (или «ab»), но проблемы, связанные с передачей текста, будут видны только в Windows.

Из источника download.file

head(print(download.file),12)
1  function (url, destfile, method, quiet = FALSE, mode = "w", cacheOK = TRUE,    
2      extra = getOption("download.file.extra"), headers = NULL,                  
3      ...)                                                                       
4  {                                                                              
5      destfile                                                                   
6      method <- if (missing(method))                                             
7          getOption("download.file.method", default = "auto")                    
8      else match.arg(method, c("auto", "internal", "wininet", "libcurl",         
9          "wget", "curl", "lynx"))                                               
10     if (missing(mode) && length(grep("\\\\.(gz|bz2|xz|tgz|zip|rd[as]|RData)$", 
11         URLdecode(url))))                                                      
12         mode <- "wb" 

Итак, глядя на источник, если вы не установили режим, функция автоматически использует «w», за исключением того, что URL-адрес содержит gz, bz2, xz и т. д. (поэтому вы получаете первую ошибку).

По моему скромному мнению, я думаю, что в Unix-подобных (например, Linux) «w» и «wb» одинаковы, потому что они не различают текстовые и двоичные файлы, но Windows делает.

Таким образом, вы можете установить mode="wd" для всех вызовов download.file (если это не передача текста в Windows), это не повлияет на функцию в Linux.

person captcoma    schedule 11.04.2020