R l oop выполняет всего 3 итерации из 2504 - PullRequest
1 голос
/ 23 апреля 2020

Я написал функцию для загрузки нескольких файлов из базы данных NOAA. Во-первых, у меня есть sites, который представляет собой список идентификаторов сайтов, которые я хочу загрузить с сайта. Это выглядит так:

 > head(sites)
   [[1]]
   [1] "9212"

   [[2]]
   [1] "10158"

   [[3]]
   [1] "11098"

> length(sites)
   [1] 2504

Моя функция показана ниже.

tested<-lapply(seq_along(sites), function(x) {
   no<-sites[[x]]
   data=GET(paste0('https://www.ncdc.noaa.gov/paleo-search/data/search.json?xmlId=', no))
   v<-content(data)   
   check=GET(v$statusUrl)
   j<-content(check)
   URL<-j$archive
   download.file(URL, destfile=paste0('./tree_ring/', no, '.zip'))
 }) 

Странная проблема заключается в том, что он работает для первых трех сайтов (загружается правильно), но затем останавливается после трех сайтов и выдает следующую ошибку:

Error in charToRaw(URL) : argument must be a character vector of length 1 

I Попытался вручную загрузить 4-й и 5-й сайт (используя тот же код, что и выше, но не в функции), и он работает нормально. Что может происходить здесь?

РЕДАКТИРОВАТЬ 1: Отображение дополнительных идентификаторов сайта в соответствии с запросом

> dput(sites[1:6])
list("9212", "10158", "11098", "15757", "15777", "15781")

1 Ответ

2 голосов
/ 23 апреля 2020

Я преобразовал ваш код в for l oop, чтобы я мог видеть самые последние значения всех ваших переменных при сбое.

Сбои не всегда согласованы на 4-м сайте. Запуск вашего кода несколько раз, иногда он дает сбой на 2, 3 или 4. Когда он терпит неудачу, если я смотрю на j, я вижу это:

$message
[1] "finalizing archive"

$status
[1] "working"
$message
[1] "finalizing archive"

$status
[1] "working"

Если я перезапущу check=GET(v$statusUrl); j<-content(check) несколько секунд спустя, затем я вижу

$archive
[1] "https://www.ncdc.noaa.gov/web-content/paleo/bundle/1986420067_2020-04-23.zip"

$status
[1] "complete"

Итак, я думаю, что серверу требуется немного времени, чтобы подготовить файл для загрузки, и иногда R запрашивает файл, прежде чем он будет готов, что вызывает ошибку. Простое исправление может выглядеть следующим образом:

check_status <- function(v) {
  check <- GET(v$statusUrl)
  content(check)
}

for(x in seq_along(sites)) {
   no<-sites[[x]]
   data=GET(paste0('https://www.ncdc.noaa.gov/paleo-search/data/search.json?xmlId=', no))
   v<-content(data)
   try_counter <- 0
   j <- check_status(v)
   while(j$status != "complete" & try_counter < 100) {
     Sys.sleep(0.1)
     j <- check_status(v)
   }
   URL<-j$archive
   download.file(URL, destfile=paste0(no, '.zip'))
}

Если статус не готов, эта версия будет ждать 0,1 секунды, прежде чем проверять снова, до 10 секунд.

...