Почему R говорит, что нет петли для перерыва / следующего, переходя на верхний уровень - PullRequest
7 голосов
/ 12 августа 2011

Почему R выбрасывает ошибку «Ошибка в значении [3L]: нет цикла для перерыва / следующего перехода на верхний уровень» вместо перехода к следующей итерации цикла?Я нахожусь на R версии 2.13.1 (2011-07-08)

for (i in seq(10)) { 
   tryCatch(stop(), finally=print('whoops'), error=function(e) next) 
}

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

for (i in c(1,2,Inf)) { 
   fname = paste(sep='', 'f', i, '.png')
   png(fname, width=1024, height=768) 
   rs <- tryCatch(plot(i), error=function(e) NULL)
   if (is.null(rs)){
    print("I'll create a different picture because of the error.")
   }
   else{
    print(paste('image', fname, 'created'))
    dev.off()
    next
   } 
}

Ответы [ 3 ]

9 голосов
/ 28 августа 2011

Может быть, вы могли бы попробовать:

for (i in seq(10)) { 
   flag <- TRUE
   tryCatch(stop(), finally=print('whoops'), error=function(e) flag<<-FALSE)
   if (!flag) next
}
4 голосов
/ 12 августа 2011

К сожалению, как только вы попадете внутрь своей функции error, вы больше не будете в цикле.Есть способ, которым вы могли бы взломать это:

for (i in seq(10)) { 
   delayedAssign("do.next", {next})
   tryCatch(stop(), finally=print('whoops'),
        error=function(e) force(do.next))
}

Хотя это ... хорошо, хакер.Возможно, есть менее хакерский способ, но я не вижу его сразу.

(Это работает, потому что delayedAssign происходит каждый цикл, сводя на нет усилия force)

РЕДАКТИРОВАТЬ

Или вы можете использовать продолжения:

for (i in seq(10)) { 
   callCC(function(do.next) {
       tryCatch(stop(), finally=print('whoops'),
           error=function(e)    do.next(NULL))
       # Rest of loop goes here
       print("Rest of loop")
   })
}

РЕДАКТИРОВАТЬ

Как отмечает Джорис, вам, вероятно, не следует использовать ни один из них, потому что они сбивают с толкучитать.Но если вы действительно хотите вызвать next в цикле, вот как:).

2 голосов
/ 12 августа 2011

Не имеет ли больше смысла ставить next вне tryCatch на основе проверки if? Примерно так:

for (i in c(1,2,Inf)) { 
   rs <- tryCatch(seq(i), finally=print('whoops'), error=function(e) NULL)
   if (is.null(rs)){
    print("I found an error!")
   }
   else{
    next
   } 
}

хотя я не уверен, что это то, что вы хотите, так как мне немного непонятно, что вы пытаетесь сделать.

EDIT

Исходя из пересмотров ФП, эта формулировка работает для меня:

plotFn <- function(fname,i){
    png(fname, width=400, height=200)
    plot(i)
    dev.off()
}


for (i in c(1,Inf,3)) { 
   fname = paste('f', i, '.png',sep="")
   rs <- tryCatch(plotFn(fname,i), error=function(e){dev.off(); return(NULL)})
   if (is.null(rs)){
    print("I'll create a different picture because of the error.")
   }
   else{
    print(paste('image', fname, 'created'))
    next
   } 
}

Я уверен, что в случае ошибки не нужно было вызывать dev.off() в случае ошибки. Мне нужно было бы покопаться немного глубже, чтобы понять, почему именно разделение png и plot вызывает проблемы. Но я думаю, что, возможно, в любом случае лучше сохранить последовательность png(); plot(); dev.off() самодостаточной. Также обратите внимание, что я вставил dev.off() в функцию ошибки.

Я не проверял, что произойдет, если plotFn выдаст ошибку на png(), никогда не создаст устройство, а затем достигнет функции ошибки и вызовет dev.off(). Поведение может зависеть от того, что еще у вас происходит в вашей R-сессии.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...