R: показывать сообщения об ошибках и предупреждения в foreach %dopar%

Я новичок в использовании foreach() %dopar% для распараллеливания, и у меня есть некоторые проблемы с обработкой ошибок или предупреждений.

  1. когда я использую try() с моим настроенным сообщением об ошибке в foreach() %dopar%, "собственное" сообщение об ошибке не отображается:

    test <- function(x) {
      if (x==2) "a"/2
    }
    
    foreach(i=1:3) %dopar% {
      tryout <- try(test(i))
      if (class(tryout)=="try-error") print("Error!")
    }
    

    В этом случае «собственное» сообщение об ошибке: Error in "a"/2 : non-numeric argument to binary operator не отображается, и будет напечатано только Error! из отлова ошибок try(). Однако оба сообщения об ошибках будут напечатаны, если не использовать foreach() %dopar%. Итак, как сделать так, чтобы отображались оба сообщения об ошибках?

  2. В приведенном выше случае, когда есть предупреждения, независимо от того, являются ли они дополнительными к ошибкам или нет, предупреждающие сообщения не печатаются, например, с тем же блоком foreach(), что и выше, и test() ниже:

    test <- function(x) {
      if (x==2) warning("Warning!")
    }
    

    Итак, как показать предупреждения?

p.s. Я обнаружил, что если я просто использую try(test(i)) внутри %dopar%, то будут напечатаны «собственные» сообщения об ошибках и предупреждения, но я хочу включить свое собственное сообщение об ошибке в реальных ситуациях. Я также пытался использовать tryCatch() вместо try(), но это не решило проблему.

Спасибо!


person Kenneth Cheng    schedule 01.09.2016    source источник
comment
Возможно, вам придется сообщить параллельному серверу, что вы хотите получить результат (например, аргумент outfile="" из makeCluster, если вы используете doSNOW). Существует связанный вопрос с более подробной информацией.   -  person Tomas Kalibera    schedule 01.09.2016
comment
Спасибо за указание на ценное направление для решения проблемы. Я пока не использую doSNOW, но я изучаю это...   -  person Kenneth Cheng    schedule 02.09.2016


Ответы (1)


Я думаю, что проблема связана с вашей обработкой ошибок и небольшим непониманием dopar. Во-первых, подумайте о dopar больше как о функции. По умолчанию он должен возвращать объект обратно пользователю в виде списка (он собирает все выходные данные каждого рабочего процесса, а функция foreach собирает их и возвращает для использования, см. «output_list» ниже).

Вы также можете установить .errorhandling = 'pass', он вернет ошибку обратно в выходной объект (обратите внимание, что, вероятно, работает, только если .combine = 'list'). Вот как работает .errorhandling:

.errorhandling указывает, как следует обрабатывать ошибку оценки задачи. Если значение равно «стоп», то выполнение будет остановлено с помощью функции остановки в случае возникновения ошибки. Если указано значение «удалить», результат этой задачи не будет возвращен или передан функции .combine. Если это «пройдено», то объект ошибки, сгенерированный оценкой задачи, будет включен в остальные результаты. Предполагается, что функция объединения (если она указана) сможет работать с объектом ошибки. Значение по умолчанию — «стоп».

Вот пример того, как настроить tryCatch внутри foreach. Обратите внимание, что ошибки теперь сохраняются в output_list.

output_list = foreach(i=1:3, .errorhandling='pass') %dopar% {
result <- tryCatch({
    object_that_doesnt_exist[i]}, 
     warning = function(war) {
         return('a warning')}, 
     error = function(err) {
         return('an error')}, 
     finally = {
         return('other things')
     }) # END tryCatch

  return(result)  # return your result to outputlist
}

output_list
person mmann1123    schedule 12.04.2017